by WebSurfer
2020年9月24日 11:28
Microsoft LocalDB の照合順序はデフォルトで SQL_Latin1_General_CP1_CI_AS になるそうです。今更ながらですが調べてみたらそうなってました。
Microsoft の Blog の記事「[SQL Azure] Unicode型列(NCHAR/NVARCHAR) に格納されるデータが “?” になる」によると、SQL Azure も同じだそうです。
なので、その記事にも書いてありますが、以下のような N プレフィックスを使わない SQL では文字化けします。
INSERT INTO [Table] ([Name]) VALUES ('あいうえお')
知ってました? 何をいまさらと言われそうですけど。(汗)
SQL 文をパラメータ化し ADO.NET + SqlClient を利用して INSERT, UPDATE 操作を行えば、内部的に N プレフィックスが付与された SQL 文に変換されて実行され、文字化けの問題は起こらないので、気が付かないかもしれません。(詳しくは先の記事「パラメータ化の副次的な効用」参照)
Visual Studio を使って ASP.NET プロジェクトを作る際[個別のユーザーアカウント]を選ぶと、ASP.NET Identity のユーザー情報のストアはデフォルトで LocalDB を使う設定となり、EF Code First で生成されるデータベースの照合順序も同じく SQL_Latin1_General_CP1_CI_AS になります。
自分でモデルを定義してそれをベースに EF Code First でデータベースを生成する場合も、接続文字列で LocalDB に接続する設定がされていると当然 LocalDB にデータベースが生成されますが、同様に照合順序は SQL_Latin1_General_CP1_CI_AS になります。
ASP.NET MVC アプリでは Linq to Entities を使って DbContext クラスを継承したコンテキストクラスを操作してデータベースとのやり取りを行うケースが多いですが、そういう場合も内部的に N プレフィックスが付与された SQL 文に変換されて実行されるようで、文字化けの問題は起こらなかったです。
by WebSurfer
2018年4月26日 19:27
自分の持っている本「一目でわかる Microsoft SQL Server 2008」によると、SQL Server の照合順序はサーバー、データベース、列、式に対して指定することができるそうです。(テーブルレベルでは指定できないようです)
そして、照合順序は変更できるのですが、既存のデータベースの照合順序を変更しても、そのテーブルの中の列の照合順序は元のままで、変更されないということは知ってました?
実は、自分は知らなかったです。おかげで 1 ~ 2 時間ハマってしまいました。(汗) また時間を無駄にすることがないように備忘録を残しておきます。
(1) データベースの照合順序
データベースの照合順序は SQL Server Management Studio (SSMS) を使って表示・変更することができます。Transact-SQL を使っても可能です。詳しくは Microsoft の文書「照合順序情報の表示」を見てください。
上の画像は、SSMS で既存のデータベース TestDatabase を右クリックして[データベースのプロパティ]ダイアログを開き、[ページの選択]で[オプション]を選択したものです。[照合順序(C)]ボックスに現在の照合順序が表示されています。
この画面で、[照合順序(C)]ボックスのドロップダウンリストから他の照合順序を選んで、変更することができます。
現在はサーバーレベルでのデフォルトの照合順序を継承して Japanese_CI_AS になっていますが、試しにそれを Japanese_BIN2 に変更してみます。
(2) 列の照合順序
上の画像は、上記 (1) で既存のデータベース TestDatabase の照合順序を Japanese_CI_AS から Japanese_BIN2 に変更した後の、テーブル dbo.T_TRADE の 列 USER_ID (varchar(10), NOT NULL) のプロパティを SSMS で見たものです。
列 USER_ID の照合順序は Japanese_CI_AS のまま変わってないのが分かるでしょうか。
(3) 列の照合順序の変更
列の照合順序の変更は Transact-SQL を使って可能です。詳しい方法は Microsoft の文書「列の照合順序の設定または変更」を見てください。
上の画像は、SSMS 上で Transact-SQL を使って、テーブル dbo.T_TRADE の 列 USER_ID の照合順序を Japanese_BIN2 に変更したところです。
(4) 変更後の列の照合順序
上の画像の通り、上記 (3) の手順を実行した結果、テーブル dbo.T_TRADE の 列 USER_ID の照合順序が Japanese_BIN2 に変更されています。
以上、既存のデーターベースの照合順序を変更しても意味はなくて、上記の操作をして列の照合順序を変えないとダメという話でした。
先の記事「SQL Server の Order By での濁音の扱い」は order by 句による並び順の話でしたが、主キーの場合は Japanese_CI_AS では濁音有り無しを区別しないことにより制約違反になることがあるということで、注意が必要です。