Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Microsoft SQL Server |
![]() ![]() |
кучка
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] Ответить | Цитировать Сообщить модератору |
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] Ответить | Цитировать Сообщить модератору |
кучка
Guest |
спасибо, как оставить нужное число знаков после запятой -- оно понятно. и как костыль к ROUND прикрутить -- тоже ок. но почему просто ROUND не канает? |
26 окт 12, 18:06 [13382003] Ответить | Цитировать Сообщить модератору |
Crimean Member Откуда: Сообщений: 13148 |
неубедительно, поскольку:
читаем описание функции ROUND в BOL, секцию "Return Types" подсказка - в процессе расчетов сервер имеет право оперировать теми типами данных, которые сочтет нужным и только после - приводить к типу данных результата. соответственно, ROUND вовсе не обязательно получит на вход тип данных результата ну и вернет нечто соответствующее а начальству могли бы подсказать констрейнт повесить на поля с money ( field = round( field, 2 )) и все, никакого редизайна кода и перепроверок работы всей математики |
||||
26 окт 12, 18:19 [13382063] Ответить | Цитировать Сообщить модератору |
iap Member Откуда: Москва Сообщений: 47045 |
На всякий случай: MONEY эквивалентно DEC(19,4) |
26 окт 12, 19:16 [13382237] Ответить | Цитировать Сообщить модератору |
кучка
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] Ответить | Цитировать Сообщить модератору |
кучка
Guest |
ну все, нашлась статья в БОЛ-е, теперь сходится. 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] Ответить | Цитировать Сообщить модератору |
Crimean Member Откуда: Сообщений: 13148 |
регионалки лук. там - "децимал поинт" для денег и цифр - это не одно и то же |
||
27 окт 12, 01:15 [13383802] Ответить | Цитировать Сообщить модератору |
Все форумы / Microsoft SQL Server | ![]() |