はじめに
SQL Serverに中国語や異体字を含む文字列を INSERT したら「?」に化けてしまった…。 そんな経験はありませんか?
実はこれ、SQL Serverが文字列をUnicodeとして扱っていないことが原因です。 この記事では、文字化けの原因と、N'...' を使った正しい登録方法、そして NVARCHAR の読み方や VARCHAR との違いまで、実例付きで分かりやすく解説します。
なぜ文字化けするのか?
SQL Serverの文字列型には2種類あります:
| 型 | Unicode対応 | 例 | 備考 |
|---|---|---|---|
VARCHAR | ❌ 非対応 | '髙橋商事' | → 「髙」が ? に化ける可能性あり |
NVARCHAR | ✅ 対応 | N'髙橋商事' | → 正しく保存される |
VARCHAR はローカルの文字コード(例:Shift-JIS)に依存するため、異体字や中国語・韓国語などのマルチバイト文字は対応していません。 一方、NVARCHAR は Unicode(UTF-16)で保存されるため、世界中の文字を正しく扱えます。
NVARCHARってなんて読むの?
「NVARCHAR」は、現場では以下のように呼ばれることが多いです:
| 読み方 | 説明 |
|---|---|
| エヌ・バーキャー | 日本語の現場でよく使われる読み方。VARCHAR を「バーキャー」と読む流儀 |
| エヌ・ヴァーチャー | 英語に近い発音。VAR を「ヴァー」と読むスタイル |
どちらでも通じますが、日本語環境では「エヌ・バーキャー」派が多めです。
チーム内で統一しておくと、会話がスムーズになります。
N'...' の意味とは?
SQL Serverでは、文字列リテラルに N を付けることで「これは Unicode 文字列です」と明示できます。
| 書き方 | 意味 | Unicode対応 |
|---|---|---|
'...' | 通常の文字列 | ❌ |
N'...' | Unicode文字列 | ✅ |
N は「National character」の略で、SQL ServerにUnicodeとして扱わせるための記号です。
実例:違いを比較してみよう
-- ❌ VARCHAR型に通常の文字列 → 文字化けする可能性あり
INSERT INTO company_table (COMPANY_NAME) VALUES ('髙橋商事');
-- ✅ NVARCHAR型にUnicodeリテラル → 正しく保存される
INSERT INTO company_table (COMPANY_NAME) VALUES (N'髙橋商事');
※ カラム型が NVARCHAR であることが前提です
よくある文字化け例
| 文字列 | 説明 |
|---|---|
髙橋商事 | 「髙」は「高」の異体字。Shift-JIS未対応 |
﨑本製作所 | 「﨑」は「崎」の異体字。よく使われるが非対応 |
纊田技研 | 「纊」はUnicode専用の旧字。VARCHARでは ? になる |
𠮷野家 | 「𠮷」は「吉」の異体字(旧字体)。Unicodeでのみ対応 |
清华大学 | 中国語の簡体字。「华」はShift-JIS未対応 |
서울대학교 | 韓国語(ハングル)。完全にUnicode依存 |
NVARCHAR に N'...' を付けないとどうなる?
意外なことに、カラム型が NVARCHAR でも、文字列リテラルが '...' のままだと文字化けする可能性があります。 SQL Serverはリテラルの形式によって、内部的な文字コードの扱いを変えるためです。
-- NG: リテラルが通常の '...' → 暗黙の型変換で文字化け
INSERT INTO company_table (COMPANY_NAME) VALUES ('髙橋商事');
-- OK: リテラルが Unicode → 正しく保存される
INSERT INTO company_table (COMPANY_NAME) VALUES (N'髙橋商事');✅ NVARCHAR 型でも、必ず N'...' を使うのが安全です
VARCHAR に N'...' を使っても意味がない?
VARCHAR カラムに N'...' を渡しても、SQL Serverは内部的に VARCHAR に変換しようとするため、Unicode文字は失われてしまいます。
| カラム型 | リテラル | 結果 |
|---|---|---|
VARCHAR | '髙橋商事' | ❌ 文字化け(?橋商事) |
VARCHAR | N'髙橋商事' | ❌ 文字化け(N は無視される) |
NVARCHAR | '髙橋商事' | ⚠️ 文字化けする可能性あり |
NVARCHAR | N'髙橋商事' | ✅ 正しく保存される |
PythonでSQL文を自動生成する場合
escaped = str(val).replace("'", "''")
sql = f"INSERT INTO company_table (COMPANY_NAME) VALUES (N'{escaped}');"✅ N'...' を使うことで、Pythonから生成したSQLでもUnicode文字が正しく登録されます
まとめ
- Unicode文字を扱うには、カラム型が
NVARCHARであることが前提 - SQL文では、文字列リテラルに
N'...'を付けることが必須 VARCHARにN'...'を使っても効果はなく、文字化けを防げないNVARCHARは「エヌ・バーキャー」または「エヌ・ヴァーチャー」と読む
このようなUnicode対応は、国際化や多言語データの取り扱いにおいて非常に重要です。 現場でのトラブル回避や設計品質の向上にもつながるので、ぜひ覚えておきましょう!


コメント