私のIDENTITY
オーバーフローチェックスクリプト を更新して、 DECIMAL
とNUMERIC
IDENTITY
列 を考慮しています。
チェックの一部として、すべてのIDENTITY
列のデータ型の範囲のサイズを計算します。これを使用して、その範囲の何パーセントが使い果たされているかを計算します。 DECIMAL
およびNUMERIC
の場合、その範囲のサイズは_2 * 10^p - 2
_ です。ここで、p
は精度です。
DECIMAL
列とNUMERIC
IDENTITY
列を含む一連のテストテーブルを作成し、次のようにそれらの範囲を計算しようとしました。
_SELECT POWER(10.0, precision)
FROM sys.columns
WHERE
is_identity = 1
AND type_is_decimal_or_numeric
;
_
これにより、次のエラーがスローされました。
_Msg 8115, Level 16, State 6, Line 1
Arithmetic overflow error converting float to data type numeric.
_
タイプDECIMAL(38, 0)
のIDENTITY
列(つまり、最大精度)に絞り込んだので、その値に対して直接POWER()
計算を試みました。
次のすべてのクエリ
_SELECT POWER(10.0, 38.0);
SELECT CONVERT(FLOAT, (POWER(10.0, 38.0)));
SELECT CAST(POWER(10.0, 38.0) AS FLOAT);
_
また、同じエラーが発生しました。
POWER()
の出力をFLOAT
タイプのNUMERIC
に変換しようとする理由(特に FLOAT
がより高い優先順位 )?p = 38
_を含む)のDECIMAL
またはNUMERIC
列の範囲を動的に計算するにはどうすればよいですか?構文
POWER ( float_expression , y )
議論
float_expression
式 タイプfloatであるか、暗黙的にfloatに変換できるタイプです。y
は、float_expressionを累乗する力です。 yは、ビットデータ型を除いて、正確な数値または近似数値データ型のカテゴリの式にすることができます。戻り型
float_expressionで送信されたものと同じ型を返します。たとえば、decimal(2,0)がfloat_expressionとして送信された場合、返される結果はdecimal(2,0)です。
最初の入力は、必要に応じて暗黙的にfloat
にキャストされます。
内部計算は、標準Cランタイムライブラリ(CRT)関数float
によるpow
演算を使用して実行されます。
次に、float
からのpow
出力は、左側のオペランドのタイプにキャストバックされます(リテラル値10.0を使用すると、numeric(3,1)
と暗黙的に示されます)。
明示的にfloat
を使用すると、あなたの場合はうまくいきます:
SELECT POWER(1e1, 38);
SELECT POWER(CAST(10 as float), 38.0);
10の正確な結果38 SQL Serverに保存できないdecimal/numeric
これは、39桁の精度が必要になるためです(1の後にゼロが38個続く)。最大精度は38です。