SQL Server 消息245,级别16,状态1,第4行将nvarchar值“239.6”转换为数据类型int时转换失败

csga3l58  于 2022-11-21  发布在  其他
关注(0)|答案(1)|浏览(294)

我 有 这样 的 疑问 :

SELECT     SerialNumber
FROM       [ETEL-PRDSQL].[ERP10DBLIVE].[ERP].[SerialNo]
WHERE      CustNum IN (2);

中 的 每 一 个
它 导致 此 错误 :
消息 245 , 级别 16 , 状态 1 , 第 4 行
将 nvarchar 值 " 239.6 " 转换 为 int 数据 类型 时 转换 失败 。
如果 我 将 CustNum 与 不同 的 值 进行 比较 , 则 该 查询 有效 , 但 当 我 尝试 CustNum IN (2) 时 , 查询 失败 。
我 该 如何 解决 这个 问题 ?

qnakjoqk

qnakjoqk1#

您有一个名为CustNumvarchar列。此列中的varchar值可能只包含数字,但这并不表示它们是数字!然后将此文本列与整数值2进行比较。同样,整数值2与文本值'2' * 不相同 *。它也与浮点值2.0不相同。它们都是不同的,它们具有不同的类型,SQLServer必须先解决任何此类差异,然后才能比较值。
根据type precedence rules,SQL Server确定需要将列中的文本转换为整数,而不是将整数转换为文本。一旦对查询做出了此确定,如果文本列中的任何数据与
整数
不兼容,则查询将失败。
了解这种转换与WHERE子句中的条件检查是分开进行的,这一点很重要,而且它是进行条件检查的先决条件。对于不转换的行,仅期望WHERE条件的计算结果为FALSE是不够的。即使您不需要该行,也是如此,因为SQL Server在尝试转换之前无法知道您不需要该行!
在本例中,我们有一个值293.6。该值可以是数字,但不是整数,也不能转换为整数。因此查询失败。
除了(最终!)查询失败,这对性能来说绝对是糟糕的。SQL Server必须对表中的每一行**进行这种转换 *...甚至是您不需要的行。这是因为SQL Server在检查条件表达式之前不知道哪些行将匹配WHERE子句,而且它需要进行这种转换才能进行检查。更糟糕的是,新的转换值不再与您的索引匹配,因此您可能拥有的任何索引对于此查询都变得毫无价值。这会降低数据库性能的核心。
如果您不喜欢它,请更好地定义数据类型,或者尝试将该字符串与另一个字符串进行比较:

SELECT     SerialNumber
FROM       [ETEL-PRDSQL].[ERP10DBLIVE].[ERP].[SerialNo]
WHERE      CustNum IN ('2');

如果执行以下操作,也可能会运行查询:

SELECT     SerialNumber
FROM       [ETEL-PRDSQL].[ERP10DBLIVE].[ERP].[SerialNo]
WHERE      CustNum IN (2.0);

现在,类型优先级规则会将文本转换为浮点类型,如果表中的其余值都兼容,则转换可能会成功。也有可能这更接近您的预期......但同样,此处的性能会差得多。

相关问题