PL/SQL - 동적 SQL
동적 SQL이란?
실행 시점 , 즉 런타임에 SQL문장이 달라지는 경우로 대표적으로 검색시, WHERE 절이 동적으로 추가되는 예시가 있다.
그 외에도 PL/SQL 블록 내에서 DDL 문을 실행하는 경우, 또는 PL/SQL 블록 내에서 ALTER SYSTEM/SESSION 명령어를 실행하여 세션별 파라미터 (ex) NLS_LANG : 언어 정보) 를 설정하는 경우에도 동적 SQL을 사용할 수 있다.
PL/SQL에서 동적 SQL을 처리하는 방법은 2가지가 있다. 두 방법 모두 SQL문장 자체를 문자열 형태로 조합하여 실행한다.
- Native Dynamic SQL (원시동적 SQL , NDS)
- DBMS_SQL 시스템 패키지
NDS
EXECUTE IMMEDIATE 문 : 가장 기본적인 동적 SQL 실행 형태이다.
구문은 다음과 같이 사용한다. INTO 다음에 결과값을 매핑할 OUT변수 , 동적으로 Binding 될 매개변수를 USING 절에 명시한다.
1 | EXECUTE IMMEDIATE 'SQL문자열' |
EXECUTE IMMEDIATE 실행 예제
1 | DECLARE |
Bind 변수
Bind 변수를 사용하여 조건문을 런타임에 만들 수 있다.
상수를 사용하는 경우에는 오라클이 매번 실행 계획을 세운다. 만약 Bind 변수를 사용하는 경우에는 sql 구문이 변경되지 않으므로, 이전에 세웠던 실행 계획을 활용해 처리한다. 즉 성능적으로 더 빨라진다. 따라서 항상 Bind 변수를 사용하는게 좋다.
일반 SQL문에서는 순서와 타입으로만 매핑된다. 즉 이름은 가독성에만 영향을 끼치고 실제 실행은 USING절에 오는 순서와, 타입 기반으로 실행된다. ( 프로시저로 매핑할떄는 변수 이름까지 맞춰주어야 한다. )
1 | WHERE test_condition1 = :바인드변수명1 |
- 프로시저안에서 DDL문 실행은 불가능하지만, 동적 SQL을 사용하면 실행이 가능하다. (ALTER SESSION 명령문과 같이 세션 파라미터를 변경하고자 할때도 마찬가지이다. )
OPEN FOR문을 통한 다중 로우 처리
- SELECT ~ INTO 를 통해 단일 로우 반환시에 프로시저내 변수에 매핑할 수 있었다. 만약 한 개 이상의 로우를 결과 집합으로 반환하는 SELECT문은 OPEN FOR문을 통해 커서 변수에 결과 값을 받아올 수 있다.
1 | OPEN 커서변수 FOR 동적_SQL문장 |
아래와 같이 예시를 보면 동적 SQL을 커서변수에 매핑할 수 있다.
1 | DECLARE |
만약 bind 변수를 사용하고자 할때는 OPEN 커서변수 FOR 동적SQL USING BIND 변수
형태로 사용 가능하다.
1 | vs_sql := 'SELECT * FROM test WHERE ID > :a AND NAME LIKE :b'; |
BULK COLLECT INTO 절을 사용한 다중 로우 처리
- 일일히 한 로우씩 읽는 방식에 비해 한꺼번에 집합적으로 처리가 가능하여, 성능면에서 더 우수하다.
1 | DECLARE |
BULK COLLECT INTO 절은 마찬가지로 동적 SQL문에서도 사용이 가능한데,EXECUTE IMMEDATE 동적쿼리문 BULK COLLECT INTO 중첩테이블변수 USING bind변수
형태로 사용이 가능하다.