Jul*_*ira 9 sql-server collation tempdb
我刚刚从我的客户那里收到了一个应用程序的源代码和数据库(它是由来自不同国家的另一家公司开发的),并且该应用程序抛出了一些与对象整理相关的异常:
无法解决 equal to 操作中“SQL_Latin1_General_CP1_CI_AS”和“Latin1_General_CI_AS”之间的排序规则冲突。
我看到,在我的情况下,这是由于存储过程创建了一个 #temp 表并且该#temp
表用于与应用程序中的表(应用程序数据库使用SQL_Latin1_General_CP1_CI_AS
和tempdb
使用Latin1_General_CI_AS
)进行比较时引起的。
我加入COLLATE SQL_Latin1_General_CP1_CI_AS
的CREATE TABLE #TEMPTABLE
声明,但是这个数据库有很多存储过程可以使用#temp
表。
如何在不破坏其他数据库/应用程序的情况下更快地解决这个问题?
这个数据库需要在这个实例上吗?如果没有,那么正如@Max Vernon 在对该问题的评论中所建议的那样,您可以将其安装在使用默认排序规则为SQL_Latin1_General_CP1_CI_AS
. 如果数据库小于 10 GB 并且不需要任何企业版功能,您甚至可以使用 SQL Server Express Edition。
但如果这不是一个选择,那么你已经在做的事情,
将 COLLATE SQL_Latin1_General_CP1_CI_AS 添加到 CREATE TABLE #TEMPTABLE 语句
几乎是你能做的唯一可靠的事情。
由于您不想对客户端交付的应用程序的操作产生不利影响,因此您无法更改新数据库的排序规则。事实上,更改数据库的默认排序规则不会解决您当前的问题,因为它不会更新该数据库中表中列的排序规则。它只会影响字符串文字和变量的排序规则,并且只有当这两个东西是唯一被比较的东西时,您才会注意到差异(因为列的排序规则会覆盖字符串文字和变量的隐含排序规则)。
由于您不想对 SQL Server 上的现有数据库产生不利影响,因此将当前实例的排序规则更改为SQL_Latin1_General_CP1_CI_AS
.
考虑到新数据库和相关代码是在具有SQL_Latin1_General_CP1_CI_AS
默认排序规则的实例上开发的(并希望对其进行测试!),您确实需要这样做,以便新数据库中的查询表现得与它们在其中的环境中一样被创造。您只能通过添加COLLATE
子句来强制对临时表中的字符串列进行排序规则(正如您所做的那样)。好吧,从技术上讲,您可以将临时表更改为表变量,因为它们的默认排序规则将从当前数据库中获取,但这是一个更具侵入性的更改,因为查询优化器不会以与临时表相同的方式处理表变量(并且还有其他显着差异)。
在COLLATE
子句中,您可以使用任一DATABASE_DEFAULT
或继续使用SQL_Latin1_General_CP1_CI_AS
。两者在这里是等价的,因为新数据库的排序规则不太可能会改变(如果它改变了,这意味着您将从客户端获得一个不包括您的更改的新数据库;-)。
仅供参考:SQL_Latin1_General_CP1_CI_AS
和之间没有太多区别Latin1_General_CI_AS
。它们都使用相同的区域设置——1033——和相同的代码页——1252。主要区别是:
SQL_
排序规则已过时了很长一段时间,如果可能,应避免SQL_
排序规则允许 Unicode 提供的一些扩展/规范化,这将等同于比SQL_
排序规则更多的字符。这取决于,例如连接到另一个国家/地区的一个或多个数据库,其变体排序规则是其所在地区的标准位置。
如果是这样,那么您需要有两个(或更多)排序规则,例如连接具有变体排序规则的数据库(或表)。
也许最好的选择是在查询中包含 COLLATE DATABASE_DEFAULT。这将处理许多(但不是全部)排序问题。
下面是一个非常简单的例子:
SELECT [ITEM_KEY],[PERSON_NAME]
FROM [TempDB].[dbo].[ITEM] AS SC
JOIN [NonStandardCollation].[dbo].[REMOTEITEM] AS NSC
WHERE SC.ITEM_KEY COLLATE DATABASE_DEFAULT = NSC.ITEM_KEY
Run Code Online (Sandbox Code Playgroud)
在这种情况下,特别是在处理其他几种排序规则时,它将简化服务器上的代码。
归档时间: |
|
查看次数: |
8160 次 |
最近记录: |