Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 кучка вопросов про decimal(20,2) и money  [new]
кучка
Guest
имелась таблица с деньгами, никаких проблем, тип столбцов был money
сегодня вдруг начальство сказало, нам не нра, т.к. не надо нам 4 знака после запятой.
т.е. им вообще никогда не надо больше двух знаков.
взяли и переделали таблицу, все мои заменили на money(20,2).
у меня было написано несколько процедур, где участвовал money,
на выходе были отличные суммы с двумя знаками после запятой.
теперь все выводится с офигительными знаками, к-ые все равно никому не нужны,
причем ROUND их тоже не берет.

вопросов несколько.
1. что при делении как-то хитро пересчитываетя точность результата, помню, но не могу найти в БОЛ.
ткните плиз, кто помнит, где это там.
я кодом могу показать, что точность поменялась, но надо бы БОЛ-ом кинуть в начальство.

2. почему при выводе результата в в первом результате разделитель точка,
во втором запятая?

3. почему Round(*, 2) не оставляет 2 знака?

declare @t table(num decimal(20,2))
insert @t values (4971.25)

select num, num / 1000000 as divd, 
       SQL_VARIANT_PROPERTY(num / 1000000, 'BaseType') as type_,
       SQL_VARIANT_PROPERTY(num / 1000000, 'Precision') as prec,
       SQL_VARIANT_PROPERTY(num / 1000000, 'Scale') as scale_,
       ROUND(num / 1000000, 2) as rnd
from @t

declare @t1 table(num money)
insert @t1 values (4971.25)

select num, num / 1000000 as divd, 
       SQL_VARIANT_PROPERTY(num / 1000000, 'BaseType') as type_,
       SQL_VARIANT_PROPERTY(num / 1000000, 'Precision') as prec,
       SQL_VARIANT_PROPERTY(num / 1000000, 'Scale') as scale_,
       ROUND(num / 1000000, 2) as rnd       
from @t1
26 окт 12, 17:49    [13381939]     Ответить | Цитировать Сообщить модератору
 Re: кучка вопросов про decimal(20,2) и money  [new]
user89
Member

Откуда:
Сообщений: 2083
кучка,

Для округления лучше использовать cast(value as decimal(точность))

select num, num / 1000000 as divd, 
       SQL_VARIANT_PROPERTY(num / 1000000, 'BaseType') as type_,
       SQL_VARIANT_PROPERTY(num / 1000000, 'Precision') as prec,
       SQL_VARIANT_PROPERTY(num / 1000000, 'Scale') as scale_,
       ROUND(num / 1000000, 2) as rnd,
       cast(num / 1000000 as decimal(20,2)) as rnd2
from @t
26 окт 12, 18:02    [13381984]     Ответить | Цитировать Сообщить модератору
 Re: кучка вопросов про decimal(20,2) и money  [new]
кучка
Guest
спасибо, как оставить нужное число знаков после запятой -- оно понятно.
и как костыль к ROUND прикрутить -- тоже ок.
но почему просто ROUND не канает?
26 окт 12, 18:06    [13382003]     Ответить | Цитировать Сообщить модератору
 Re: кучка вопросов про decimal(20,2) и money  [new]
Crimean
Member

Откуда:
Сообщений: 13148
кучка
оно понятно


неубедительно, поскольку:

кучка
но почему


читаем описание функции ROUND в BOL, секцию "Return Types"
подсказка - в процессе расчетов сервер имеет право оперировать теми типами данных, которые сочтет нужным и только после - приводить к типу данных результата. соответственно, ROUND вовсе не обязательно получит на вход тип данных результата ну и вернет нечто соответствующее

а начальству могли бы подсказать констрейнт повесить на поля с money ( field = round( field, 2 )) и все, никакого редизайна кода и перепроверок работы всей математики
26 окт 12, 18:19    [13382063]     Ответить | Цитировать Сообщить модератору
 Re: кучка вопросов про decimal(20,2) и money  [new]
iap
Member

Откуда: Москва
Сообщений: 47045
На всякий случай: MONEY эквивалентно DEC(19,4)
26 окт 12, 19:16    [13382237]     Ответить | Цитировать Сообщить модератору
 Re: кучка вопросов про decimal(20,2) и money  [new]
кучка
Guest
iap, а почему же тогда вот такое не дает одинаковые результаты?

declare @t table(num decimal(19,4))
insert @t values (4971.25)

select num, num / 1000000 as divd, 
       SQL_VARIANT_PROPERTY(num / 1000000, 'BaseType') as type_,
       SQL_VARIANT_PROPERTY(num / 1000000, 'Precision') as prec,
       SQL_VARIANT_PROPERTY(num / 1000000, 'Scale') as scale_,
       ROUND(num / 1000000, 2) as rnd
from @t

declare @t1 table(num money)
insert @t1 values (4971.25)

select num, num / 1000000 as divd, 
       SQL_VARIANT_PROPERTY(num / 1000000, 'BaseType') as type_,
       SQL_VARIANT_PROPERTY(num / 1000000, 'Precision') as prec,
       SQL_VARIANT_PROPERTY(num / 1000000, 'Scale') as scale_,
       ROUND(num / 1000000, 2) as rnd       
from @t1


num	divd	type_	prec	scale_	rnd
4971.2500	0.004971250000	decimal	27	12	0.000000000000

num	divd	type_	prec	scale_	rnd
4971,25	0,0049	money	19	4	0,00
27 окт 12, 00:08    [13383500]     Ответить | Цитировать Сообщить модератору
 Re: кучка вопросов про decimal(20,2) и money  [new]
кучка
Guest
iap
На всякий случай: MONEY эквивалентно DEC(19,4)


ну все, нашлась статья в БОЛ-е, теперь сходится.
money не эквивалентно decimal(19,4).
money имеет те же scale/precision, но попадает в группу типов с fixed scale/precision.
а decimal как раз в ту группу не попадает, ибо ...besides decimal...

The precision and scale of the numeric data types besides decimal are fixed. If an arithmetic operator has two expressions of the same type, the result has the same data type with the precision and scale defined for that type. If an operator has two expressions with different numeric data types, the rules of data type precedence define the data type of the result. The result has the precision and scale defined for its data type.

спасибо Crimean за подсказку.
1000000 он счел за int.
т.е. в случае money / int остаемся в группе с fixed scale/precision и тип результата money.
а в случае decimal(19,4) / int scale/precision как раз пересчитывается по жуткой формуле:
precision = p1 - s1 + s2 + max(6, s1 + p2 + 1)
scale = max(6, s1 + p2 + 1)

люди!!! но почему в одном случае студия дает разделитель в виде запятой, а в другом случае точку???
27 окт 12, 00:53    [13383706]     Ответить | Цитировать Сообщить модератору
 Re: кучка вопросов про decimal(20,2) и money  [new]
Crimean
Member

Откуда:
Сообщений: 13148
кучка
люди!!! но почему в одном случае студия дает разделитель в виде запятой, а в другом случае точку???


регионалки лук. там - "децимал поинт" для денег и цифр - это не одно и то же
27 окт 12, 01:15    [13383802]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить