Der Kollationskonflikt zwischen "SQL_Latin1_General_CP1_CI_AS" und "Latin1_General_CI_AS" kann nicht gleichgeschlossen werden

Ich habe den folgenden Code

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 

Beim Ausführen des Codes bekomme ich den Fehler in den Titel eingefügt, nachdem ich die beiden Joins für Tabelle C. Ich denke, das kann etwas mit der Tatsache zu tun, dass ich mit SQL 2008 und habe eine Kopie von diesem db auf meine wiederhergestellt Maschine, die 2005 ist. Bitte helfen!

Sie haben eine Fehlanpassung von zwei verschiedenen Kollationen in Ihrem Tisch. Sie können überprüfen, welche sortingen jede Spalte in Ihrer Tabelle hat, indem Sie diese Abfrage verwenden:

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

sortingen werden benötigt und bei der Bestellung und beim Vergleich von characterketten verwendet. Es ist in der Regel eine gute Idee, eine einzige, einzigartige Kollation in Ihrer database verwendet haben – nicht verwenden verschiedene Kollatierungen in einer einzigen Tabelle oder database – Sie sind nur um Ärger ….

Sobald Sie sich für eine einzige sorting entschieden haben, können Sie die Tabellen / Spalten ändern, die noch nicht mit diesem Befehl übereinstimmen:

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

Marc

UPDATE: Um die Volltextindizes in Ihrer database zu finden, verwenden Sie diese Abfrage hier:

 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 INNER JOIN 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 

Sie können dann den Volltext-Index mit:

 DROP FULLTEXT INDEX ON (tablename) 

Ich mache folgendes:

 ...WHERE fieldname COLLATE DATABASE_DEFAULT = otherfieldname COLLATE DATABASE_DEFAULT 

Arbeitet jedes Mal. 🙂

Verwenden Sie die collate in Ihrer Abfrage:

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

Ich kann nicht die Syntax genau richtig haben (check BOL), aber du kannst dies tun, um die Kollation on-the-fly für die Abfrage zu ändern – Sie müssen möglicherweise die Klausel für jede Verknüpfung hinzufügen.

edit: Ich habe erkannt, dass das nicht ganz richtig war – die Sortierklausel geht nach dem Feld, das du ändern musst – in diesem Beispiel habe ich die sorting auf dem Feld tA.oldValue geändert.

Identifizieren Sie die Felder, für die sie diesen Fehler austriggers und fügen Sie sie hinzu: COLLATE DATABASE_DEFAULT

Es gibt zwei Tabellen, die im Code-Feld verbunden sind:

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

Aktualisieren Sie Ihre Anfrage an:

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

@Valkyrie ehrfürchtige Antwort. Ich dachte, ich stelle hier einen Fall ein, wenn ich das gleiche mit einer Unterabfrage im Inneren einer gespeicherten Prozedur ausführte, da ich mich fragte, ob Ihre Antwort in diesem Fall funktioniert, und es hat toll gemacht.

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

Dies kann leicht passieren, wenn Sie 2 verschiedene databaseen und speziell 2 verschiedene databaseen von 2 verschiedenen servern haben. Beste Option ist, es zu einer gemeinsamen Sammlung zu ändern und den Join oder Vergleich zu machen.

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

Die Ursache ist, dass die SQL server-database, die Sie das Schema genommen hat, eine sorting hat, die sich von Ihrer lokalen Installation unterscheidet. Wenn Sie sich keine Sorgen um die sorting machen möchten, installieren Sie SQL server lokal mit der gleichen sorting wie die SQL server 2008-database.

Ich hatte so etwas schon früher, und was wir fanden, war, dass die Zusammenstellung zwischen 2 Tischen unterschiedlich war.

Prüfen Sie, ob diese gleich sind.

Für diejenigen, die ein CREATE DATABASE-Skript (wie war mein Fall) für die database, die dieses Problem verursacht wird, können Sie das folgende CREATE-Skript verwenden, um die sorting anzupassen:

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

oder

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

Dies gilt für die gewünschten Kollation auf alle Tische, was genau das war, was ich brauchte. Es ist ideal, um zu versuchen, die sorting für alle databaseen auf einem server gleich zu halten. Hoffe das hilft.

Weitere Informationen zum folgenden Link: SQL SERVER – Erstellen von database mit unterschiedlicher sorting auf server

Dank der Antwort von marc_s habe ich mein ursprüngliches Problem getriggers – inspiriert, um einen Schritt weiter zu gehen und einen Ansatz zu geben, um eine ganze Tabelle zu einer time zu verwandeln – tsql Skript, um die Änderungen der Spalte zu generieren:

 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) 

bekommt: ALTER TABLE Affiliate ALTER COLUMN myTable NVARCHAR (4000) COLLATE Latin1_General_CI_AS NOT NULL

Ich werde zugeben, dass es von der Notwendigkeit verwirrt ist, col.max_length / 2

Ich habe den Inhalt von dieser Seite verwendet , um das folgende Skript zu erstellen, das die sorting aller Spalten in allen Tabellen ändert:

 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 - Fügen Sie hier die Parameter für die gespeicherte Prozedur hinzu 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 

Ich hatte einen ähnlichen Fehler (kann den Zusammenlagerungskonflikt zwischen "SQL_Latin1_General_CP1_CI_AS" und "SQL_Latin1_General_CP1250_CI_AS" in der INTERSECT-Operation nicht beheben), als ich den alten jdbc-Treiber verwendete.

Ich habe das getriggers, indem ich einen neuen Treiber von Microsoft oder Open-Source-Projekt jTDS herunterlade .

Hier ist, was wir getan haben, in unserer Situation brauchen wir eine Ad-hoc-Abfrage, die mit einer datesbeschränkung auf Anfrage ausgeführt wird, und die Abfrage ist in einer Tabelle definiert.

Unsere neue Abfrage muss data zwischen verschiedenen databaseen anpassen und data von beiden enthalten.

Es scheint, dass die COLLATION zwischen dem db, der data aus dem iSeries / AS400-System importiert, und unsere Berichtsdatenbank unterschiedlich ist – dies könnte auf die spezifischen datatypen (wie griechische Akzente auf Namen und so weiter) zurückzuführen sein.

Also haben wir die folgende Join-Klausel verwendet:

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

ALTER DATABASE test2 – Setzen Sie hier Ihren databasenamen ein COLLATE Latin1_General_CS_AS – Ersetzen Sie durch die sorting, die Sie benötigen

Sie können dies einfach mit 4 einfachen Schritten machen

  1. Sicherung Ihrer database, nur incase
  2. Ändern Sie die databasekollation: Klicken Sie mit der rechten Maustaste auf database, wählen Sie properties aus, gehen Sie zu den Optionen und ändern Sie die sorting auf die erforderliche sorting.
  3. Erstellen Sie ein Skript, um alle databaseobjekte zu löschen und neu zu erstellen: Klicken Sie mit der rechten Maustaste auf Ihre database, wählen Sie Aufgaben aus, wählen Sie Skript generieren … (stellen Sie sicher, dass Sie in den erweiterten Optionen des Assistenten Drop & Create auswählen, auch Schema und data auswählen)
  4. Führen Sie das oben beschriebene Skript aus

Überprüfen Sie den Grad der sorting, der nicht übereinstimmt (server, database, Tabelle, Spalte, character).

Wenn es der server ist, haben mir diese Schritte geholfen:

  1. Stoppen Sie den server
  2. Finden Sie Ihr Werkzeug sqlservr.exe
  3. Führen Sie diesen Befehl aus:

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

  4. Starten Sie Ihren SQL server:

    net start name_of_instance

  5. Überprüfen Sie die sorting Ihres servers erneut.

Hier ist mehr Info:

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