NVARCHAR 리터럴의 N 프리픽스 누락으로 한글·이모지가 에러 없이 깨지는 문제
公開日 2026-08-16 · 更新日 2026-08-16 · 最終検証日 2026-08-16
結論
SQL Server에서 NVARCHAR 컬럼에 문자열 리터럴을 직접 대입할 때 `N` 프리픽스를 빠뜨리면, 리터럴은 연결의 기본 코드페이지로 암묵 변환된 후 NVARCHAR 타입에 저장됩니다. 한글·일본어·이모지 등 그 코드페이지로 표현할 수 없는 문자는 손실되지만, 이는 에러도 경고도 발생시키지 않고 값만 조용히 깨집니다. ASCII만 있는 테스트 데이터로는 알아차릴 수 없어 본 가동 이후에 발견되는 경우가 많고, 같은 패턴이 반복적으로 재발하기 쉽습니다.
この文書の適用条件
| 対象製品 | SQL Server(유니코드 문자열 리터럴 전반에 영향) |
|---|---|
| 確認バージョン | SQL Server 2012 이상(Azure SQL Database·Managed Instance 포함) |
| 適用環境 | 온프레미스, EC2, Amazon RDS for SQL Server, Azure SQL |
| 必要権限 | 진단 SQL은 대상 테이블의 SELECT 권한만 필요. 소스코드 검색은 레포지토리 읽기 권한 |
| 実行影響 | 본 문서의 진단은 모두 참조 전용. 기존에 손상된 데이터의 수정·복구는 별도로 대상 행의 UPDATE를 수반함 |
| 再起動 | 불필요 |
| 最終検証日 | 2026-08-16 |
そのまま実行できるコマンド
- 対象
- SQL Server 2012 이상 / Azure SQL Database·Managed Instance
- 権限
- 대상 테이블의 SELECT 권한(메타데이터 참조는 public 롤로 가능)
- 変更作業
- 없음(참조만)
- Production実行
- 가능
-- 対象: SQL Server 2012 以降 / Azure SQL Database・Managed Instance
-- 権限: メタデータの参照はpublicロールで可。個々のデータ確認には対象テーブルのSELECT権限が必要
-- 変更作業: なし(参照のみ)
-- Production実行: 可能
-- 非ASCII文字を保持しうる nvarchar / nchar 列を一覧化する(調査対象の絞り込み用)
SELECT
t.name AS table_name,
c.name AS column_name,
ty.name AS type_name,
c.max_length
FROM sys.columns AS c
INNER JOIN sys.tables AS t
ON t.object_id = c.object_id
INNER JOIN sys.types AS ty
ON ty.user_type_id = c.user_type_id
WHERE ty.name IN ('nvarchar', 'nchar')
ORDER BY t.name, c.column_id;이 목록은 조사 범위를 좁히기 위한 것일 뿐, 해당 컬럼이 존재하는 것 자체가 문제는 아닙니다. 다음 단계에서 개별 컬럼의 데이터를 확인합니다.
- 対象
- 애플리케이션·저장 프로시저 소스코드 레포지토리
- 権限
- 레포지토리 읽기 권한
- 変更作業
- 없음(참조만)
- Production実行
- 가능
# 対象: アプリケーション・ストアドプロシージャのソースコードリポジトリ
# 権限: リポジトリの読み取り権限
# 変更作業: なし(参照のみ)
# Production実行: 可能
#
# .sql ファイル内で、Nプレフィックスの無いシングルクォート文字列リテラルのうち
# 非ASCII文字を含むものを検出する(正規表現なので誤検知はあり、ヒット箇所は目視確認が前提)
grep -RnoP "(?<![Nn])'[^']*[^\x00-\x7F][^']*'" --include=*.sql .
# 文字列結合や sp_executesql で動的SQLを組み立てている箇所も洗い出す
grep -RniE "(sp_executesql|EXEC\(|exec\()" --include=*.sql --include=*.cs --include=*.ts .주석이나 의도된 비ASCII 문자열(에러 메시지 문구 등)도 함께 잡히므로, 정규식 히트는 모두 "조사 대상"일 뿐 "확정된 버그"가 아닙니다. 건별로 NVARCHAR 컬럼·파라미터 대입 여부를 확인합니다.
こういう状況で使います
- 한글·일본어·이모지가 포함된 데이터를 등록하면 에러는 없지만 저장 후 값이 "?"나 다른 문자로 바뀌어 있다
- 애플리케이션 테스트(ASCII만 있는 테스트 데이터)에서는 문제가 없고, 본 가동 이후나 실데이터 투입 후에야 발견된다
- 동적 SQL(문자열 결합이나 sp_executesql)을 거치는 쓰기 경로에서만 발생한다
- 한 번 "수정"했다고 생각한 코드베이스에서, 다른 위치·다른 프로젝트에서 같은 증상이 재발한다
考えられる原因(可能性の高い順)
01
문자열 리터럴이 연결의 기본 코드페이지로 암묵 변환된다
N 프리픽스가 없는 단일 인용 문자열 리터럴은 먼저 non-Unicode 문자열로 해석되고, 연결의 기본 코드페이지로 변환된 후 NVARCHAR 타입에 대입됩니다. 그 코드페이지로 표현할 수 없는 문자는 변환 시 손실됩니다.
02
동적 SQL을 조립할 때 NVARCHAR를 의식하지 않고 문자열을 결합하고 있다
문자열 결합이나 sp_executesql로 SQL문을 조립할 때, 삽입하는 값의 문자열 리터럴에 N 프리픽스를 빠뜨리기 쉽습니다. 특히 값이 파라미터가 아니라 문자열로 직접 삽입되는 경우에 자주 발생합니다.
03
에러도 경고도 없어 테스트에서 알아차리기 어렵다
컴파일 에러도 런타임 에러도 발생하지 않기 때문에 ASCII만 있는 테스트 데이터로는 정상으로 보입니다. 실제 비ASCII 데이터가 들어가야 비로소 증상이 나타납니다.
04
한 번 손실된 문자는 독립된 출처가 없으면 복구할 수 없다
암묵 변환으로 손실된 문자는 NVARCHAR 컬럼 안에 남아 있지 않습니다. 다른 시스템의 로그나 원본 데이터 백업 등 독립된 출처가 따로 없는 한, 이후에 정확한 값을 복원할 수 없습니다.
確認手順
- 1
대상 테이블의 nvarchar/nchar 컬럼을 찾아낸다
参照のみ위의 진단 SQL로 비ASCII 문자를 담을 수 있는 컬럼 목록을 만듭니다.
- 2
소스코드 내 N 프리픽스 누락을 검색한다
参照のみgrep으로 의심되는 문자열 리터럴과 동적 SQL 조립 위치를 찾아내고 건별로 확인합니다.
- 3
기존 데이터의 손상 징후를 확인한다
参照のみ원래 비ASCII여야 하는 컬럼에서 의도치 않은 문자로 바뀐 곳이 없는지 개별 확인합니다.
- 4
손상된 데이터의 독립된 출처가 있는지 확인한다
参照のみ외부 시스템 로그나 다른 경로의 기록 등, 올바른 값을 가진 별도 정보원이 남아 있는지 확인합니다.
対応方法
すぐに実施できる低リスクの対応
신규 코드의 모든 NVARCHAR 리터럴에 N 프리픽스를 붙인다
低신규 추가·수정하는 SQL 코드부터 시작하여, 기존 비ASCII 문자열 리터럴에도 N 프리픽스를 붙입니다.
동적 SQL 생성 부분을 우선적으로 수정한다
低문자열 결합이나 sp_executesql로 조립하는 부분은 영향 범위가 넓으므로 우선 수정합니다. 가능하면 파라미터화로 전환합니다.
事前検討が必要な変更
코드 리뷰 체크 항목에 추가한다
低NVARCHAR 컬럼에 대한 문자열 리터럴 대입을 리뷰 시 확인 항목으로 명문화합니다.
CI·pre-commit에서 N 프리픽스 누락을 기계적으로 탐지한다
中위의 grep 패턴을 CI나 pre-commit 훅에 넣어, 육안 리뷰만 의존하지 않는 구조로 만듭니다.
専門家のレビューが必要な作業
이미 손상된 기존 데이터의 복구를 검토한다
専門家レビュー必須독립된 출처(외부 로그, 다른 경로의 백업 등)가 있는 경우에만 복구할 수 있습니다. 없는 경우 복구할 수 없다는 점을 관계자에게 명확히 알리고, 이후 재발 방지에 집중합니다.
!注意事項
- N 프리픽스를 신규 코드에 붙여도, 이미 손상되어 저장된 기존 데이터는 자동으로 고쳐지지 않습니다.
- 애플리케이션 계층에서 SQL 문자열을 조립하는 경우, 문자열 결합이 아니라 파라미터화된 바인드를 쓰면 이 문제 자체를 회피할 수 있습니다. 가능한 한 파라미터화를 우선하세요.
- 테스트 데이터가 ASCII만이면 본 가동까지 알아차릴 수 없습니다. 테스트에는 의도적으로 비ASCII 문자(한글·일본어·이모지 등)를 포함시키세요.
- 한 번 전면 수정해도, 새 코드 경로나 외부에서 가져온 샘플 SQL에 예전 방식이 섞여 들어가면 재발합니다. 기계적 탐지를 계속 유지하세요.
バージョン・環境による違い
これで解決しない場合に確認すること
자체 코드베이스에서 같은 패턴이 다른 곳에도 없는지 횡단 검색했는가
한 곳만 고쳐서는, 같은 방식이 다른 저장 프로시저나 배치 처리에 남아 있을 수 있습니다.
손상이 의심되는 컬럼에 대해 독립된 출처가 따로 남아 있는가
없다면 복구할 수 없다는 것을 전제로 앞으로의 운영을 설계합니다.
파라미터화된 쿼리 경로는 원래 이 문제의 영향을 받지 않는다
ORM이나 드라이버의 파라미터 바인드를 쓰는 경로는 대상 외임을 확인하고 우선순위를 올바르게 판단합니다.
この文書の根拠と限界
製品の公式ドキュメントに基づく説明
유니코드 문자열 리터럴에 N 프리픽스가 필요하다는 것은 SQL Server 공식 문서에 명시된 사양입니다. 이 문서가 설명하는 "알아차리기 어려움"과 재발하기 쉬운 경향은 실제 운영에서 여러 차례 관찰된 경향을 일반화한 것이며, 특정 고객의 사례·건수·시점은 포함하지 않습니다.
よくある質問
N 프리픽스를 빠뜨리면 반드시 에러가 나나요?
아닙니다. 컴파일 에러도 런타임 에러도 발생하지 않습니다. 연결의 기본 코드페이지로 표현할 수 없는 문자가 조용히 손실될 뿐, 처리 자체는 정상 종료합니다.
동적 SQL이 아닌 경우에도 발생하나요?
네. 문자열 리터럴을 직접 NVARCHAR 타입의 컬럼·변수·파라미터에 대입하는 경로라면, 정적인 INSERT문에서도 동일하게 발생합니다.
파라미터화 쿼리를 쓰면 막을 수 있나요?
네. 드라이버나 ORM의 파라미터 바인드를 쓰는 경로에서는 값의 타입과 문자 인코딩이 드라이버 쪽에서 올바르게 처리되므로, 이 문제 자체가 발생하지 않습니다.
손상된 데이터는 복구할 수 있나요?
독립된 출처(외부 시스템 로그나 다른 경로의 기록 등)가 따로 남아 있는 경우에만 복구할 수 있습니다. NVARCHAR 컬럼 안에는 원래 문자가 남아 있지 않으므로, 출처가 없으면 복구할 수 없습니다.
この文書がカバーする質問
- SQL Server에서 한글이나 이모지가 깨지는 원인
- N 프리픽스 없는 SQL 문자열에서 무슨 일이 일어나는가
リスク表示の意味
- 参照のみデータと設定を変更しません。
- 低影響は限定的ですが、権限と負荷の確認が必要です。
- 中性能・ロック・コストに影響する可能性があります。
- 高障害・データ損失・復旧作業が発生する可能性があります。
- 専門家レビュー必須本番適用前に別途レビューが必須です。
GIIPの対応範囲
GIIP에서는 신규로 추가하는 SQL 코드에 대해 N 프리픽스 누락을 기계적으로 탐지하는 체크를 리뷰 공정에 넣고 있습니다. 같은 패턴의 사고가 여러 프로젝트에서 형태를 바꿔 재발한 경험으로, 리뷰에서의 육안 확인만 의존하지 않고 기계적 탐지를 반드시 병용하는 방침입니다.
執筆・技術検証
GIIP プロダクション運用チーム
大規模Webサービス、SQL Server、Oracle、AWS、Azureの設計・移行・運用に約30年従事。x12largeクラスのAWS RDS for SQL Server環境12セット、約12万テーブルのOracle環境、約3TBのTiDBからAurora MySQLへの移行を経験。現在も複数のクラウドデータベースと約30のWebサービスを、AIエージェントと人間の専門家が継続的に監視・運用しています。
Aurora MySQL에서 utf8mb3에서 utf8mb4로 마이그레이션할 때 확인할 사항
utf8mb4로 변환할 때 가장 먼저 깨지는 것은 인덱스의 키 길이입니다. 대상을 찾아내는 SQL, 콜레이션 선택 방법, 변환 시 영향과 설정 위치를 정리합니다.
ai-operationsAI 생성 콘텐츠의 오염을 탐지하는 가드와, 재생성을 완료 조건으로 삼지 않는 운영
AI 생성 콘텐츠에 섞여 들어가는 기존에 알려진 오염 패턴을 기계적으로 탐지하고, 재생성 후에는 본문을 직접 확인한 뒤 완료로 판단하는 운영 가드를 설명합니다.
incident-responseAI 에이전트가 데이터베이스 장애에 대응할 수 있는 범위와, 사람이 판단해야 하는 범위
장애 대응을 단계별로 나누어 AI가 담당할 수 있는 범위(감지·원인 분리·제한적인 1차 대응)와 사람이 판단해야 하는 범위(불가역적 작업·중단 판단)를 정리하고, 조회 전용 트리아지 쿼리를 제공합니다.
関連サービス
NVARCHAR 리터럴 일괄 점검을 요청한다
同じ確認を複数の環境で継続する必要がある場合は、運用体制ごと相談できます。
NVARCHAR 리터럴 일괄 점검을 요청한다