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




sql server是什么 (16)

我有以下代码

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年。


您的表格中有两个不同的排序规则不匹配。 您可以使用此查询来检查表格中每列的排序规则:

SELECT
    col.name, col.collation_name
FROM 
    sys.columns col
WHERE
    object_id = OBJECT_ID('YourTableName')

排序和比较字符串时需要使用排序规则。 在整个数据库中使用单一的唯一排序规则通常是一个好主意 - 不要在单个表或数据库中使用不同的排序规则 - 只是要求麻烦....

一旦您确定了一个排序规则,您可以使用以下命令更改那些不匹配的表/列:

ALTER TABLE YourTableName
  ALTER COLUMN OffendingColumn
    VARCHAR(100) COLLATE Latin1_General_CI_AS NOT NULL

渣子

更新:要在数据库中找到全文索引,请在此处使用此查询:

SELECT
    fti.object_Id,
    OBJECT_NAME(fti.object_id) 'Fulltext index',
    fti.is_enabled,
    i.name 'Index name',
    OBJECT_NAME(i.object_id) 'Table name'
FROM 
    sys.fulltext_indexes fti
INNER JOIN 
    sys.indexes i ON fti.unique_index_id = i.index_id

然后,您可以使用以下命令删除全文索引:

DROP FULLTEXT INDEX ON (tablename)

我做了以下几点:

...WHERE 
    fieldname COLLATE DATABASE_DEFAULT = otherfieldname COLLATE DATABASE_DEFAULT

每次工作。 :)


错误(无法解决...之间的排序规则冲突)通常在比较来自多个数据库的数据时发生。

由于您现在无法更改数据库的排序规则,因此请使用COLLATE DATABASE_DEFAULT。

----------
AND db1.tbl1.fiel1 COLLATE DATABASE_DEFAULT =db2.tbl2.field2 COLLATE DATABASE_DEFAULT 

如果这发生在整个数据库中,那么最好更改您的数据库排序规则,如下所示:

USE master;  
GO  
ALTER DATABASE MyOptionsTest  
COLLATE << INSERT COLATION REQUIRED >> ;  
GO  

--Verify the collation setting.  
SELECT name, collation_name  
FROM sys.databases  
WHERE name = N'<< INSERT DATABASE NAME >>';  
GO 

here引用


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


我已经使用这个site的内容来创建下面的脚本,它改变了所有表中所有列的排序规则:

CREATE PROCEDURE [dbo].[sz_pipeline001_collation] 
    -- Add the parameters for the stored procedure here
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;


SELECT 'ALTER TABLE [' + SYSOBJECTS.Name + '] ALTER COLUMN [' + SYSCOLUMNS.Name + '] ' +
SYSTYPES.name + 
    CASE systypes.NAME
    WHEN 'text' THEN ' '
    ELSE
    '(' + RTRIM(CASE SYSCOLUMNS.length
    WHEN -1 THEN 'MAX'
    ELSE CONVERT(CHAR,SYSCOLUMNS.length)
    END) + ') ' 
    END

    + ' ' + ' COLLATE Latin1_General_CI_AS ' + CASE ISNULLABLE WHEN 0 THEN 'NOT NULL' ELSE 'NULL' END
    FROM SYSCOLUMNS , SYSOBJECTS , SYSTYPES
    WHERE SYSCOLUMNS.ID = SYSOBJECTS.ID
    AND SYSOBJECTS.TYPE = 'U'
    AND SYSTYPES.Xtype = SYSCOLUMNS.xtype
    AND SYSCOLUMNS.COLLATION IS NOT NULL
    AND NOT ( sysobjects.NAME LIKE 'sys%' )
    AND NOT ( SYSTYPES.name LIKE 'sys%' )

END

感谢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的需求感到困惑 -


如果您有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

检查不匹配的归类级别(服务器,数据库,表,列,字符)。

如果是服务器,这些步骤只能帮助我一次:

  1. 停止服务器
  2. 找到你的sqlservr.exe工具
  3. 运行这个命令:

    sqlservr -m -T4022 -T3659 -s"name_of_insance" -q "name_of_collation"

  4. 启动你的sql服务器:

    net start name_of_instance

  5. 再次检查服务器的排序规则。

以下是更多信息:

https://www.mssqltips.com/sqlservertip/3519/changing-sql-server-collation-after-installation/


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

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


之前我有过这样的事情,而我们发现,两张表格之间的整理是不同的。

检查这些是否相同。


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

Code域中有两个表格:

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

将您的查询更新为:

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

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 )

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

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


对于那些有导致此问题的数据库的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 - 在服务器上使用不同的排序规则创建数据库


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

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

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

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

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