0

这让我们感到困惑......

我们有一个使用 CAST 将浮点数转换为小数的查询,此查询连接多个表以查找要返回的行。其中一个表中的一行包含一个值,当 CAST 转换为小数时会导致算术溢出错误。

奇怪的是,具有此值的行不是结果集中返回的行之一。

过于简化的例子:

ID  Value
1   1.1
2   11.1
3   11111.1

询问:

SELECT Id, CAST(value as decimal(4,1))
FROM <complex number of joins>
WHERE <conditions that don't return row with Id 3>

... 算术错误

如果我们在 WHERE 子句中明确排除该行,那么错误就会消失。例如。WHERE ... AND Id <> 3

.. 工作正常

有谁知道这怎么可能?

注意:这里的问题不是 CAST 在 ID 为 3 的行上失败!问题是 WHERE 子句排除了 ID 为 3 的行,但查询仍然失败。如果 WHERE 子句没有返回值为 11111.1 的行,查询如何失败?

4

3 回答 3

0

类型DECIMAL(4, 1)表示总共四位精度,其中一位在小数点右边。因此,为了适应价值11111.1,您至少需要DECIMAL(6, 1). 以下查询应该有效:

SELECT Id, CAST(value AS DECIMAL(6,1))
FROM <complex number of joins>
WHERE <conditions that don't return row with Id 3>

至少,以上内容适用于您提供的三点样本数据。

演示

于 2020-01-17T05:00:57.517 回答
0

这不是因为您过滤数据的 where 条件,而是因为您在演员表中选择了较少的数据长度。您应该将其更改为 DECIMAL(8,2) 或列数据的最大长度。您可以尝试以下示例,它将向您解释它是如何工作的。

以下将起作用,因为它不获取任何数据

WITH yourTable AS (
    SELECT 1 AS ID, '1.1' AS Value UNION ALL
    SELECT 2, '11.1' UNION ALL
    SELECT 3, '11111.1313'
)

SELECT Id, CAST(value as decimal(4,1)) AS Id_casted
FROM yourTable WHERE yourTable.ID=4

以下将不起作用,因为十进制值超过了转换长度

WITH yourTable AS (
    SELECT 1 AS ID, '1.1' AS Value UNION ALL
    SELECT 2, '11.1' UNION ALL
    SELECT 3, '11111.1313'
)

SELECT Id, CAST(value as decimal(4,1)) AS Id_casted
FROM yourTable WHERE yourTable.ID=3

您可以通过将 Decimal(4,1) = 3 digit 更改为 Decimal(8,2) = 6 digit 来解决此问题

WITH yourTable AS (
    SELECT 1 AS ID, '1.1' AS Value UNION ALL
    SELECT 2, '11.1' UNION ALL
    SELECT 3, '11111.1313'
)

SELECT Id, CAST(value as DECIMAL(8,2)) AS Id_casted
FROM yourTable WHERE yourTable.ID=3

简单的以下代码显示它会引发异常,因为 numeric(5,2) 的最大值将为 999.99,当您分配 1000 时,它将引发异常

DECLARE @aritherror NUMERIC(5,2)
SET @aritherror = 1000.554
SELECT @aritherror
于 2020-01-17T05:46:39.077 回答
0

似乎是在操作后应用过滤器,而不是相反。查看查询的执行计划,以帮助您了解操作的顺序。

于 2020-01-17T05:25:25.517 回答