我不会再干预Martin的回答,而是在此添加我的其余发现POWER()。
坚持你的内裤。
前言
首先,我向您展示A 的MSDN文档POWER():
句法
POWER ( float_expression , y )
争论
float_expression
是float类型或可以隐式转换为float类型的表达式。
返回类型
与相同float_expression。
您可以通过阅读POWER()返回类型为的最后一行来得出结论FLOAT,但请再次阅读。float_expression是“ float类型或可以隐式转换为float的类型”。因此,尽管有其名称,float_expression但实际上可能是a FLOAT,a DECIMAL或an INT。由于的输出与的输出POWER()相同float_expression,因此它也可能是这些类型之一。
因此,我们有一个标量函数,其返回类型取决于输入。可以吗
观察结果
我向您展示了B,这是一个测试,POWER()它证明了根据输入将其输出转换为不同数据类型的测试。
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。
因此,SELECT POWER(10.0, 38);由于出现溢出错误而失败,因为10.0将其强制转换NUMERIC(38, 1)为不足以容纳10 38的结果。这是因为10 38扩展为小数点前有39位数字,而NUMERIC(38, 1)可以存储小数点前有37位数字和小数点后一位。因此,最大值NUMERIC(38, 1)可容纳10 37 - 0.1。
有了这种理解,我可以编写出另一个溢出失败,如下所示。
SELECT POWER(1000000000, 3); -- one billion
10亿(相对于第一个示例中的1万亿,后者被强制转换为NUMERIC(38, 0))小到足以容纳INT。但是,将十亿加到三阶幂对于来说太大了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,因此可以适用于所有可能的精度,该精度可以容纳大量的数字。
由于这些函数非常普遍,因此必须了解结果可能会被舍入或由于其行为而导致溢出错误,这一点很重要。如果您期望或依赖于特定的数据类型来输出,请根据需要显式转换相关输入。
因此,孩子们,既然您知道这一点,就可以继续前进并繁荣起来。