给出下表:
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')
如果我运行以下查询;
SELECT *
FROM #a
LEFT JOIN #b
ON #a.MyInt = #b.MyVarchar
SQL Server 必须执行隐式转换,因为#a.MyInt
和#b.MyVarchar
是不匹配的数据类型。由于数据类型优先级,具有最低类型优先级 (#b.MyVarchar) 的列将转换为较高优先级 (INT) 的类型
这意味着上面的查询等效于
SELECT *
FROM #a
LEFT JOIN #b
ON #a.MyInt = CONVERT(INT,#b.MyVarchar)
两者都失败,因为其中某个值#b.MyVarchar
对于列来说是无效值INT
。
我的问题是为什么 的VARCHAR
优先级低于INT
?如果是相反的情况,隐式转换将会成功,但我们会得到一个错误的查询。为什么错误比成功执行更可取?我的猜测是,这对于 SQL Server 来说更像是一种“防御”机制 - 它更喜欢错误,因此需要用户明确决定他们想要做什么,而不是在用户不知情的情况下给出可能意外的查询结果。意识到?
由于 SQL Server 是 RDBMS,因此它们针对针对正确定义的表发送 SQL 查询的应用程序进行了优化。
降低 varchar 的数据类型优先级使引擎能够在评估将参数作为文字字符串或 varchar 参数发送的查询时避免对列表达式进行隐式转换:
或者
在这两种常见情况下,我们避免转换每一行的值并使用此策略启用索引查找。
我们有两种可能的场景来比较字符串和整数:
我们可以说第一种情况更快,因为只有一个多刻度操作。
当我们需要进行这种比较时,这种情况非常罕见,因此即使我们知道第二种情况提供了更大的灵活性 - 这种需要也是非常罕见的。所以速度获胜。
也正是这样,sql引擎展现了编程的本质。通过定义,
Strongly Typed
等数据类型,对数据进行严格的限制和维护。它展现了 的特点。datetime
INT
BIT
data integrity
RDBMS
所以上面的数据示例查询肯定会失败。