web-dev-qa-db-ja.com

tempdb照合とは異なるデータベース照合

クライアント(別の国の別の会社が開発したもの)からアプリケーションのソースコードとデータベースを受け取ったところ、アプリケーションがオブジェクトの照合に関連するいくつかの例外をスローしています。

等しい操作で、「SQL_Latin1_General_CP1_CI_AS」と「Latin1_General_CI_AS」の間の照合の競合を解決できません。

私の場合、これはストアドプロシージャが#tempテーブルを作成し、この#tempテーブルがアプリケーションからのテーブルとの比較に使用された場合に発生することがわかりました(アプリケーションデータベースはSQL_Latin1_General_CP1_CI_ASおよびtempdbLatin1_General_CI_AS)を使用します。

COLLATE SQL_Latin1_General_CP1_CI_ASステートメントにCREATE TABLE #TEMPTABLEを追加していますが、このデータベースには#tempテーブルを使用する可能性のある多くのストアドプロシージャがあります。

他のデータベース/アプリケーションを壊すことなく、これをより速く修正するにはどうすればよいですか?

このデータベースはこのインスタンス上にある必要がありますか?そうでない場合は、@ Max Vernonが質問のコメントで提案したように、デフォルトの照合順序SQL_Latin1_General_CP1_CI_ASで作成されたインスタンスにこれをインストールできます。おそらく、データベースが10 GB未満でEnterprise Editionの機能を必要としない場合は、SQL Server Express Editionの使用を回避することもできます。

しかし、それが選択肢ではない場合は、すでにあなたがしていること、

cOLLATE SQL_Latin1_General_CP1_CI_ASをCREATE TABLE #TEMPTABLEステートメントに追加する

あなたができる唯一の信頼できることはほとんどです。

クライアントから提供されたアプリの動作に悪影響を与えたくないので、新しいデータベースの照合順序を変更することはできません。実際、DBのデフォルトの照合順序を変更しても、そのDB内のテーブルの列の照合順序が更新されないため、現在の問題は修正されません。これは、文字列リテラルと変数の照合順序にのみ影響し、比較されるのはこれら2つだけの場合のみです(列の照合順序は、文字列リテラルと変数の暗黙の照合順序をオーバーライドするため)。

SQL Server上の既存のDBに悪影響を与えたくないので、現在のインスタンスの照合順序をSQL_Latin1_General_CP1_CI_ASに変更するというトラブルを経験しても意味がありません。

新しいDBと関連コードがSQL_Latin1_General_CP1_CI_ASをデフォルトの照合順序として持つインスタンスで開発された(そしてうまくいけばテストされた!)ことを考えると、新しいDBのクエリが実際と同じように動作するようにする必要があります。それらが作成された環境。これを行うには、COLLATE句を追加して(一時的に)一時テーブルの文字列列の照合を強制する必要があります。ええと、技術的に言えばcan一時テーブルをテーブル変数に変更します。これは、デフォルトの照合順序が現在のデータベースから取得されるためですが、クエリオプティマイザーがテーブル変数を処理しないため、より煩わしい変更になります。一時テーブルと同じ方法です(他にも注目すべき違いがあります)。

COLLATE句では、DATABASE_DEFAULTを使用するか、SQL_Latin1_General_CP1_CI_ASを引き続き使用できます。新しいDBの照合順序が変更される可能性は低いので、どちらもここでは同等です(変更された場合、変更が含まれていないクライアントからの新しいDBが存在することになります;-)。


参考:SQL_Latin1_General_CP1_CI_ASLatin1_General_CI_ASの違いはあまりありません。どちらも同じロケール(1033)と同じコードページ(1252)を使用しています。主な違いは次のとおりです。

  • SQL_照合は長い間推奨されておらず、可能であれば回避する必要があります
  • 単語内のアポストロフィとダッシュを別の方法で扱います
  • SQL_照合順序では、SQL_照合順序よりも多くの文字に相当する、Unicodeによって提供されるいくつかの拡張/正規化が可能です。
4
Solomon Rutzky

たとえば、異国の照合がその地域の標準的な場所である別の国で提供されているデータベースに接続している場合などです。

その場合、バリアント照合があるデータベース(またはテーブル)との結合など、2つ(またはそれ以上)の照合が必要になる理由があります。

おそらく最良の選択は、クエリにCOLLATE DATABASE_DEFAULTを含めることです。これは、多くの(すべてではない)照合問題を処理します。

以下の非常に単純な例:

SELECT [ITEM_KEY],[PERSON_NAME]
FROM   [TempDB].[dbo].[ITEM] AS SC
  JOIN [NonStandardCollation].[dbo].[REMOTEITEM] AS NSC
WHERE  SC.ITEM_KEY COLLATE DATABASE_DEFAULT =  NSC.ITEM_KEY

この場合、特に他のいくつかの照合を扱う場合、サーバー上のコードが単純化されます。

2
RLF