Dav*_*vid 6 sql sql-server floating-point numbers
附件是在SQL中运行的代码示例.这似乎是SQL Server的意外行为.应该发生的是从数字中删除负数,但是当在更新命令下使用相同的函数时,它会执行绝对值并对数字进行舍入.为什么是这样?
DECLARE @TEST TABLE (TEST varchar(2048));
INSERT INTO @TEST VALUES (' -29972.95');
SELECT TEST FROM @TEST;
SELECT ABS(TEST) FROM @TEST;
UPDATE @TEST SET TEST = ABS(TEST);
SELECT TEST FROM @TEST;
Run Code Online (Sandbox Code Playgroud)
以下是该代码的结果.
-29972.95
29972.95
29973
Run Code Online (Sandbox Code Playgroud)
这似乎更像是函数的“功能” ,而不是与orCONVERT相关的任何内容(它不同的唯一原因是因为隐式地将back返回的值转换为)。SELECTUPDATEUPDATEFLOAT(8)ABS(...)VARCHAR
更新计划中的计算标量包含表达式
[Expr1003] = Scalar Operator(CONVERT_IMPLICIT(varchar(2048),
abs(CONVERT_IMPLICIT(float(53),[TEST],0))
,0) /*<-- style used for convert from float*/
)
Run Code Online (Sandbox Code Playgroud)
值 - 输出
0(默认)- 最多 6 位数字。适当时使用科学记数法。
1 - 始终为 8 位数字。始终使用科学记数法。
2 - 始终为 16 位数字。始终使用科学记数法。
这可以在下面的示例中看到:
SELECT
[# Digits],
CONVERT(FLOAT(8), CONVERT(VARCHAR(20), N)) AS [FLOAT(VARCHAR(N))],
CONVERT(FLOAT(8), CONVERT(VARCHAR(20), N, 0)) AS [FLOAT(VARCHAR(N, 0))],
CONVERT(FLOAT(8), CONVERT(VARCHAR(20), N, 1)) AS [FLOAT(VARCHAR(N, 1))]
FROM (SELECT '6 digits', ABS('9972.95') UNION ALL SELECT '7 digits', ABS('29972.95')) T ([# Digits], N)
Run Code Online (Sandbox Code Playgroud)
这将返回以下结果:
# Digits FLOAT(VARCHAR(N)) FLOAT(VARCHAR(N, 0)) FLOAT(VARCHAR(N, 1))
-------- ----------------- -------------------- --------------------
6 digits 9972.95 9972.95 9972.95
7 digits 29973 29973 29972.95
Run Code Online (Sandbox Code Playgroud)
这证明UPDATE使用CONVERT(VARCHAR, ABS(...))默认样式“0”是有效的。这将 限制FLOAT为ABS6 位数字。去掉 1 个字符,以免隐式转换溢出,在此场景中您保留实际值。
回到OP:
ABS返回 a FLOAT(8)。UPDATE导致隐式转换,实际上是“CONVERT(VARCHAR(2048), ABS(...), 0)”,然后溢出了默认样式的最大位数。| 归档时间: |
|
| 查看次数: |
141 次 |
| 最近记录: |