パソコン練習日記

やってみたことを記録しています。Bloggerからこちらに引っ越して来ました。一部、画像がリンク切れしていますがひとつひとつ直すのは心が折れたのでそのままにします。

SQL Server Linuxコンテナを使ったところ、日本語が?に文字化けしたので調べてみたら

プログラムの単体テスト用DB(SQL Server)として、LinuxコンテナのSQL Serverを使ってみてるのですが、テストデータを何にしようかな、とSQL Server Management StudioからポチポチInsertしてたところ、文字化け。

もう夜遅いので今度調べよう。と、寝ました。

で、今日。調査開始。

まずはSQLserver2022 On LinuxのDockerコンテナをPowershellで起動

docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=P@`$`$w0rd" -p 1433:1433 --name sqlsv22 --hostname sqlsv -d mcr.microsoft.com/mssql/server:2022-latest


DB作って、テーブル作って、日本語のデータをInsert。
テーブル構成も日本語のデータが登録できればいいので適当。

CREATE DATABASE testdb;

use testdb;

CREATE TABLE test (
    id INT PRIMARY KEY,
    message VARCHAR(255)
);

INSERT INTO test (id, message) VALUES (1, 'おはよう');

INSERT INTO test (id, message) VALUES (2, 'Good Morning');

select * from test;

とりあえず、再現OK。"おはよう"は文字化けして????になってる

で、SQLServerを使っていてそんな感じになった記憶が無いので、日本語バージョンでインストールしていたからかな?と思い、WindowsServer上にSQL Server2022をインストールしてみて同じようにやってみた。
そしたらやっぱり文字化けしていない。

じゃあ、英語バージョンで同じようにやったら文字化けするんだろうなぁ、と思いWindowsServer上に英語バージョンのSQL Server2022をインストールし同じように実行したところ、文字化けしていない。なんで?

調べたところ、2012年のSQL Server Japan Support Team Blogに「非 Unicode から Unicode への変換ができなかったから」、「データベースの照合順序がLatin1_General_CI_ASの場合」にデータが?になるとのこと。

確かにコンテナのSQL Serverインスタンスは照合順序が"SQL_Latin1_General_CP1_CI_AS"

なので、試しにCREATE DATABASEステートメントでデータを入れるDBの照合順序をJapanese_CI_ASに指定してみる。

CREATE DATABASE [testdb] 
COLLATE Japanese_CI_AS;

USE testdb;

DROP TABLE IF EXISTS test;

CREATE TABLE test (
    id INT PRIMARY KEY,
    message NVARCHAR(255)
);

INSERT INTO test (id, message) VALUES (1, N'おはよう');
INSERT INTO test (id, message) VALUES (2, N'Good Morning');

select * from test;

すると文字化けしなくなった

もう一個試し。いま稼働しているコンテナを削除し、

docker runでカスタム SQL Server照合順序を指定(-e "MSSQL_COLLATION=Japanese_CI_AS")を追加

docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=P@`$`$w0rd" -e "MSSQL_COLLATION=Japanese_CI_AS" -p 1433:1433 --name sqlsv22 --hostname sqlsv -d mcr.microsoft.com/mssql/server:2022-latest

"Japanese_CI_AS"になっていることを確認

それからこのままCreate Database、Create Table、データInsert。

文字化けしてないことを確認

で、もうひとつ実験。

いま稼働しているコンテナを削除し、もう一回、カスタム SQL Server照合順序を指定せずにDocker run

Create  Databaseでも照合順序を指定せず、テーブルのカラムmessageの型を"VARCHAR"ではなく、"NVARCHAR"に指定。日本語をInsertの際、Unicode文字列として処理されるようNプレフィックスを付ける

CREATE DATABASE testdb;

use testdb;

CREATE TABLE test (
    id INT PRIMARY KEY,
    message NVARCHAR(255)
);

INSERT INTO test (id, message) VALUES (1, N'おはよう');
INSERT INTO test (id, message) VALUES (2, 'Good Morning');

select * from test;

これも文字化けしない。

 

じゃあ、今後どれで行こうかというとDocker runの時のカスタム SQL Server照合順序指定でいいかな