gpt4 book ai didi

sql - SELECT 与 UPDATE,使用 ABS 函数时出现意外四舍五入

转载 作者:行者123 更新时间:2023-12-04 13:05:35 24 4
gpt4 key购买 nike

附件是在 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;

以下是该代码的结果。
  -29972.95
29972.95
29973

最佳答案

这似乎更像是 CONVERT 的“功能”功能比什么都重要SELECTUPDATE (唯一不同的原因是 UPDATE 隐式地将 FLOAT(8) 返回的 ABS(...) 转换回 VARCHAR )。

更新计划中的计算标量包含表达式

[Expr1003] = Scalar Operator(CONVERT_IMPLICIT(varchar(2048),
abs(CONVERT_IMPLICIT(float(53),[TEST],0))
,0) /*<-- style used for convert from float*/
)

Value - Output

0 (default) - A maximum of 6 digits. Use in scientific notation, when appropriate.

1 - Always 8 digits. Always use in scientific notation.

2 - Always 16 digits. Always use in scientific notation.



来自 MSDN: https://docs.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-2017

这可以在下面的示例中看到:
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)

这将返回以下结果:
# 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

这证明了 UPDATE正在使用 CONVERT(VARCHAR, ABS(...))有效地使用默认样式“0”。这限制了 FLOAT来自 ABS到 6 位数字。去掉 1 个字符,这样它就不会溢出隐式转换,在这种情况下您会保留实际值。

将此带回 OP:
  • ABS在这种情况下,函数返回 FLOAT(8)在示例中。
  • UPDATE然后导致一个隐式转换,实际上是`CONVERT(VARCHAR(2048), ABS(...), 0),然后溢出了默认样式的最大数字。
  • 为了避免这种行为(如果这与实际问题有关),您需要指定 1 或 2(甚至 3 以获得 17 位数字)的样式以避免这种截断(但一定要处理自以下以来使用的科学记数法)现在总是在这种情况下返回)
  • 关于sql - SELECT 与 UPDATE,使用 ABS 函数时出现意外四舍五入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53196295/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com