동적 SQL
설명 영상 동적 SQL · 2:08
왜 배우는가: 동적 SQL은 실행 시점에 SQL 문장을 조립하므로 검색 조건이 가변적인 업무 프로그램에서 필수적으로 쓰인다. 정적 SQL과 비교한 장단점, 보안·성능 문제는 응용 개발과 DB 튜닝 설계에서 반복적으로 판단해야 하는 주제라 시험에서도 자주 묻는다.
출제 이력: 제117회 2교시 3번, 제108회 1교시 6번
1. 한 줄 정의와 핵심 키워드
동적 SQL은 컴파일 시점이 아닌 실행 시점에 SQL 문장을 문자열로 구성하여 실행하는 방식이다.
- 동적 SQL(Dynamic SQL)
- 실행 시 구문 구성
- 준비(PREPARE)·실행(EXECUTE)
- 네이티브 동적 SQL(NDS)
- DBMS_SQL 패키지
- 바인드 변수
- SQL 삽입(SQL Injection)
2. 개념 풀이
쉽게 말하면 프로그램이 실행되는 도중에 "어떤 테이블에서, 어떤 조건으로 조회할지"를 정해 SQL을 만들어 실행하는 기법이다. 검색 조건이 사용자 입력에 따라 달라지는 화면에서 주로 쓴다.
정식으로는 호스트 언어의 실행 시에 SQL문을 생성하는 방법이다. 문장을 문자열로 만들어 DBMS에 보내면, DBMS는 그 문자열을 해석(PREPARE)하고 실행(EXECUTE)한다. 따라서 PREPARE는 문자열 SQL을 해석·번역하는 단계, EXECUTE는 번역된 SQL을 실행하는 단계다.
정적 SQL은 컴파일 시점에 문법과 대상 객체가 검증되지만, 동적 SQL은 문자열이 실행될 때 비로소 검증된다. 그래서 문법 오류가 실행 시점에 발견된다. 이 차이가 동적 SQL의 유연성과 위험성을 함께 만든다.
Oracle에서 동적 SQL을 처리하는 방식은 두 가지다. 하나는 네이티브 동적 SQL(NDS)로, EXECUTE IMMEDIATE문과 OPEN FOR문을 쓴다. 다른 하나는 DBMS_SQL 패키지로, 커서를 직접 다루는 절차형 방식이다. NDS는 SQL에 통합되어 간결하고, DBMS_SQL은 세밀한 제어가 필요할 때 쓴다.
동적 SQL에서 값은 문자열 결합보다 바인드 변수로 넘기는 것이 원칙이다. 바인드 변수는 USING 절로 전달하며, 실행 계획 재사용과 삽입 공격 방지에 도움이 된다.
3. 등장 배경과 필요성
업무 시스템에서는 검색 항목이 많고 조합이 수백 가지에 이르는 경우가 흔하다. 정적 SQL로 모든 조합을 미리 작성하면 코드가 중복되고 유지보수가 어렵다. 동적 SQL은 필요한 조건만 이어 붙여 하나의 로직으로 처리하게 한다.
또 DDL처럼 데이터베이스 제품의 기능 업데이트로 새 명령이 추가되는 문장은 정적 전처리 대상으로 두기 부담스럽다. 대부분의 DBMS에서 DDL은 동적 SQL로 실행하는 것이 일반적이다. 정적 SQL은 PL/SQL 블록 안에서 DML 중심으로 쓰이는 반면, 동적 SQL은 블록 안에서도 테이블 생성·인덱스 삭제·TRUNCATE 같은 DDL을 실행할 수 있게 해 준다.
이런 이유로 동적 SQL은 SQL 분석 오버헤드를 줄이면서도 소스 코드에 SQL을 고정하지 않는 방법으로 자리 잡았다. 실무에서는 검색 화면, 관리 배치, 데이터 이관 도구에서 많이 사용된다.
SQL 실행 시 구문 번역 과정이 매번 일어나면 비용이 커지므로, 재사용 가능한 형태로 준비해 두는 것이 동적 SQL 활용의 핵심이다.
4. 구성요소·원리·절차
동적 SQL은 실행 시점에 SQL 문자열을 만들어 DBMS에 전달하고, 이를 준비(PREPARE)와 실행(EXECUTE) 두 단계로 처리한다. 정적 SQL은 컴파일 시점에 구문과 접근 객체가 고정되지만, 동적 SQL은 문자열을 조립하므로 실행 전까지 구문이 정해지지 않는다.
| 구성요소 | 역할 | 비고 |
|---|---|---|
| SQL 문자열 | 실행 시점에 조립되는 질의 본문 | 조건·테이블명이 변수로 결정됨 |
| PREPARE 단계 | 문자열을 구문 분석·번역해 실행 가능한 중간 코드로 만듦 | 실행 계획 생성 |
| EXECUTE 단계 | 준비된 문을 바인드 값과 함께 실행 | 재사용 가능 |
| 바인드 변수 | 값을 외부에서 전달하는 자리표시자 | 구문 재사용과 SQL 주입 방지에 쓰임 |
| 실행 인터페이스 | Oracle 네이티브 동적 SQL(EXECUTE IMMEDIATE), DBMS_SQL 패키지, T-SQL의 EXEC·sp_executesql | 제품별 방식이 다름 |
원리는 다음과 같다. 문자열로 전달된 SQL은 파서가 해석하고 옵티마이저가 실행 계획을 만든다. 같은 구문이 바인드 변수 형태로 반복되면 계획과 커서를 재사용한다. 값만 바뀌고 구문 골격이 같으면 재파싱 비용이 줄어든다. 반대로 값을 문자열에 직접 이어 붙이면 구문이 매번 달라져 재사용이 깨진다.
절차는 다음과 같다.
- 응용 프로그램이 조건에 따라 SQL 문자열을 조립한다.
- 문자열을 DBMS에 전달하고 PREPARE 단계에서 구문을 해석한다. 이때 문법 오류가 검출된다.
- 바인드 변수에 실제 값을 연결한다.
- EXECUTE 단계에서 문을 실행하고 결과를 받는다.
- 커서나 핸들을 정리한다. DBMS_SQL은 커서를 열고 닫는 절차가 명시적으로 필요하다.
동적 SQL의 실행 오류는 문자열이 실행되는 시점에야 검출된다
5. 관련 법령·기준·표준
동적 SQL 자체를 규정한 법령이나 고시는 없다. 관련 기준은 DBMS 제품 문서, 개발 표준, 그리고 개인정보·보안 관련 법령이다. 여기서는 이 개념을 다루는 설계 기준과 제품 기준을 정리한다. 법령 번호를 확인하지 못한 항목은 기준 이름만 쓴다.
| 기준 | 적용 내용 | 값·조건 |
|---|---|---|
| Oracle 네이티브 동적 SQL | EXECUTE IMMEDIATE 로 PREPARE·EXECUTE 통합 | 바인드 변수는 USING 절로 전달 |
| Oracle DBMS_SQL 패키지 | 커서 단위로 파싱·바인딩·패치 제어 | 커서 열기부터 닫기까지 단계를 순서대로 호출 |
| T-SQL sp_executesql | 매개변수화된 동적 문 실행 | 입력·출력 매개변수 처리 가능 |
| 바인드 변수 사용 | 구문 재사용, 주입 방지 | 값은 문자열 결합 대신 바인드 변수로 전달 |
| 영구 테이블 DML 권한 | 동적 문 실행 주체의 권한 | 권한이 불확실하면 영구 테이블 INSERT·UPDATE·DELETE 금지 권고 |
| 응용 계층 분리 | 애플리케이션 역할·중간 계층 사용 | 직접 DB 연결 대신 중간 계층 경유 |
표의 값은 제품 문서와 개발 가이드의 일반 원칙이다. 조문 번호는 제시하지 않는다.
권한과 보안 측면에서 보면, 동적 SQL은 실행 주체가 가진 권한 범위 안에서만 작동한다. 사용자에게 테이블 직접 접근 권한이 없으면 동적 문도 실행할 수 없다. 권한이 확실하지 않으면 영구 테이블에 대한 쓰기 문은 동적으로 만들지 않는 것이 안전하다.
개인정보 측면에서는 동적 SQL에 값을 직접 이어 붙이는 방식이 SQL 주입 취약점의 원인이 된다. 바인드 변수 사용과 입력값 검증이 함께 필요하다. 개인정보를 다루는 경우에도 SQL 주입 방지에 유의한다.
6. 유형과 비교
동적 SQL은 실행 방식과 바인딩 방법에 따라 몇 가지 유형으로 나뉜다. 가장 기본적인 구분은 SQL 문장이 컴파일 시점에 고정되는지 실행 시점에 만들어지는지이며, 이를 정적 SQL과 비교하면 특성 차이가 분명해진다. 아래 표는 정적 SQL, 동적 SQL(문자열 실행), 바인드 변수를 쓴 동적 SQL을 비교한다.
| 비교 항목 | 정적 SQL | 동적 SQL(문자열 실행) | 바인드 변수 동적 SQL |
|---|---|---|---|
| 문장 확정 시점 | 컴파일 시점 | 실행 시점 | 실행 시점 |
| 문법 오류 검출 | 컴파일 시 검출 | 실행 시 검출 | 실행 시 검출 |
| 유연성 | 낮음 | 높음 | 높음 |
| 캐시 재사용 | 높음 | 낮음(문자열이 달라지면 재파싱) | 높음(바인드 변수로 동일 커서 공유) |
이어지는 내용
- 7. 장단점·한계와 개선 방향
- 8. 사례 또는 계산 예제
- 9. 최근 동향과 쟁점
- 10. 흔한 실수와 채점 포인트
- 11. 암기 정리
- 12. 답안 구성 예시
- 13. 예상 변형 문항
로그인하면 하루 2페이지까지 무료로 전체를 읽을 수 있습니다.
앱에서 이 단원 읽기