【问题标题】:Why is SQL Server trying to convert my nvarchar(20) datatype to an int?为什么 SQL Server 试图将我的 nvarchar(20) 数据类型转换为 int?
【发布时间】:2018-04-27 22:42:29
【问题描述】:

我在 SQL Select 查询中遇到“转换”错误。

错误是:

消息 248,第 16 级,状态 1,第 6 行
nvarchar 值 '7000952682' 的转换溢出了一个 int 列。

问题是,我的表中没有 int 列!

这是表结构:

这里是查询:

如果我将@SU 的值设置为NULL,那么它会按预期返回所有行。当该值设置为“7000952682”的字符串值时,我收到错误消息。

为什么 SQL Server 试图将 nvarchar 值转换为 int?

【问题讨论】:

  • 看起来 CASE 语句正在尝试将表中 SU 列的值转换为 int。有没有办法确认这一点并强制它保持 nvarchar 值与其他 nvarchar 值进行比较(而不是尝试将它/它们转换为整数)?
  • 请阅读meta.stackoverflow.com/questions/285551/… 和接受的答案

标签: sql sql-server tsql


【解决方案1】:

CASE 表达式的所有分支必须具有相同的类型。在这种情况下(没有双关语),看起来 SQL Server 正在使用整数类型并将 SU 隐式转换为整数。问题是 SQL Server 中整数的最大值约为 21 亿,而您给出的示例是使用值 7000952682,因此溢出。

这里有两个选择。你可以做任何事情varchar:

CASE WHEN @SU IS NULL OR @SU = '' THEN '1' ELSE [SU] END

或者,您可以使用不会溢出的类型将所有内容设为数字,例如

CASE WHEN @SU IS NULL OR @SU = ''
     THEN CAST(1 AS numeric(20, 6))
     ELSE CAST([SU] AS numeric(20, 6)) END

作为旁注,您可以使用COALESCE 更简洁地编写CASE 表达式的第一部分:

CASE WHEN COALESCE(@SU, '') = '' THEN '1' ELSE [SU] END

【讨论】:

  • 将“THEN 1”更改为“THEN '1'”解决了这个问题。
【解决方案2】:

不要在where 子句中使用case。逻辑更简单准确表示为:

where (@su is null or @su = '' or @su = su)

【讨论】:

  • 虽然蒂姆的回答正确地解释了问题,但恕我直言,这个答案更好,因为它为整个 where 子句提供了更好的选择。,使用isnull(@su, '') = '' or so = @su 甚至会更好。两者都 +1。
猜你喜欢
  • 2023-03-06
  • 1970-01-01
  • 2013-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-06
相关资源
最近更新 更多