sql-server - studio - sql server是什么




在等于操作中无法解决“SQL_Latin1_General_CP1_CI_AS”与“Latin1_General_CI_AS”之间的排序规则冲突 (13)

我有以下代码

SELECT tA.FieldName As [Field Name],
       COALESCE(tO_A.[desc], tO_B.[desc], tO_C.Name, tA.OldVAlue) AS [Old Value],
       COALESCE(tN_A.[desc], tN_B.[desc], tN_C.Name, tA.NewValue) AS [New Value],
       U.UserName AS [User Name],
       CONVERT(varchar, tA.ChangeDate) AS [Change Date] 
  FROM D tA
       JOIN 
       [DRTS].[dbo].[User] U 
         ON tA.UserID = U.UserID
       LEFT JOIN 
       A tO_A 
         on tA.FieldName = 'AID' 
        AND tA.oldValue = CONVERT(VARCHAR, tO_A.ID)
       LEFT JOIN 
       A tN_A 
         on tA.FieldName = 'AID' 
        AND tA.newValue = CONVERT(VARCHAR, tN_A.ID)
       LEFT JOIN 
       B tO_B 
         on tA.FieldName = 'BID' 
        AND tA.oldValue = CONVERT(VARCHAR, tO_B.ID)
       LEFT JOIN 
       B tN_B 
         on tA.FieldName = 'BID' 
        AND tA.newValue = CONVERT(VARCHAR, tN_B.ID)
       LEFT JOIN 
       C tO_C 
         on tA.FieldName = 'CID' 
        AND tA.oldValue = tO_C.Name
       LEFT JOIN 
       C tN_C 
         on tA.FieldName = 'CID' 
        AND tA.newValue = tN_C.Name
 WHERE U.Fullname = @SearchTerm
ORDER BY tA.ChangeDate

在运行代码时,在为表C添加两个连接后,我得到了粘贴在标题中的错误。我认为这可能与我使用SQL Server 2008的事实有关,并已将此db的副本还原到我的机器是2005年。


@Valkyrie真棒回答。 当我在这里提到一个案例,当在子查询中执行相同的存储过程时,我想知道在这种情况下你的答案是否有效,并且它确实很棒。

...WHERE fieldname COLLATE DATABASE_DEFAULT in ( select distinct otherfieldname COLLATE DATABASE_DEFAULT from ... where ... )


ALTER DATABASE test2 - 将您的数据库名称放在这里COLLATE Latin1_General_CS_AS - 替换为您需要的任何归类


在查询中使用collate子句:

LEFT JOIN C tO_C on tA.FieldName = 'CID' AND tA.oldValue COLLATE Latin1_General_CI_AS = tO_C.Name  

我可能没有完全正确的语法(检查BOL),但是您可以通过这种方式更改查询的即时排序规则 - 您可能需要为每个联接添加子句。

编辑:我意识到这是不完全正确的 - collat​​e子句在需要更改的字段之后 - 在此示例中,我更改了tA.oldValue字段上的排序tA.oldValue


如果您有2个不同的数据库,并且特别是来自2个不同服务器的2个不同数据库,这很容易发生 最好的选择是将其更改为一个通用的集合并进行连接或比较。

select 
   *
from sd
inner join pd on sd.SCaseflowID collate  Latin1_General_CS_AS = pd.PDebt_code collate  Latin1_General_CS_AS

对于那些有导致此问题的数据库的CREATE DATABASE脚本(就像我的情况那样),可以使用以下CREATE脚本来匹配排序规则:

-- Create Case Sensitive Database
CREATE DATABASE CaseSensitiveDatabase
COLLATE SQL_Latin1_General_CP1_CS_AS -- or any collation you require
GO
USE CaseSensitiveDatabase
GO
SELECT *
FROM sys.types
GO
--rest of your script here

要么

-- Create Case In-Sensitive Database
CREATE DATABASE CaseInSensitiveDatabase
COLLATE SQL_Latin1_General_CP1_CI_AS -- or any collation you require
GO
USE CaseInSensitiveDatabase
GO
SELECT *
FROM sys.types
GO
--rest of your script here

这将所需的整理应用于所有表格,这正是我所需要的。 对于服务器上的所有数据库,尝试保持排序规则相同是理想的选择。 希望这可以帮助。

有关以下链接的更多信息: SQL SERVER - 在服务器上使用不同的排序规则创建数据库


您可以通过4个简单的步骤轻松完成此操作

  1. 备份您的数据库,只是incase
  2. 更改数据库排序规则:右键单击数据库,选择属性,转到选项并将排序规则更改为所需的排序规则。
  3. 生成一个脚本以删除并重新创建所有数据库对象:右键单击数据库,选择任务,选择生成脚本...(确保在向导的高级选项中选择“删除并创建”,同时选择“架构和数据”)
  4. 运行上面生成的脚本

感谢marc_s的回答,我解决了我原来的问题 - 启发了更进一步,并发布一种方法来转换整个表 - tsql脚本来生成alter column语句:

DECLARE @tableName VARCHAR(MAX)
SET @tableName = 'affiliate'
--EXEC sp_columns @tableName
SELECT  'Alter table ' + @tableName + ' alter column ' + col.name
        + CASE ( col.user_type_id )
            WHEN 231
            THEN ' nvarchar(' + CAST(col.max_length / 2 AS VARCHAR) + ') '
          END + 'collate Latin1_General_CI_AS ' + CASE ( col.is_nullable )
                                                    WHEN 0 THEN ' not null'
                                                    WHEN 1 THEN ' null'
                                                  END
FROM    sys.columns col
WHERE   object_id = OBJECT_ID(@tableName)

获取:ALTER TABLE加盟商ALTER COLUMN myTable NVARCHAR(4000)COLLATE Latin1_General_CI_AS NOT NULL

我会承认对col.max_length / 2的需求感到困惑 -


我做了以下几点:

...WHERE 
    fieldname COLLATE DATABASE_DEFAULT = otherfieldname COLLATE DATABASE_DEFAULT

每次工作。 :)


我有一个类似的错误(无法解决INTERSECT操作中“SQL_Latin1_General_CP1_CI_AS”和“SQL_Latin1_General_CP1250_CI_AS”之间的排序规则冲突),当我使用旧的jdbc驱动程序。

我通过从Microsoft或开源项目jTDS下载新驱动程序来解决此jTDS


根本原因是您从架构中获取的sql server数据库的排序规则与本地安装不同。 如果您不想担心排序问题,请使用与SQL Server 2008数据库相同的排序规则在本地重新安装SQL Server。


确定它引发此错误的字段并将其添加到它们后面:COLLATE DATABASE_DEFAULT

Code域中有两个表格:

...
and table1.Code = table2.Code
...

将您的查询更新为:

...
and table1.Code COLLATE DATABASE_DEFAULT = table2.Code COLLATE DATABASE_DEFAULT
...

这里是我们所做的,在我们的情况下,我们需要使用日期限制按需执行临时查询,并且查询在表中定义。

我们的新查询需要匹配不同数据库之间的数据并包含来自两者的数据。

从iSeries / AS400系统导入数据的数据库和我们的报告数据库之间的COLLATION似乎有所不同 - 这可能是由于特定的数据类型(例如名称上的希腊语重音等)。

所以我们使用了下面的连接子句:

...LEFT Outer join ImportDB..C4CTP C4 on C4.C4CTP COLLATE Latin1_General_CS_AS=CUS_Type COLLATE Latin1_General_CS_AS

INSERT INTO eSSLSmartOfficeSource2.[dbo].DeviceLogs  (DeviceId,UserId,LogDate,UpdateFlag) 
SELECT DL1.DeviceId ,DL1.UserId COLLATE DATABASE_DEFAULT,DL1.LogDate 
,0 FROM eSSLSmartOffice.[dbo].DeviceLogs DL1 
WHERE  NOT EXISTS 
(SELECT DL2.DeviceId ,DL2.UserId COLLATE DATABASE_DEFAULT
,DL2.LogDate ,DL2.UpdateFlag 
FROM eSSLSmartOfficeSource2.[dbo].DeviceLogs DL2    
WHERE  DL1.DeviceId =DL2.DeviceId
 and DL1.UserId collate  Latin1_General_CS_AS=DL2.UserId collate  Latin1_General_CS_AS
  and DL1.LogDate =DL2.LogDate )