SEa*_*986 2 sql-server datatypes errors implicit-conversions
给出下表:
CREATE TABLE #a
(
MyInt INT
)
INSERT INTO #a VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)
CREATE TABLE #b
(
MyVarchar VARCHAR(10)
)
INSERT INTO #b VALUES('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9'),('ten')
Run Code Online (Sandbox Code Playgroud)
如果我运行以下查询;
SELECT *
FROM #a
LEFT JOIN #b
ON #a.MyInt = #b.MyVarchar
Run Code Online (Sandbox Code Playgroud)
SQL Server 必须执行隐式转换,因为#a.MyInt
和#b.MyVarchar
是不匹配的数据类型。由于数据类型优先级,具有最低类型优先级 (#b.MyVarchar) 的列将转换为较高优先级 (INT) 的类型
这意味着上面的查询等效于
SELECT *
FROM #a
LEFT JOIN #b
ON #a.MyInt = CONVERT(INT,#b.MyVarchar)
Run Code Online (Sandbox Code Playgroud)
两者都失败,因为其中某个值#b.MyVarchar
对于列来说是无效值INT
。
我的问题是为什么 的VARCHAR
优先级低于INT
?如果是相反的情况,隐式转换将会成功,但我们会得到一个错误的查询。为什么错误比成功执行更可取?我的猜测是,这对于 SQL Server 来说更像是一种“防御”机制 - 它更喜欢错误,因此需要用户明确决定他们想要做什么,而不是在用户不知情的情况下给出可能意外的查询结果。意识到?
由于 SQL Server 是 RDBMS,因此它们针对针对正确定义的表发送 SQL 查询的应用程序进行了优化。
降低 varchar 的数据类型优先级使引擎能够在评估将参数作为文字字符串或 varchar 参数发送的查询时避免对列表达式进行隐式转换:
select *
from someTable
where SomeIntColumn = '1'
Run Code Online (Sandbox Code Playgroud)
或者
where SomeDateColumn = '2024-01-01'
Run Code Online (Sandbox Code Playgroud)
在这两种常见情况下,我们避免转换每一行的值并使用此策略启用索引查找。
这也使得查询的形式
where SomeIntColumn = 'not convertable to int'
Run Code Online (Sandbox Code Playgroud)
失败而不是返回零行。
归档时间: |
|
查看次数: |
101 次 |
最近记录: |