在TSQL查询中使用COLLATE是否会进行永久性更改?

时间:2017-07-18 16:07:39

标签: sql sql-server tsql

我需要查询JOIN来自不同数据库(同一服务器)中不同表的两列,但是我收到此错误:

  

无法解决" A"之间的整理冲突和" B"在等于操作。

错误源自查询行,我在其中对两个表进行比较。

我知道我可以使用COLLATE来确保两个比较值具有相同的排序规则,但我想知道这是否对这些表有任何永久性影响,如永久整理更改,因为它们是需要它们用于其他应用程序。

示例:

SELECT t1.value1, t1.value2, t2.value3 
FROM db1.dbo.tbl1 AS t1
JOIN db2.dbo.tbl2 AS t2 ON t1.ID = t2.ID

2 个答案:

答案 0 :(得分:1)

将COLLATE想象成“CAST”...它只是说“将此字符串解释为此排序规则”,这样您就可以使两个排序规则相同,并进行正确的比较。

从你的例子:

SELECT t1.value1, t1.value2, t2.value3 
  FROM db1.dbo.tbl1 AS t1
       INNER JOIN JOIN db2.dbo.tbl2 AS t2
       ON t1.ID COLLATE DATABASE_DEFAULT = t2.ID COLLATE DATABASE_DEFAULT

这里我只使用“DATABASE_DEFAULT”作为示例排序规则...使用您希望的任何排序规则(如果您使用其中一个列的排序规则,则只需要一个COLLATE语句...在OTHER计划中)。

有意义吗?

答案 1 :(得分:0)

要回答您的问题,我们首先要确保我们在同一页面上。我们将从几个表开始:

CREATE TABLE dbo.table1(someText varchar(20)); -- uses default collation: SQL_Latin1_General_CP1_CI_AS
CREATE TABLE dbo.table2(someText varchar(20) collate Latin1_General_BIN);
table1上的someTxt使用我的服务器默认排序规则( SQL_Latin1_General_CP1_AS )。 table2上的同一列使用 Latin1_General_BIN

此查询给出了您所看到的错误。

SELECT * 
FROM dbo.table1 t1
JOIN dbo.table2 t2 
  ON t1.someText = t2.someText;

错误:

  

Msg 468,Level 16,State 9,Line 23   无法在等于操作的情况下解决“Latin1_General_BIN”和“SQL_Latin1_General_CP1_CI_AS”之间的排序规则冲突。

使用COLLATE解决此错误有两种常用方法:

选项1 - 在您的查询中

SELECT * 
FROM dbo.table1 t1
JOIN dbo.table2 t2 
  ON t1.someText = t2.someText collate SQL_Latin1_General_CP1_CI_AS;

-- OR:

SELECT * 
FROM dbo.table1 t1
JOIN dbo.table2 t2 
  ON t1.someText = t2.someText collate Latin1_General_BIN;

选项2 - 更改表格定义 在这里,我将使用COLLATE更改table1上的列以匹配table2上的列。

ALTER TABLE dbo.table1
ALTER column someText varchar(20) collate Latin1_General_BIN;

现在我不必在查询中定义排序规则。

您的问题

  

我知道我可以使用COLLATE来确保两个比较值都有   相同的整理,但我想知道这是否有任何一种   对这些表格的永久影响,如永久整理更改,   鉴于他们需要它们用于其他应用程序。

如果你选择选项1,那么答案是;以这种方式使用COLLATE不会以任何方式改变表格。如果您选择选项2,则 - 列上的排序规则将永久更改。影响可能很大,或者根本没有影响(我对您的应用程序知之甚少)。