Как с помощью TSQL преобразовать высокоточное значение в числовое?

У меня довольно распространенная проблема, но мое обычное решение не работает. У меня есть очень точное значение, хранящееся как символ в промежуточной таблице. Когда я нажимаю его на конечный пункт назначения, столбец с числовым типом данных (38,38), он терпит неудачу. Я думал, что это из-за отрицательного знака, но когда я избавился от него, у меня все еще есть проблема. У меня исчерпан числовой столбец, но я все еще получаю следующую ошибку: Ошибка арифметического переполнения при преобразовании nvarchar в числовой тип данных.

Обычно я просто конвертирую в float, но это не работает. Кроме того, я хочу сохранить точность значения, и float, похоже, уберет это.

Что мне здесь не хватает?

DECLARE @Value NVARCHAR(255) = '-1.000000000000000'
SELECT CAST(@Value AS numeric(38,38))

DECLARE @Value NVARCHAR(255) = '-1.000000000000000'
SELECT CAST(CAST(@Value AS FLOAT) AS numeric(38,38))

ПОЯСНЕНИЕ: числовые (38,38) являются абсурдными параметрами и использовались только для тестирования и в качестве примера для этого вопроса. В исходном столбце было задано значение numeric(16,15), которое работало более чем в 99% случаев с набором данных из миллионов записей и поэтому не помечалось как проблема.


person Bob Wakefield    schedule 05.02.2018    source источник
comment
Проблема заключается в том, что вы не можете иметь точность/шкалу 38, 38 с числом ›= 1 или ‹= -1 (поскольку вы указали точность 38 после запятой).   -  person ZLK    schedule 06.02.2018
comment
Вы читали документацию о том, что означает numeric(38, 38)??? Это означает, что всего 38 цифр, 38 цифр после запятой. Как вы ожидаете, что это сработает?   -  person Eric    schedule 06.02.2018
comment
как сказал ZLK, вы забываете определение. Просто чтобы полностью объяснить это --- с (38,38) вы можете иметь .00000000000000000000000000000000000000001 ... вы не можете иметь 1.0000000000000000000000000000000000000000 == (38,37)   -  person Mike M    schedule 06.02.2018
comment
Да, я читал документацию, но, вероятно, это тот случай, когда я не понимаю, что читаю. decimal[ (p[ ,s] )] где s ограничено значениями от 0 до p. Как это звучит, вы говорите, что хоть -1. 15 нулей - это значение, -1. 38 нулей - это то, что на самом деле сохраняется. В моей проблеме есть и другая сложность, но теперь я вижу основную проблему.   -  person Bob Wakefield    schedule 06.02.2018
comment
@BobWakefield Точность — это общее количество цифр, включая левое и правое десятичное число. Масштаб - это то, насколько далеко сместить десятичную дробь от конца. Другими словами, что-то вроде (10,2) означает всего 10 цифр, 2 из которых находятся справа от десятичной дроби. Это оставляет максимум 8 слева.   -  person Pittsburgh DBA    schedule 06.02.2018
comment
@BobWakefield Для еще большего удовольствия подождите, пока вы не используете простые операторы или агрегаты. документы. microsoft.com/en-us/sql/t-sql/типы данных/   -  person Pittsburgh DBA    schedule 06.02.2018


Ответы (1)


numeric(38,38) — числовое значение из 38 цифр, 38 из которых после запятой. Из-за этого любое число больше 1 или меньше -1 (имеет 1 или более цифр слева от десятичной дроби) будет переполнено. Вам необходимо учитывать максимальное количество цифр, которые могут встречаться как слева, так и справа от десятичной дроби.

1.00001 будет числом (6,5) с 6 цифрами, 5 из которых находятся справа от десятичной дроби, а 1 слева.

10.00001 будет числом (7,5) с 7 цифрами, 5 из которых справа от десятичной дроби, 2 из которых слева.

person Andrew O'Brien    schedule 05.02.2018
comment
Да 38,38 было многовато. Это произошло в конце часов, когда я пытался понять, почему эти значения не подходят. В какой-то момент у меня были более разумные настройки. НАСТОЯЩАЯ ошибка здесь заключалась в непонимании того, что если тип данных был числовым (6,5), то 5 не было предложением. Вроде 5 не максимальное значение. Если приходит число 1,1, оно фактически будет храниться как 1,10000. - person Bob Wakefield; 06.02.2018