每次启动 SQL Server 时,都会创建 tempdb 数据库。该数据库与 model 数据库具有相同的默认排序规则。这通常与实例的默认排序规则相同。如果为创建的用户数据库指定的默认排序规则与 model 的排序规则不同,则该用户数据库与 tempdb 的默认排序规则也不同。所有临时存储过程或临时表都创建和存储在 tempdb 中。这意味着临时表中的所有隐式列以及临时存储过程中的所有强制默认常量、变量和参数都具有与可比较对象(在永久表和存储过程中创建)不同的排序规则。
这将导致用户定义的数据库和系统数据库对象之间的排序规则出现互相不匹配的问题。例如,SQL Server 实例使用 Latin1_General_CS_AS 排序规则,而您执行以下语句:
CREATE DATABASE TestDB COLLATE Estonian_CS_AS;
USE TestDB;
CREATE TABLE TestPermTab (PrimaryKey int PRIMARY KEY, Col1 nchar );
在此系统中,tempdb 数据库使用代码页 1252 的 Latin1_General_CS_AS 排序规则,TestDB 和 TestPermTab.Col1 使用代码页 1257 的 Estonian_CS_AS 排序规则。例如:
USE TestDB;
GO
-- Create a temporary table with the same column declarations
-- as TestPermTab
CREATE TABLE #TestTempTab (PrimaryKey int PRIMARY KEY, Col1 nchar )
INSERT INTO #TestTempTab
SELECT * FROM TestPermTab
GO
在上述示例中,tempdb 数据库使用 Latin1_General_CS_AS 排序规则,TestDB 和 TestTab.Col1 使用 Estonian_CS_AS 排序规则。例如:
SELECT * FROM TestPermTab a INNER JOIN #TestTempTab on a.Col1 = #TestTempTab.Col1
由于 tempdb 使用默认的服务器排序规则,而 TestPermTab.Col1 使用其他排序规则,因此 SQL Server 会返回如下错误:“无法解决等于运算中 'Latin1_General_CI_AS_KS_WS' 与 'Estonian_CS_AS' 之间的排序规则冲突。”
为防止出现此错误,可以使用下列方法之一:
-
指定临时表列使用用户数据库(而不是 tempdb)的默认排序规则。如果系统需要,这可以使临时表在多个数据库中使用具有类似格式的表。
CREATE TABLE #TestTempTab
(PrimaryKey int PRIMARY KEY,
Col1 nchar COLLATE database_default
)
-
为
#TestTempTab 列指定正确的排序规则:
CREATE TABLE #TestTempTab
(PrimaryKey int PRIMARY KEY,
Col1 nchar COLLATE Estonian_CS_AS
)