SQL INSERT문 따옴표 이스케이프가 필요한 이유

CSV 파일을 SQL INSERT문으로 옮기다가 갑자기 문법 오류가 뜨는 경우가 있습니다. 원인을 찾아보면 대부분 값 하나에 작은따옴표(어퍼스트로피)가 들어있을 뿐입니다. 예를 들어 상품명이 "Women's Shoes"처럼 아포스트로피를 포함하고 있으면, 그 값을 그대로 SQL문에 넣는 순간 나머지 문장 전체가 깨져버립니다.
이 현상은 데이터가 이상해서 생기는 문제가 아닙니다. SQL이 문자열을 표현하는 방식 자체에서 나오는 필연적인 결과입니다. 원리를 알면 왜 이스케이프 처리가 필요한지, 그리고 왜 손으로 값을 하나씩 고치는 대신 변환 과정에서 자동으로 처리해야 하는지가 분명해집니다.
요약 ① SQL은 문자열 값을 작은따옴표 한 쌍으로 감싸서 "여기부터 여기까지가 텍스트"라고 표시합니다. ② 값 안에 작은따옴표가 그대로 들어있으면, SQL 파서는 그 지점에서 문자열이 끝났다고 오해합니다. ③ 그래서 값 안의 작은따옴표는 두 번 반복해 적어야 "이건 문자열을 끝내는 기호가 아니라 실제 글자"라고 구분됩니다.
SQL은 왜 문자열을 작은따옴표로 감싸는가
SQL문에서 텍스트 값은 항상 작은따옴표 한 쌍으로 감쌉니다. 예를 들어 이름 컬럼에 "모니터"를 넣는다면 'monitor'처럼 앞뒤로 작은따옴표를 붙여야, 데이터베이스가 이것이 숫자나 명령어가 아니라 문자 그대로의 텍스트라는 것을 알아챕니다.
이 작은따옴표는 단순한 장식이 아니라 문자열의 시작과 끝을 표시하는 구분자입니다. 파서는 여는 작은따옴표를 만나면 "지금부터 텍스트 구간"이라고 인식하고, 다음 작은따옴표를 만나는 순간 "여기서 텍스트가 끝났다"고 판단합니다. 이 규칙 자체는 어떤 SQL 방언을 쓰든 공통으로 적용됩니다.
값 안에 작은따옴표가 있으면 무슨 일이 벌어지는가
문제는 값 자체에 작은따옴표가 포함되어 있을 때 생깁니다. 상품명이 "Women's Shoes"라고 가정하고 이 값을 그대로 옮기면 VALUES ('Women's Shoes')라는 문장이 만들어집니다.
파서 입장에서는 이 문장을 다르게 읽습니다. 첫 번째 작은따옴표에서 문자열이 시작되고, 두 번째 작은따옴표인 Women 바로 뒤의 것을 만나는 순간 "문자열이 여기서 끝났다"고 판단해 버립니다. 그러면 남은 s Shoes'는 문자열 바깥에 뜬금없이 놓인 글자 덩어리가 되어, 파서가 기대하던 위치(쉼표나 괄호 닫힘)에 엉뚱한 문자가 와서 문법 오류로 이어집니다.
왜 따옴표를 두 번 반복해서 적어야 하는가
이 문제를 푸는 방법은 값 안의 작은따옴표를 두 번 연속으로 적는 것입니다. 즉 'Women's Shoes' 대신 'Women''s Shoes'처럼 써야 합니다. 두 개가 연달아 나오면 파서는 이것을 "문자열이 끝났다는 신호"가 아니라 "문자열 안에 실제로 들어있는 작은따옴표 글자 하나"로 해석합니다.
이 방식은 특정 프로그램만의 편법이 아니라 SQL 표준에서 정한 이스케이프 규칙입니다. 그래서 값을 SQL문에 넣기 전에는 항상 "이 값 안에 작은따옴표가 몇 개 있는지, 각각을 두 번씩 반복했는지"를 확인해야 문법이 깨지지 않습니다. CSV 파일 하나에 수백 행이 있고 그중 몇 개에만 아포스트로피가 섞여 있다면, 이 확인을 손으로 매 값마다 반복하는 일은 눈에 잘 띄지도 않고 놓치기도 쉽습니다.
CSV를 붙여넣으면 값 안의 작은따옴표까지 자동으로 이스케이프된 CREATE TABLE·INSERT문을 바로 생성합니다.

도구가 값마다 이 판단을 대신하는 방식
CSV를 SQL로 변환하는 이 도구는 각 값을 SQL문에 넣기 전에 값 안의 작은따옴표를 자동으로 두 개씩으로 바꿔서 적습니다. CSV 한 줄에 아포스트로피가 몇 개 들어있든, 어느 행 어느 컬럼에 있든 상관없이 변환 과정에서 동일하게 적용되기 때문에, 입력한 CSV를 붙여넣는 순간 결과 INSERT문에는 이미 이스케이프가 끝난 값이 나타납니다. 값 하나하나를 열어보고 따옴표가 있는지 눈으로 찾아 고칠 필요가 없어지는 지점입니다.
모든 컬럼에 따옴표를 감싸는 것은 아니다
다만 이 처리는 텍스트로 판단된 컬럼에만 적용됩니다. CSV의 각 컬럼 값을 살펴 전부 숫자 형태이면 정수나 소수로, true/false나 yes/no 형태이면 불리언으로 판단하는데, 이렇게 텍스트가 아닌 값으로 판정된 컬럼은 애초에 작은따옴표로 감싸지 않고 값 그대로 SQL문에 들어갑니다. 작은따옴표 문제 자체가 "문자열 리터럴"에서만 발생하는 현상이므로, 숫자나 불리언 컬럼에는 이스케이프할 대상 자체가 없는 셈입니다. 반대로 값에 문자가 섞여 있어 텍스트로 판정된 컬럼만 따옴표로 감싸이고, 그 안의 작은따옴표만 이스케이프 대상이 됩니다.
정리
- SQL은 문자열 값을 작은따옴표 한 쌍으로 감싸서 텍스트의 시작과 끝을 표시합니다.
- 값 안에 작은따옴표가 그대로 들어있으면, 파서가 그 지점을 문자열의 끝으로 오해해 나머지 문장이 문법 오류로 이어집니다.
- 해결책은 값 안의 작은따옴표를 두 번 연속으로 적는 것으로, 이는 SQL 표준이 정한 이스케이프 방식입니다.
- 이 문제는 텍스트로 다뤄지는 값에서만 생기며, 숫자나 불리언으로 판정된 컬럼은 애초에 따옴표로 감싸지 않으므로 해당하지 않습니다.
- CSV 행이 많아질수록 아포스트로피가 섞인 값을 손으로 찾아 고치기보다, 변환 과정에서 자동으로 이스케이프하는 편이 누락 없이 안전합니다.
CSV를 붙여넣으면 값 안의 작은따옴표까지 자동으로 이스케이프된 CREATE TABLE·INSERT문을 바로 생성합니다.
자주 묻는 질문
작은따옴표 대신 큰따옴표로 문자열을 감싸면 이 문제가 없어지나요?
방언마다 다릅니다. 일부 데이터베이스는 문자열에 큰따옴표 사용을 허용하기도 하지만, PostgreSQL이나 SQL Server 같은 방언에서는 큰따옴표가 문자열이 아니라 테이블·컬럼 같은 식별자를 감싸는 용도로 쓰입니다. 그래서 큰따옴표로 바꾸는 것은 근본적인 해결이 아니고, 오히려 다른 문법 오류를 만들 수 있습니다. 문자열 리터럴은 작은따옴표라는 전제 위에서 이스케이프를 하는 것이 방언 간에 가장 폭넓게 통하는 방법입니다.
따옴표를 두 번 쓰는 대신 백슬래시(')로 이스케이프해도 되나요?
일부 데이터베이스는 백슬래시 이스케이프도 인식하지만, 이는 SQL 표준에 포함된 방식이 아니라 특정 방언의 확장 기능에 가깝습니다. 설정이나 방언에 따라 백슬래시가 그대로 문자로 취급되어 오히려 값이 이상하게 들어갈 수도 있습니다. 작은따옴표를 두 번 반복하는 방식이 여러 방언에서 공통으로 통하는 표준적인 이스케이프 방법입니다.
이스케이프를 안 하면 항상 눈에 보이는 오류가 나나요?
꼭 그렇지는 않습니다. 작은따옴표 때문에 문자열이 예상보다 일찍 끝나면 그 뒤에 남는 글자들이 문장 구조와 맞지 않아 대체로 문법 오류로 이어집니다. 다만 남은 글자들이 우연히 다음 문장과 맞아떨어지는 형태가 되면, 오류 없이 실행되면서 원래 의도와 다른 값이 저장되는 경우도 이론적으로는 있을 수 있습니다. 구체적으로 어떤 결과가 나올지는 나머지 문장 구조와 데이터베이스에 따라 달라지므로 일반화하기는 어렵고, 애초에 이스케이프를 해서 이런 불확실성 자체를 없애는 편이 안전합니다.
숫자나 불리언 컬럼의 값도 이스케이프를 신경 써야 하나요?
그럴 필요는 없습니다. 작은따옴표로 값을 감싸는 것은 문자열(텍스트) 값에만 해당하는 표기 방식이고, 숫자나 불리언 값은 애초에 따옴표 없이 그대로 SQL문에 들어갑니다. 값이 따옴표로 감싸이지 않으니 그 안에서 따옴표가 문자열을 끊는 문제도 발생하지 않습니다. 이 도구도 컬럼을 숫자나 불리언으로 판정했을 때는 값을 따옴표 없이 그대로 쓰고, 텍스트로 판정된 컬럼만 따옴표로 감싸고 이스케이프 처리를 적용합니다.
