Skip to content
튜닝 연습PL/SQL과 사용자 정의 함수
PLSQL-029

보안 점검에서 주문 상태 변경 API로 주문 금액까지 0원으로 바꿀 수 있었다

기초PLSQL한빛유통679 / 700

상황 ​

고객센터와 쇼핑몰 관리 화면은 주문 상태를 바꿀 때 프로시저 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 NUMBER
  • 상태 변경은 하루 약 12,000번이고, 한 번에 주문 한 건을 고친다
  • CURSOR_SHARING = EXACT · 통계 최신

원본 SQL ​

sql
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;

실행계획 학습용 예시 ​

xplan
[보안 점검 때 실제로 실행된 문장 (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는 없다)

문제 ​

  1. 상태 값 하나로 주문 금액까지 바뀐 이유를 실행된 문장으로 설명하시오. 같은 모양의 문장이 하루 1만 개 넘게 생긴 이유도 쓰시오.
  2. 프로시저를 고치시오. 동적 SQL이 필요한 경우와 필요 없는 경우를 가려 쓰고, 고친 판이 보안 말고도 무엇을 얻는지 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자