테마
고객센터와 쇼핑몰 관리 화면은 주문 상태를 바꿀 때 프로시저 P_SET_ORD_ST를 부른다. 지난주 외부 보안 점검에서 상태 값 칸에 CANCEL', ORD_AMT = '0을 넣자 주문 금액이 0원으로 바뀌었다는 지적이 나왔다.
프로시저를 짠 개발자는 "화면에서 받은 값을 SQL에 넣으려면 동적 SQL을 써야 한다고 배웠다"라고 한다. DBA는 같은 모양의 UPDATE가 공유 풀에 하루 1만 개 넘게 쌓인다는 것도 함께 알려 왔다.
T_ORD 주문: 100,000행 · 896블록 · PK_T_ORD (ORD_SEQ) · ORD_ST는 COMPLETE, PENDING, CANCEL 세 가지 · ORD_AMT NUMBERCURSOR_SHARING = EXACT · 통계 최신PROCEDURE P_SET_ORD_ST(p_ord_seq IN NUMBER, p_ord_st IN VARCHAR2) IS
BEGIN
EXECUTE IMMEDIATE 'UPDATE T_ORD SET ORD_ST = ''' || p_ord_st || ''''
|| ' WHERE ORD_SEQ = ' || p_ord_seq;
IF SQL%ROWCOUNT = 0 THEN
RAISE_APPLICATION_ERROR(-20001, '주문 없음: ' || p_ord_seq);
END IF;
END;
[보안 점검 때 실제로 실행된 문장 (V$SQL.SQL_TEXT)]
UPDATE T_ORD SET ORD_ST = 'CANCEL', ORD_AMT = '0' WHERE ORD_SEQ = 61873
[V$SQL: 이 프로시저가 만든 문장 · 하루]
SQL_TEXT 앞부분 문장 수 실행 합계 하드 파싱
UPDATE T_ORD SET ORD_ST = 'COMPLETE' WHERE ORD_SEQ = … 9,212 9,240 9,212
UPDATE T_ORD SET ORD_ST = 'CANCEL' WHERE ORD_SEQ = … 2,104 2,111 2,104
UPDATE T_ORD SET ORD_ST = 'PENDING' WHERE ORD_SEQ = … 649 649 649
합계 11,965 12,000 11,965
[TKPROF: 그중 한 문장]
call count cpu elapsed disk query current rows
------- ------ -------- ---------- ---------- ---------- ---------- ----------
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 2 1 1
Misses in library cache during parse: 1
[USER_DEPENDENCIES: P_SET_ORD_ST가 기대는 객체]
SYS.STANDARD · SYS.DBMS_STANDARD (T_ORD는 없다)