WITH 문WITH 문CTE(Common Table Expressions)를 정의하기 위한 구문으로 서브쿼리를 재사용 가능하고 가독성 높게 작성할 수 있도록 지원한다.
복잡한 SQL 쿼리를 읽기 쉽고 관리 가능하게 구조화하며, 동일한 서브쿼리를 반복적으로 재작정 하지 않아도 된다. 재귀 쿼리 작성 시 활용된다.
WITH DepartmentSalary AS (
SELECT DEPARTMENT_ID, ROUND(AVG(SALARY), 2) AS AVG_SALARY
FROM EMPLOYEES
GROUP BY DEPARTMENT_ID
ORDER BY DEPARTMENT_ID NULLS LAST
)
SELECT *
FROM DepartmentSalary
WHERE AVG_SALARY > 5000;
WITH CTE1 AS (
SELECT ...
),
CTE2 AS (
SELECT ...
FROM CTE1
)
SELECT ...
FROM CTE2;
WITH NUMBERS (NUM) AS (
SELECT 1 AS NUM
FROM DUAL
UNION ALL
SELECT NUM + 1 AS NUM
FROM NUMBERS
WHERE NUM < 10
)
SELECT B.NUM
FROM NUMBERS B;
WITH 문 사용 시 유의사항ORDER BY, GROUP BY, DISTINCT 등)에서 메모리(PGA)를 다 사용하면 Temp Tablespace 데이터를 기록.SORT(GROUP BY), SORT(ORDER BY), SORT(UNIQUE)와 같은 키워드로 나타남.HASH JOIN, HASH GROUP BY 등으로 표시.SQL로 요청한 데이터를 어떻게 꺼내 올 것인가에 대한 Plan이다. 성능 병목 현상을 파악하는 데 유용하다.
높은 확률로 Optimizer가 결정한 실행 계획이 최선인 경우가 많으며, 이따금씩 Optimizer의 실행 계획이 잘못되었다 판단될 경우 적절한 Hint를 사용하여 튜닝한다.
DBMS_XPLAN 패키지를 사용하여 실행 계획을 읽기 쉽게 출력한다.
EXPLAIN PLAN FOR
SELECT * FROM employees;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(NULL, NULL, 'ALLSTATS LAST'));
Operation : 작업 유형.Name : 테이블 또는 인덱스 이름.E-Rows : 옵티마이저가 예측한 row 수.A-Rows : 실제로 처리된 row 수.Buffers : 해당 단게에서 I/O한 Block 수.들여쓰기가 많이 들어간
Id순으로 읽는다.
TABLE ACCESS FULLTABLE ACCESS BY INDEX ROWIDINDEX RANGE SCANBETWEEN, >=, <= 등)에 따라 인덱스를 검색하는 작업.INDEX UNIQUE SCANNESTED LOOPSHASH JOINSORT AGGREGATEGROUP BY 없이 집계 함수가 실행될 때 사용.SORT GROUP BYGROUP BY 조건을 처리하기 위해 데이터를 정렬하는 작업.SORT ORDER BYHASH GROUP BYSORT GROUP BY보다 효율적.VIEW PUSHED PREDICATEMATERIALIZEWINDOW SORT사용자가 특정 작업을 수행하기 위해 정의한 PL/SQL 코드 블록이다. 반복적인 작업을 자동화하고 코드 재사용성을 높이기 위해 사용하며, 주로 입력 값을 받아 처리 후 결과를 반환한다.
사용자 정의 함수의 특징으로는 다음과 같다.
사용자 정의 함수의 구성 요소로는 다음과 같다.
사용자 정의 함수 작성 팁
- 명확하고 간결한 함수 이름 사용.
- 함수는 단일 작업에 집중.
- 매개변수와 반환값에 대한 데이터 타입 명확히 지정.
EXCEPTION블록으로 오류 처리 강화.
CREATE OR REPLACE FUNCTION 함수이름 (매개변수 IN 데이터타입)
RETURN 반환타입 IS
BEGIN
-- 작업 수행
RETURN 결과값;
END;
-- 사용자 정의 함수 예시
CREATE OR REPLACE FUNCTION get_discount_price (price IN NUMBER)
RETURN NUMBER IS
BEGIN
RETURN price * 0.9;
END;
-- SQL 문에서 호출
SELECT get_discount_price(1000) AS discounted_price
FROM dual;
-- PL/SQL 블록에서 호출
DECLARE
discounted_price NUMBER;
BEGIN
discounted_price := get_discount_price(1000);
DBMS_OUTPUT.PUT_LINE('할인가:' || discounted_price);
END;
사용자 정의 함수가 너무 느릴 경우, 스칼라 서브쿼리를 통해 캐싱 기능을 이용한다.
SELECT ( SELECT get_discount_price(1000) FROM dual ) FROM DUAL;
사용자 정의 함수에서 오류가 발생하면 EXCEPTION 구문으로 처리가 가능하다.
CREATE OR REPLACE FUNCTION 함수이름 (매개변수 IN 데이터타입)
RETURN 반환타입 IS
BEGIN
-- 작업 수행
RETURN 결과값;
EXCEPTION
-- 오류 처리
RETURN 결과값;
END;
-- 변경
CREATE OR REPLACE FUNCTION 함수이름 ...;
-- 삭제
DROP FUNCTION 함수이름;
-- AS OF TIMESTAMP 절을 사용하여 5분 전 데이터를 조회
-- 이 데이터를 기반으로 복구 작업 수행
SELECT *
FROM employees
AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '5' MINUTE);
공격자가 입력 필드나 URL에 악의적인 SQL 코드를 삽입하여 데이터베이스를 조작하는 공격 기법이다. 주로 민감한 데이터 유출, 데이터 변경, 시스템 권한 탈취가 목적이다.