1

当我在 SQL Server 中尝试这个临时查询时(假设UserId是 NVARCHAR 字段):

SELECT * FROM MyUser WHERE UserId = 123456

我收到此错误:

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

'foo'显然,在我的UserId专栏下面的某个地方有一个值。

为什么 SQL Server 试图将我的整个列转换为 INTEGER,而不是做对我来说显而易见的事情:将我的搜索值转换为 NVARCHAR?

4

3 回答 3

3

比较是使用Data Type Precedence的规则完成的:

当运算符组合不同数据类型的两个表达式时,数据类型优先级规则指定将具有较低优先级的数据类型转换为具有较高优先级的数据类型。

类型(NVARCHAR优先级 25)转换为int(优先级 16)。请注意,优先级 1 表示“最高”。

于 2010-11-19T16:55:04.543 回答
2

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

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

编辑#1

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

是的,如果这样做会很好。但我想那是因为在尝试其他类型的比较时,会有太多的转换试图暗示。

where dateOfBirth = 1976-6-16

对比

where dateOfBirth = N'1976-06-16'

在第一个例子中,用户的意图是什么?是验证 是否dateOfBirth等于 的日期值,1976-06-16还是与 的整数值进行比较1976 - 6 - 16,这将导致1954,这可能足够合理,可以将其视为任何给定日期的年份。

我认为存在诸如nvarcharto之类的隐式转换datetime,但是要涵盖的内容很多,因此它们将自己限制为最常见的可能转换。

于 2010-11-19T16:51:30.127 回答
1

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

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

于 2010-11-19T17:15:13.277 回答