マーティンの答えにさらに干渉する代わりに、POWER()ここでの私の発見の残りを追加します。
ニッカーズを保持します。
前文
最初に、MSDNのドキュメントPOWER() Aを展示します。
構文
POWER ( float_expression , y )
引数
float_expression
float型の式、または暗黙的にfloat型に変換できる型の式です。
戻り型
と同じfloat_expression。
POWER()戻り値の型である最後の行を読んでから結論を出すことができますがFLOAT、もう一度読んでください。float_expression「フロート型または暗黙的にフロートに変換できる型」です。そのため、その名前にfloat_expressionもかかわらず、実際にはa FLOAT、a DECIMAL、またはanになりINTます。の出力はの出力とPOWER()同じであるためfloat_expression、それもこれらのタイプの1つである可能性があります。
したがって、入力に依存する戻り値の型を持つスカラー関数があります。それは可能性が?
観察
POWER()入力に応じて出力を異なるデータ型にキャストするテストを示すテストBを紹介します。
SELECT
POWER(10, 3) AS int
, POWER(1000000000000, 3) AS numeric0 -- one trillion
, POWER(10.0, 3) AS numeric1
, POWER(10.12305, 3) AS numeric5
, POWER(1e1, 3) AS float
INTO power_test;
EXECUTE sp_help power_test;
DROP TABLE power_test;
関連する結果は次のとおりです。
Column_name Type Length Prec Scale
-------------------------------------------------
int int 4 10 0
numeric0 numeric 17 38 0
numeric1 numeric 17 38 1
numeric5 numeric 17 38 5
float float 8 53 NULL
起こっているように見えるのは、を含まず、それに適合する最小の型にPOWER()キャストfloat_expressionすることBIGINTです。
したがって、10 38の結果を保持するのに十分な大きさにキャストされないSELECT POWER(10.0, 38);ため、オーバーフローエラー10.0NUMERIC(38, 1)で失敗します。これは、10 38が10進数の前に39桁を占めるように展開するのに対しNUMERIC(38, 1)、10進数の前に37桁と1桁を格納できるためです。したがって、最大値をNUMERIC(38, 1)保持することができるが10である37 - 0.1です。
この理解を武器に、次のように別のオーバーフロー障害を作成できます。
SELECT POWER(1000000000, 3); -- one billion
10億は(にキャストされる最初の例の1兆ドルとは対照的にNUMERIC(38, 0))に収まるほど十分に小さいINTです。ただし、10億を3乗すると、には大きすぎINTてオーバーフローエラーになります。
他のいくつかの関数は、出力タイプが入力に依存する同様の動作を示します。
- 数学関数:
POWER()、CEILING()、FLOOR()、RADIANS()、DEGREES()、およびABS()
- システム関数と表現:
NULLIF()、ISNULL()、COALESCE()、IIF()、CHOOSE()、とCASE表現
- 算術演算子:
SELECT 2 * @MAX_INT;およびの両方SELECT @MAX_SMALLINT + @MAX_SMALLINT;は、たとえば、変数の名前がデータ型である場合、算術オーバーフローになります。
結論
この特定の場合、解決策はを使用することSELECT POWER(1e1, precision)...です。これは、とんでもないほど大きな数を保持できる1e1キャストされるためFLOAT、すべての可能な精度で機能します。
これらの関数は非常に一般的であるため、結果が丸められたり、その動作によりオーバーフローエラーが発生したりする可能性があることを理解することが重要です。出力に特定のデータ型が必要な場合、または依存する場合は、必要に応じて関連する入力を明示的にキャストしてください。
それで、子供たち、あなたはこれを知ったので、あなたは出て行って、繁栄するかもしれません。