我 有 这样 的 疑问 :
SELECT SerialNumber
FROM [ETEL-PRDSQL].[ERP10DBLIVE].[ERP].[SerialNo]
WHERE CustNum IN (2);
中 的 每 一 个
它 导致 此 错误 :
消息 245 , 级别 16 , 状态 1 , 第 4 行
将 nvarchar 值 " 239.6 " 转换 为 int 数据 类型 时 转换 失败 。
如果 我 将 CustNum
与 不同 的 值 进行 比较 , 则 该 查询 有效 , 但 当 我 尝试 CustNum IN (2)
时 , 查询 失败 。
我 该 如何 解决 这个 问题 ?
1条答案
按热度按时间qnakjoqk1#
您有一个名为
CustNum
的varchar
列。此列中的varchar
值可能只包含数字,但这并不表示它们是数字!然后将此文本列与整数值2
进行比较。同样,整数值2
与文本值'2'
* 不相同 *。它也与浮点值2.0
不相同。它们都是不同的,它们具有不同的类型,SQLServer必须先解决任何此类差异,然后才能比较值。根据type precedence rules,SQL Server确定需要将列中的文本转换为整数,而不是将整数转换为文本。一旦对查询做出了此确定,如果文本列中的任何数据与整数不兼容,则查询将失败。
了解这种转换与WHERE子句中的条件检查是分开进行的,这一点很重要,而且它是进行条件检查的先决条件。对于不转换的行,仅期望WHERE条件的计算结果为FALSE是不够的。即使您不需要该行,也是如此,因为SQL Server在尝试转换之前无法知道您不需要该行!
在本例中,我们有一个值
293.6
。该值可以是数字,但不是整数,也不能转换为整数。因此查询失败。除了(最终!)查询失败,这对性能来说绝对是糟糕的。SQL Server必须对表中的每一行**进行这种转换 *...甚至是您不需要的行。这是因为SQL Server在检查条件表达式之前不知道哪些行将匹配WHERE子句,而且它需要进行这种转换才能进行检查。更糟糕的是,新的转换值不再与您的索引匹配,因此您可能拥有的任何索引对于此查询都变得毫无价值。这会降低数据库性能的核心。
如果您不喜欢它,请更好地定义数据类型,或者尝试将该字符串与另一个字符串进行比较:
如果执行以下操作,也可能会运行查询:
现在,类型优先级规则会将文本转换为浮点类型,如果表中的其余值都兼容,则转换可能会成功。也有可能这更接近您的预期......但同样,此处的性能会差得多。