在这种情况下 SQL Server 隐式类型转换如何工作?

问题描述 投票:0回答:3

当我在 SQL Server 中尝试此即席查询时(假设

UserId
是 NVARCHAR 字段):

SELECT * FROM MyUser WHERE UserId = 123456

我收到此错误:

消息 245,第 16 级,状态 1,第 1 行
将 nvarchar 值“foo”转换为数据类型 int 的列时出现语法错误。

显然在我的

'foo'
列下有一个值
UserId

为什么 SQL Server 尝试将我的整个列转换为 INTEGER,而不是执行对我来说显而易见的操作:将我的搜索值转换为 NVARCHAR?

sql-server implicit-conversion
3个回答
4
投票

使用数据类型优先级的规则进行比较:

当操作员将两个 不同数据类型的表达式, 数据类型优先级规则 指定数据类型 较低的优先级被转换为 优先级较高的数据类型。

优先级1表示最高。因此

NVARCHAR
类型(优先级 25)转换为
int
(优先级 16),因为
NVARCHAR
在此规模中的优先级较低。


2
投票

我认为这是因为它无法比较不同类型的两个值。然后,必须将两个相等比较成员转换为相同类型。我想,在这里,

int
是首选。

我相信

int
优先于
nvarchar
类型,因此它必须隐式尝试将
nvarchar
转换为 int 值。

编辑#1

“但是,尝试将我给出的值转换为我正在搜索的字段的类型,而不是相反,这不是明智的做法吗?”

是的,如果可以的话那就太好了。但我想这是因为在尝试其他类型的比较时会有太多的转换尝试暗示。

where dateOfBirth = 1976-6-16

where dateOfBirth = N'1976-06-16'

在第一个例子中,用户的意图是什么?是验证

dateOfBirth
是否等于
1976-06-16
的日期值,还是与
1976 - 6 - 16
的整数值进行比较,得到
1954
,这可以合理地认为它是年份任何给定的日期。

我认为存在隐式转换,例如

nvarchar
datetime
,但有很多内容需要涵盖,因此他们将自己限制为最常见的可能转换。


1
投票

如果您知道列是 NVARCHAR,为什么还要指定整数值?

不幸的是,与许多 SQL 实现一样,SQL Server 在类型支持方面远远落后于其他语言。类型检查通常仅在运行时执行。因此,像您这样的查询不会进行语法检查以突出显示您在这里遇到的问题。您的查询有问题,因为您不匹配不同的类型,但由于 SQL Server 不会对其进行验证,因此结果将是不可预测的,具体取决于数据。

© www.soinside.com 2019 - 2024. All rights reserved.