giip
SES 안건 등록
SQL Server참조만文字セット障害対応

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;

이 목록은 조사 범위를 좁히기 위한 것일 뿐, 해당 컬럼이 존재하는 것 자체가 문제는 아닙니다. 다음 단계에서 개별 컬럼의 데이터를 확인합니다.

소스코드 내 N 프리픽스 누락을 기계적으로 탐지한다(참조 전용)참조만
対象
애플리케이션·저장 프로시저 소스코드 레포지토리
権限
레포지토리 읽기 권한
変更作業
없음(참조만)
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)을 거치는 쓰기 경로에서만 발생한다
  • 한 번 "수정"했다고 생각한 코드베이스에서, 다른 위치·다른 프로젝트에서 같은 증상이 재발한다

가능한 원인(가능성이 높은 순)

  1. 01

    문자열 리터럴이 연결의 기본 코드페이지로 암묵 변환된다

    N 프리픽스가 없는 단일 인용 문자열 리터럴은 먼저 non-Unicode 문자열로 해석되고, 연결의 기본 코드페이지로 변환된 후 NVARCHAR 타입에 대입됩니다. 그 코드페이지로 표현할 수 없는 문자는 변환 시 손실됩니다.

  2. 02

    동적 SQL을 조립할 때 NVARCHAR를 의식하지 않고 문자열을 결합하고 있다

    문자열 결합이나 sp_executesql로 SQL문을 조립할 때, 삽입하는 값의 문자열 리터럴에 N 프리픽스를 빠뜨리기 쉽습니다. 특히 값이 파라미터가 아니라 문자열로 직접 삽입되는 경우에 자주 발생합니다.

  3. 03

    에러도 경고도 없어 테스트에서 알아차리기 어렵다

    컴파일 에러도 런타임 에러도 발생하지 않기 때문에 ASCII만 있는 테스트 데이터로는 정상으로 보입니다. 실제 비ASCII 데이터가 들어가야 비로소 증상이 나타납니다.

  4. 04

    한 번 손실된 문자는 독립된 출처가 없으면 복구할 수 없다

    암묵 변환으로 손실된 문자는 NVARCHAR 컬럼 안에 남아 있지 않습니다. 다른 시스템의 로그나 원본 데이터 백업 등 독립된 출처가 따로 없는 한, 이후에 정확한 값을 복원할 수 없습니다.

확인 절차

  1. 1

    대상 테이블의 nvarchar/nchar 컬럼을 찾아낸다

    참조만

    위의 진단 SQL로 비ASCII 문자를 담을 수 있는 컬럼 목록을 만듭니다.

  2. 2

    소스코드 내 N 프리픽스 누락을 검색한다

    참조만

    grep으로 의심되는 문자열 리터럴과 동적 SQL 조립 위치를 찾아내고 건별로 확인합니다.

  3. 3

    기존 데이터의 손상 징후를 확인한다

    참조만

    원래 비ASCII여야 하는 컬럼에서 의도치 않은 문자로 바뀐 곳이 없는지 개별 확인합니다.

  4. 4

    손상된 데이터의 독립된 출처가 있는지 확인한다

    참조만

    외부 시스템 로그나 다른 경로의 기록 등, 올바른 값을 가진 별도 정보원이 남아 있는지 확인합니다.

대응 방법

즉시 실행 가능한 저위험 대응

  • 신규 코드의 모든 NVARCHAR 리터럴에 N 프리픽스를 붙인다

    낮음

    신규 추가·수정하는 SQL 코드부터 시작하여, 기존 비ASCII 문자열 리터럴에도 N 프리픽스를 붙입니다.

  • 동적 SQL 생성 부분을 우선적으로 수정한다

    낮음

    문자열 결합이나 sp_executesql로 조립하는 부분은 영향 범위가 넓으므로 우선 수정합니다. 가능하면 파라미터화로 전환합니다.

사전 검토가 필요한 변경

  • 코드 리뷰 체크 항목에 추가한다

    낮음

    NVARCHAR 컬럼에 대한 문자열 리터럴 대입을 리뷰 시 확인 항목으로 명문화합니다.

  • CI·pre-commit에서 N 프리픽스 누락을 기계적으로 탐지한다

    중간

    위의 grep 패턴을 CI나 pre-commit 훅에 넣어, 육안 리뷰만 의존하지 않는 구조로 만듭니다.

전문가의 검토가 필요한 작업

  • 이미 손상된 기존 데이터의 복구를 검토한다

    전문가 검토 필수

    독립된 출처(외부 로그, 다른 경로의 백업 등)가 있는 경우에만 복구할 수 있습니다. 없는 경우 복구할 수 없다는 점을 관계자에게 명확히 알리고, 이후 재발 방지에 집중합니다.

!주의 사항

  • N 프리픽스를 신규 코드에 붙여도, 이미 손상되어 저장된 기존 데이터는 자동으로 고쳐지지 않습니다.
  • 애플리케이션 계층에서 SQL 문자열을 조립하는 경우, 문자열 결합이 아니라 파라미터화된 바인드를 쓰면 이 문제 자체를 회피할 수 있습니다. 가능한 한 파라미터화를 우선하세요.
  • 테스트 데이터가 ASCII만이면 본 가동까지 알아차릴 수 없습니다. 테스트에는 의도적으로 비ASCII 문자(한글·일본어·이모지 등)를 포함시키세요.
  • 한 번 전면 수정해도, 새 코드 경로나 외부에서 가져온 샘플 SQL에 예전 방식이 섞여 들어가면 재발합니다. 기계적 탐지를 계속 유지하세요.

버전·환경에 따른 차이

Azure SQL Database·Managed Instance온프레미스 SQL Server와 동일하게 동작합니다. 연결 문자열이나 정렬 순서 설정과 무관하게, N 프리픽스가 없는 리터럴은 마찬가지로 암묵 변환 대상이 됩니다.

이것으로 해결되지 않을 때 확인할 사항

  • 자체 코드베이스에서 같은 패턴이 다른 곳에도 없는지 횡단 검색했는가

    한 곳만 고쳐서는, 같은 방식이 다른 저장 프로시저나 배치 처리에 남아 있을 수 있습니다.

  • 손상이 의심되는 컬럼에 대해 독립된 출처가 따로 남아 있는가

    없다면 복구할 수 없다는 것을 전제로 앞으로의 운영을 설계합니다.

  • 파라미터화된 쿼리 경로는 원래 이 문제의 영향을 받지 않는다

    ORM이나 드라이버의 파라미터 바인드를 쓰는 경로는 대상 외임을 확인하고 우선순위를 올바르게 판단합니다.

이 문서의 근거와 한계

제품 공식 문서에 기반한 설명

유니코드 문자열 리터럴에 N 프리픽스가 필요하다는 것은 SQL Server 공식 문서에 명시된 사양입니다. 이 문서가 설명하는 "알아차리기 어려움"과 재발하기 쉬운 경향은 실제 운영에서 여러 차례 관찰된 경향을 일반화한 것이며, 특정 고객의 사례·건수·시점은 포함하지 않습니다.

자주 묻는 질문

N 프리픽스를 빠뜨리면 반드시 에러가 나나요?

아닙니다. 컴파일 에러도 런타임 에러도 발생하지 않습니다. 연결의 기본 코드페이지로 표현할 수 없는 문자가 조용히 손실될 뿐, 처리 자체는 정상 종료합니다.

동적 SQL이 아닌 경우에도 발생하나요?

네. 문자열 리터럴을 직접 NVARCHAR 타입의 컬럼·변수·파라미터에 대입하는 경로라면, 정적인 INSERT문에서도 동일하게 발생합니다.

파라미터화 쿼리를 쓰면 막을 수 있나요?

네. 드라이버나 ORM의 파라미터 바인드를 쓰는 경로에서는 값의 타입과 문자 인코딩이 드라이버 쪽에서 올바르게 처리되므로, 이 문제 자체가 발생하지 않습니다.

손상된 데이터는 복구할 수 있나요?

독립된 출처(외부 시스템 로그나 다른 경로의 기록 등)가 따로 남아 있는 경우에만 복구할 수 있습니다. NVARCHAR 컬럼 안에는 원래 문자가 남아 있지 않으므로, 출처가 없으면 복구할 수 없습니다.

이 문서가 다루는 질문

  • SQL Server에서 한글이나 이모지가 깨지는 원인
  • N 프리픽스 없는 SQL 문자열에서 무슨 일이 일어나는가

위험도 표시의 의미

  • 참조만데이터와 설정을 변경하지 않습니다.
  • 낮음영향은 제한적이지만 권한과 부하 확인이 필요합니다.
  • 중간성능·락·비용에 영향을 줄 수 있습니다.
  • 높음장애·데이터 손실·복구 작업이 발생할 수 있습니다.
  • 전문가 검토 필수프로덕션 적용 전 별도 검토가 반드시 필요합니다.

GIIP의 대응 범위

GIIP에서는 신규로 추가하는 SQL 코드에 대해 N 프리픽스 누락을 기계적으로 탐지하는 체크를 리뷰 공정에 넣고 있습니다. 같은 패턴의 사고가 여러 프로젝트에서 형태를 바꿔 재발한 경험으로, 리뷰에서의 육안 확인만 의존하지 않고 기계적 탐지를 반드시 병용하는 방침입니다.

작성·기술 검증

GIIP 프로덕션 운영팀

대규모 웹 서비스, SQL Server, Oracle, AWS, Azure의 설계·마이그레이션·운영에 약 30년간 종사했습니다. x12large급 AWS RDS for SQL Server 환경 12세트, 약 12만 개 테이블 규모의 Oracle 환경, 약 3TB 규모의 TiDB에서 Aurora MySQL로의 마이그레이션 경험이 있습니다. 현재도 다수의 클라우드 데이터베이스와 약 30개의 웹 서비스를 AI 에이전트와 사람 전문가가 지속적으로 모니터링·운영하고 있습니다.

관련 노하우

관련 서비스

NVARCHAR 리터럴 일괄 점검을 요청한다

동일한 확인을 여러 환경에서 계속해야 한다면, 운영 체계 전체를 상담할 수 있습니다.

NVARCHAR 리터럴 일괄 점검을 요청한다

← 지식 베이스 목록으로