すべての列を変更するよりもSQL Serverとデータベースの照合順序の不一致を解決する簡単な方法はありますか?


8

免責事項:私はこの質問が以前に100回尋ねられたことを知っていますが、私が先に進み、それを行うために多くのコードを記述/ソースする前に見逃していた簡単な解決策がないかどうかを確認したかっただけです。

私たちのソフトウェアは、元々SQL Server 7用に設計されたデータベースを使用しているため、それを作成するすべてのスクリプトは、文字列に明示的な照合を指定していません。代わりに、データベースがSQL Server 2000以降に作成または復元されると、すべての列がデータベース照合を継承します(これSQL_Latin1_General_CP1_CI_ASは、SQL Server 7のデフォルトだったためです)。

理論的には、これはそれほど重要ではありません。私たちのデータベースが顧客のサーバーでゼロから作成された場合、それは顧客のサーバーの照合順序(通常は最新のインストールのデフォルトLatin1_General_CP1_CI_AS)を継承し、すべてが機能するためです。ただし、このシナリオは、データベースのバックアップを送信するか、データベースのバックアップを送信すると失敗し、コードが一時テーブルなどにアクセスしようとすると、恐ろしい照合不一致エラーが発生します。

SQL Serverインスタンスをインストールまたは再構築して、推奨される照合順序を使用するようにお客様に説明しましたが、もちろん、常にそうであるとは限らず、常に可能であるとは限りません。

新しいデータベースの作成とデータのコピーを含むソリューションは実際には実用的ではありません。ライブデータベースで手を振って、データを乱すことなくすべての列を修正できる「魔法の杖」が必要です。私はこれを行うユーティリティを書くことを考えていますが、それはかなり大きな仕事になるので、誰かより簡単な提案はありますか?

回答:


6

1つのオプションは、照合の不一致に対してコードを「証明」することです。

特別な照合「DATABASE_DEFAULT」を使用して、実際の照合が何であるかを知らずに強制することができます。使用する必要がある一時テーブル、テーブル変数、システムテーブルのchar型の列で使用します。

例:

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

これはまた、クライアントがDBを新しい別のSQL Serverボックスに移行し、さらに別の照合を使用する場合にも機能することを意味します...


2

簡単に言えば、簡単な方法はありません。過去にも同じ問題がありました。

私が言うことは2つあります。最初に、顧客が予期しない照合を使用してデータベースを送信したときに、DBに一致するデフォルトの照合を使用して新しいSQLインスタンスをインストールし、その中で動作します。

2つ目は、アプリが他の照合順序(デフォルトでは変更される可能性があるため)で動作し、SQLサーバーとDBの照合順序が一致する限り正しく動作することを確認することです。次に、顧客に自分のDBと一致する照合を使用してSQLサーバーをインストールさせることは、かなり簡単で、その後機能します。

または、あなたが言ったようにデータベースのすべてのテーブルなどを更新するユーティリティを書いてください、しかしそれはあなたが望むより多くの仕事かもしれません。


2

データベース内のすべての列が同じ照合順序である場合、データベース間クエリを実行するときに問題が発生するだけです(またはアプリケーションがソート順に依存します)。

一時的なテーブルへの結合は、tempdbのようにクロスデータベースであることがわかったときに、問題が発生します。ただし、並べ替えは簡単COLLATE database_defaultです。一時テーブルのテキスト列がディレクティブで明示的に作成されることを確認してください。これは、列がtempdbの既定のコレクション(サーバーの既定と同じ)ではなく、現在のデータベースの既定の照合で作成されることを意味します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.