无法解决等于操作中“SQL_Latin1_General_CP1_CI_AS”与“Latin1_General_CI_AS”之间的sorting规则冲突
我有以下代码
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 2008的事实有关,并且已经将这个数据库的副本恢复到了我的这是2005年的机器,请帮助!
你的表中有两个不同的sorting规则不匹配。 你可以通过使用这个查询来检查你的表中每个列的sorting规则:
SELECT col.name, col.collation_name FROM sys.columns col WHERE object_id = OBJECT_ID('YourTableName')
sorting和比较string时需要使用sorting规则。 在整个数据库中使用唯一的唯一整理通常是一个好主意 – 不要在单个表或数据库中使用不同的sorting规则 – 只是要求麻烦….
一旦您确定了一个sorting规则,您可以使用以下命令更改那些不匹配的表/列:
ALTER TABLE YourTableName ALTER COLUMN OffendingColumn VARCHAR(100) COLLATE Latin1_General_CI_AS NOT NULL
渣子
更新:在数据库中find全文索引,在这里使用这个查询:
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
子句:
LEFT JOIN C tO_C on tA.FieldName = 'CID' AND tA.oldValue COLLATE Latin1_General_CI_AS = tO_C.Name
我可能没有完全正确的语法(检查BOL),但是可以这样做来为查询即时更改sorting规则 – 您可能需要为每个连接添加子句。
编辑:我意识到这是不正确的 – collate子句后,你需要改变的领域 – 在这个例子中,我改变了tA.oldValue
领域的sortingtA.oldValue
。
确定它引发这个错误的领域,并添加以下内容:COLLATE DATABASE_DEFAULT
Code字段上有两个表格:
... and table1.Code = table2.Code ...
将您的查询更新为:
... and table1.Code COLLATE DATABASE_DEFAULT = table2.Code COLLATE DATABASE_DEFAULT ...
@Valkyrie真棒回答。 以为我在这里把一个情况下,当一个子查询执行相同的内存存储过程,因为我想知道如果你的答案在这种情况下工作,它确实很棒。
...WHERE fieldname COLLATE DATABASE_DEFAULT in ( select distinct otherfieldname COLLATE DATABASE_DEFAULT from ... where ... )
当您有两个不同的数据库,特别是来自两个不同服务器的两个不同的数据库时,这很容易发生 最好的select是将其更改为一个通用的集合,并进行join或比较。
select * from sd inner join pd on sd.SCaseflowID collate Latin1_General_CS_AS = pd.PDebt_code collate Latin1_General_CS_AS
根本原因是您从架构中获取的sql server数据库的sorting规则与本地安装不同。 如果您不想担心sorting问题,请使用与SQL Server 2008数据库相同的sorting规则在本地重新安装SQL Server。
之前我曾经有过这样的事情,而我们发现两张表格之间的整理是不同的。
检查这些是一样的。
对于那些有导致此问题的数据库的CREATE DATABASE脚本(就像我的情况),您可以使用以下CREATE脚本来匹配sorting规则:
-- 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
这将所需的sorting应用于所有表,这正是我所需要的。 对于服务器上的所有数据库,尝试保持sorting规则相同是理想的select。 希望这可以帮助。
有关以下链接的更多信息: SQL SERVER – 在服务器上使用不同的sorting规则创build数据库
感谢marc_s的回答,我解决了我原来的问题 – 启发了更进一步,并发表一种方法来转换整个表 – tsql脚本生成更改列语句:
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的需要 –
我已经使用了来自这个网站的内容来创build下面的脚本来改变所有表中所有列的sorting规则:
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
我有一个类似的错误(无法解决INTERSECT操作中的“SQL_Latin1_General_CP1_CI_AS”和“SQL_Latin1_General_CP1250_CI_AS”之间的sorting规则冲突),当我使用旧的jdbc驱动程序。
我通过从Microsoft或开源项目jTDS下载新驱动程序来解决此问题 。
这里是我们所做的,在我们的情况下,我们需要使用date限制按需执行即席查询,查询在表中定义。
我们的新查询需要匹配不同数据库之间的数据,并包含来自两者的数据。
从iSeries / AS400系统导入数据的数据库和我们的报告数据库之间的COLLATION似乎不同,这可能是由于特定的数据types(如希腊语名称等等)。
所以我们使用了下面的连接子句:
...LEFT Outer join ImportDB..C4CTP C4 on C4.C4CTP COLLATE Latin1_General_CS_AS=CUS_Type COLLATE Latin1_General_CS_AS
ALTER DATABASE test2 – 把你的数据库名称放在这里COLLATE Latin1_General_CS_AS – 用你需要的任何整理代替
你可以轻松地使用4个简单的步骤来做到这一点
- 备份您的数据库,只是incase
- 更改数据库sorting规则:右键单击数据库,select属性,转到选项并将sorting规则更改为所需的sorting规则。
- 生成一个脚本来删除和重新创build所有的数据库对象:右键单击您的数据库,select任务,select生成脚本…(请确保select向导的高级选项上的删除和创build,也select架构和数据)
- 运行上面生成的脚本
检查不匹配的归类级别(服务器,数据库,表,列,字符)。
如果是服务器,这些步骤帮助我一次:
- 停止服务器
- find你的sqlservr.exe工具
-
运行这个命令:
sqlservr -m -T4022 -T3659 -s"name_of_insance" -q "name_of_collation"
-
启动你的sql服务器:
net start name_of_instance
-
再次检查您的服务器的sorting规则。
这里是更多的信息:
https://www.mssqltips.com/sqlservertip/3519/changing-sql-server-collation-after-installation/