Gibt es eine einfachere Möglichkeit, nicht übereinstimmende SQL Server- / Datenbankkollatierungen zu beheben, als jede Spalte zu ändern?

8

HAFTUNGSAUSSCHLUSS: Ich weiß, dass diese Frage schon hundert Mal gestellt wurde, aber ich wollte nur überprüfen, ob es keine einfachere Lösung gab, die ich möglicherweise verpasst hätte, bevor ich fortfuhr und viel Code dazu schrieb / beschaffte.

Unsere Software verwendet eine Datenbank, die ursprünglich für SQL Server 7 entwickelt wurde. Daher geben alle Skripts, die sie erstellen, keine explizite Sortierung für Zeichenspalten an. Wenn stattdessen eine Datenbank in SQL Server 2000 oder höher erstellt / wiederhergestellt wird, erbt jede Spalte die Datenbankkollatierung (was zufällig der Fall ist, SQL_Latin1_General_CP1_CI_ASda dies der SQL Server 7-Standard war).

Theoretisch wäre dies nicht allzu wichtig, da unsere Datenbank, wenn sie auf dem Server eines Kunden von Grund auf neu erstellt wird, die Server-Sortierung des Kunden erbt (was normalerweise die Standardeinstellung für die moderne Installation ist Latin1_General_CP1_CI_AS) und alles einfach funktioniert. Dieses Szenario bricht jedoch zusammen, wenn sie uns eine Datenbanksicherung senden oder wenn wir ihnen eine Datenbanksicherung senden, und entweder wir oder sie erhalten den gefürchteten Fehler bei der Nichtübereinstimmung der Kollatierung, wenn der Code versucht, auf temporäre Tabellen usw. zuzugreifen.

Wir haben versucht, Kunden zu schulen, ihre SQL Server-Instanzen zu installieren oder neu zu erstellen, um unsere bevorzugte Sortierung zu verwenden, aber das passiert natürlich nicht immer und ist nicht immer möglich.

Lösungen, bei denen eine neue Datenbank erstellt und die Daten kopiert werden, sind für uns nicht wirklich praktisch. Wir benötigen einen "Zauberstab", mit dem wir einer Live-Datenbank winken können, um alle vorhandenen Spalten zu korrigieren, ohne die Daten zu stören. Ich denke darüber nach, ein Dienstprogramm zu schreiben, um dies zu tun, aber hat jemand einfachere Vorschläge, da dies eine ziemlich große Aufgabe sein wird?

Christian Hayter
quelle

Antworten:

6

Eine Möglichkeit besteht darin, Ihren Code gegen Kollatierungsfehlanpassungen zu "prüfen".

Sie können die spezielle Kollatierung "DATABASE_DEFAULT" verwenden, um zu erzwingen, ohne die tatsächliche Kollatierung zu kennen. Sie verwenden es für Spalten vom Typ char in temporären Tabellen, Tabellenvariablen und Systemtabellen, die Sie verwenden müssen.

Beispiel:

CREATE TABLE #Currency (CCY CHAR(3))
GO
INSERT #Currency VALUES ('GBP')
INSERT #Currency VALUES ('CHF')
INSERT #Currency VALUES ('EUR')
GO
SELECT Something
FROM myTable M JOIN #Currency C ON M.CCY = C.CCY --error!
GO
-- in join too
SELECT Something
FROM myTable M JOIN #Currency C ON M.CCY = C.CCY COLLATE DATABASE_DEFAULT --no error
GO
DROP TABLE #Currency
GO


CREATE TABLE  #Currency (CCY CHAR(3) COLLATE DATABASE_DEFAULT)
GO
INSERT #Currency VALUES ('GBP')
INSERT #Currency VALUES ('CHF')
INSERT #Currency VALUES ('EUR')
GO
SELECT Something
FROM myTable M JOIN #Currency C ON M.CCY = C.CCY --no error!
GO

DROP TABLE #Currency
GO

Dies bedeutet auch, dass wenn Ihre Clients ihre Datenbank auf eine neue Whizzy-SQL Server-Box mit einer weiteren anderen Sortierung migrieren, dies auch funktioniert ...

gbn
quelle
2

Kurze Antwort ist, dass es keinen einfachen Weg gibt. Ich hatte das gleiche Problem in der Vergangenheit.

Was ich sagen würde, sind zwei Dinge: Zuerst, wenn Ihr Kunde Ihnen eine Datenbank mit einer unerwarteten Sortierung sendet, installieren Sie eine neue SQL-Instanz mit einer Standardkollatierung, die ihrer Datenbank entspricht, und arbeiten Sie damit.

Die zweite Möglichkeit besteht darin, sicherzustellen, dass Ihre App mit anderen Kollatierungen als den Standardeinstellungen funktioniert (da sich diese in Zukunft ändern könnten) und ordnungsgemäß funktioniert, solange die Kollatierung auf dem SQL Server und der Datenbank übereinstimmt. Dann ist es ziemlich einfach, den Kunden SQL Server mit einer Sortierung installieren zu lassen, die seiner Datenbank entspricht und dann funktioniert.

Oder schreiben Sie ein Dienstprogramm, das alle Tabellen usw. in Ihrer Datenbank wie gesagt aktualisiert, aber das könnte mehr Arbeit bedeuten, als Sie möchten.

SpaceManSpiff
quelle
2

Wenn alle Spalten in der Datenbank dieselbe Sortierung haben, verursacht dies nur Probleme bei datenbankübergreifenden Abfragen (oder Ihre Anwendung ist sortierreihenfolgenabhängig).

Der entscheidende Punkt tritt auf, wenn Sie feststellen, dass das Verknüpfen mit temporären Tabellen datenbankübergreifend ist, da sie sich in Tempdb befinden. Das ist jedoch einfach zu sortieren - stellen Sie nur sicher, dass alle Textspalten in temporären Tabellen explizit mit der COLLATE database_defaultDirektive erstellt werden. Dies bedeutet, dass die Spalte mit der Standardkollatierung der aktuellen Datenbank anstelle der Standardauflistung von tempdb erstellt wird (die mit der Standardauflistung des Servers identisch ist).

David Spillett
quelle