Varchar 和 nvarchar 不同的隐式转换为 int

Varchar and nvarchar different implicit conversion to int

SQL 服务器 2017。整理:SQL_Latin1_General_CP1_CI_AS

遗留数据库。

以下代码:

DECLARE @qav nvarchar(255)
SET @qav = '-89'

SELECT CASE WHEN @qav < '0' THEN 1 ELSE 0 END as char_test

----=====================================

DECLARE @qav1 varchar(255)
SET @qav1 = '-89'

SELECT CASE WHEN @qav1 < '0' THEN 1 ELSE 0 END as char_test

结果不同:

char_test   
----------- 
0           

char_test   
----------- 
1           

谁能解释为什么 nvarchar '-89' < '0' 在使用 varcharnvarchar 时返回不同的结果?

字符串和数字完全不同。字符串按每个字符从左到右排序,数字按数字顺序排列。这只是使用 正确 数据类型如此重要的原因之一。

'10' 小于 '2'因为'2'大于'1';因此 '10' 小于 '2''09-12-2019' 是“before'31-01-1924' 因为 '3' 大于 '0'.

如果要比较数字,请使用数字数据类型,而不是字符串。如果您要比较日期(和时间),请使用日期和时间数据类型,而不是字符串。


显示 OP 实际询问的内容 Data Type Precedence。当 2 个表达式具有不同的数据类型并进行比较时,数据优先级用于将表达式的一侧隐式转换为与另一侧相同。

在您的查询中有 2 个表达式:@qav1 < '0'@qav1 < 0。前者不受数据类型优先级的影响,因为双方相同。结果,-0 进行比较,后者具有 更大的 值,因此返回 1

对于第二个表达式,'-89' 由于数据类型优先级而隐式转换为 int,因此表达式成为 -89 < 0。这是真的,所以 1 被返回。

SQL Server uses the following precedence order for data types:

  1. user-defined data types (highest)
  2. sql_variant
  3. xml
  4. datetimeoffset
  5. datetime2
  6. datetime
  7. smalldatetime
  8. date
  9. time
  10. float
  11. real
  12. decimal
  13. money
  14. smallmoney
  15. bigint
  16. int
  17. smallint
  18. tinyint
  19. bit
  20. ntext
  21. text
  22. image
  23. timestamp
  24. uniqueidentifier
  25. nvarchar (including nvarchar(max) )
  26. nchar
  27. varchar (including varchar(max) )
  28. char
  29. varbinary (including varbinary(max) )
  30. binary (lowest)

对于隐式转换,int 的优先级高于 varcharnvarchar(Implicit and explicit conversion).
所以在这种情况下:

'-89' < 0

'-89' 转换为 int 等同于:

-89 < 0

TRUE