我有以下代码
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年。
答案 0 :(得分:740)
我执行以下操作:
...WHERE
fieldname COLLATE DATABASE_DEFAULT = otherfieldname COLLATE DATABASE_DEFAULT
每次都有效。 :)
答案 1 :(得分:279)
您的表格中有两种不同的排序规则不匹配。您可以使用此查询检查表中每列的排序规则:
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)
答案 2 :(得分:67)
在查询中使用collate
子句:
LEFT JOIN C tO_C on tA.FieldName = 'CID' AND tA.oldValue COLLATE Latin1_General_CI_AS = tO_C.Name
我可能没有完全正确的语法(检查BOL),但是你可以这样做来为查询动态更改排序规则 - 你可能需要为每个连接添加子句。
编辑:我意识到这不太对 - collate子句在你需要更改的字段之后 - 在这个例子中我更改了tA.oldValue
字段的排序规则。
答案 3 :(得分:25)
确定引发此错误的字段并向其添加以下内容: COLLATE DATABASE_DEFAULT
代码字段中有两个表连接:
...
and table1.Code = table2.Code
...
将您的查询更新为:
...
and table1.Code COLLATE DATABASE_DEFAULT = table2.Code COLLATE DATABASE_DEFAULT
...
答案 4 :(得分:11)
@Valkyrie很棒的答案。以为我在这里提出了一个案例,当一个子查询执行相同的内存存储过程时,因为我想知道你的答案在这种情况下是否有效,并且确实很棒。
...WHERE fieldname COLLATE DATABASE_DEFAULT in (
SELECT DISTINCT otherfieldname COLLATE DATABASE_DEFAULT
FROM ...
WHERE ...
)
答案 5 :(得分:10)
在where条件中添加collate SQL_Latin1_General_CP1_CI_AS
这适合我。
WHERE U.Fullname = @SearchTerm collate SQL_Latin1_General_CP1_CI_AS
答案 6 :(得分:9)
当您拥有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
答案 7 :(得分:6)
根本原因是您从中获取架构的SQL Server数据库具有与本地安装不同的归类。如果您不想担心排序规则,请使用与SQL Server 2008数据库相同的排序规则在本地重新安装SQL Server。
答案 8 :(得分:5)
错误(无法解决....之间的排序规则冲突)通常在比较来自多个数据库的数据时发生。
由于您现在无法更改数据库的排序规则,请使用COLLATE DATABASE_DEFAULT。
----------
AND db1.tbl1.fiel1 COLLATE DATABASE_DEFAULT =db2.tbl2.field2 COLLATE DATABASE_DEFAULT
答案 9 :(得分:4)
之前我有类似的东西,我们发现两张桌子之间的整理是不同的。
检查这些是否相同。
答案 10 :(得分:3)
感谢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 Affiliate ALTER COLUMN myTable NVARCHAR(4000)COLLATE Latin1_General_CI_AS NOT NULL
我承认对 col.max_length / 2 的需要感到困惑 -
答案 11 :(得分:2)
我已使用此site中的内容创建以下脚本,该脚本会更改所有表中所有列的排序规则:
(name, df)
答案 12 :(得分:2)
在@JustSteve的答案中添加了代码以处理varchar和varchar(MAX)列:
DECLARE @tableName VARCHAR(MAX)
SET @tableName = 'first_notes'
--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) + ') '
WHEN 167
THEN ' varchar(' + CASE col.max_length
WHEN -1
THEN 'MAX'
ELSE
CAST(col.max_length AS VARCHAR)
end
+ ') '
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)
答案 13 :(得分:2)
如果在整个数据库中出现这种情况,那么最好像这样更改数据库归类:
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
答案 14 :(得分:2)
检查不匹配的排序规则级别(服务器,数据库,表,列,字符)。
如果是服务器,这些步骤对我有一次帮助:
运行此命令:
sqlservr -m -T4022 -T3659 -s"name_of_insance"
-q "name_of_collation"
启动sql server:
net start name_of_instance
再次检查服务器的排序规则。
以下是更多信息:
https://www.mssqltips.com/sqlservertip/3519/changing-sql-server-collation-after-installation/
答案 15 :(得分:2)
如果对于导致此问题的数据库有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 – Creating Database with Different Collation on Server
答案 16 :(得分:1)
您可以通过使用4个简单步骤轻松完成此操作
答案 17 :(得分:1)
ALTER DATABASE test2 - 将您的数据库名称放在此处 COLLATE Latin1_General_CS_AS - 替换为您需要的任何排序规则
答案 18 :(得分:1)
这是我们所做的,在我们的情况下,我们需要根据需要使用日期限制执行即席查询,并在表中定义查询。
我们的新查询需要匹配不同数据库之间的数据,并包含来自这两个数据库的数据。
似乎从iSeries / AS400系统导入数据的数据库与我们的报告数据库之间的COLLATION不同 - 这可能是因为特定的数据类型(例如名称上的希腊语重音等)。 / p>
所以我们使用了下面的join子句:
...LEFT Outer join ImportDB..C4CTP C4 on C4.C4CTP COLLATE Latin1_General_CS_AS=CUS_Type COLLATE Latin1_General_CS_AS
答案 19 :(得分:1)
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 )
答案 20 :(得分:1)
我遇到了类似的错误(当我使用旧的jdbc驱动程序时,无法解决INTERSECT操作中“SQL_Latin1_General_CP1_CI_AS”和“SQL_Latin1_General_CP1250_CI_AS”之间的排序规则冲突)。
答案 21 :(得分:1)
答案 22 :(得分:0)
您的数据库中可能没有任何排序规则问题,但是如果您从排序规则与原始排序规则不同的服务器上的备份中还原了数据库副本,并且代码正在创建临时表,则这些临时表将从服务器继承排序规则,将与您的数据库发生冲突。
答案 23 :(得分:0)
我有类似的要求;在这里为有类似情况的任何人记录我的方法...
使用SQL Server架构比较(来自SQL Server Data Tools / Visual Studio)将源(全新安装)与目标(具有无效排序规则的数据库)进行比较。
就我而言,我直接比较了两个数据库;尽管您可以通过一个项目来工作,以允许您手动调整之间的片段...
Object Types
下,仅选择您感兴趣的那些类型(对我来说,只有Views
和Tables
)General
下,选择:
DELETE
文件夹并选择EXCLUDE
一次取消所有操作。CREATE
对象也要排除(这里,由于它们不存在于目标中,因此它们在那里的排序规则不会错误;是否应存在是另一个主题的问题)。Update
推送更改这仍然需要一些人工(例如,检查您是否正在影响排序规则)-但它会为您处理依赖项。
此外,您可以保留有效模式的数据库项目,以便在要更新的数据库数量超过1个的情况下,可以为数据库使用通用模板,假设所有目标数据库都应使用相同的模式。
如果您希望大规模修改数据库项目中的设置,也可以在数据库项目的文件上使用查找/替换(例如,这样您可以使用架构比较从无效数据库中创建项目,修改项目文件,然后切换源代码模式中的/ target进行比较,以将您的更改推送回数据库)。