행위

Literal sql 개선방법

DB CAFE

thumb_up 추천메뉴 바로가기


1 LITERAL SQL 개선 방법[편집]

1.1 PL/SQL[편집]

1.1.1 UPDATE문 개선 방법[편집]

  1. SQL 문자열의 바인딩 할 곳에 PLACEHOLDER(:)와 식별이 가능한 임의의 문자를 결합하여 기입
  2. USING절에 바인딩 할 값을 (:) 순서에 맞게 기입
※ 참고 : PLACEHOLDER와 USING절 변수 개수는 반드시 동일해야함


DECLARE

  V_ENAME EMP.ENAME%TYPE DEFAULT 'DBCAFE'; -- VARCHAR2(10)
  V_EMPNO EMP.EMPNO%TYPE DEFAULT 7369; -- NUMBER(4)
  V_MGR   EMP.MGR%TYPE   DEFAULT 7902; -- NUMBER(4)

BEGIN

  EXECUTE IMMEDIATE 'UPDATE EMP 
 		        SET ENAME = :ENAME
              	      WHERE EMPNO = :EMPNO
             		AND MGR = :MGR
                        AND ROWNUM <= 1'
              USING V_ENAME, V_EMPNO, V_MGR;
          
  DBMS_OUTPUT.PUT_LINE ( 'UPDATE CNT : ' || SQL%ROWCOUNT );        
    
  COMMIT;      

END;

1.1.2 SELECT문 개선 방법[편집]

[ 처리 방법 ]
 1. SQL 문자열의 바인딩 할 곳에 PLACEHOLDER(:)와 식별이 가능한 임의의 문자를 결합하여 기입
 2. USING절에 바인딩 할 값을 (:) 순서에 맞게 기입
 ※ 참고 : PLACEHOLDER와 USING절 변수 개수는 반드시 동일해야함

DECLARE

  V_EMPNO EMP.EMPNO%TYPE DEFAULT 7369; -- NUMBER(4)
  V_MGR   EMP.MGR%TYPE   DEFAULT 7902; -- NUMBER(4)
  R_EMPNO EMP.EMPNO%TYPE; -- NUMBER(4)
  R_ENAME EMP.ENAME%TYPE; -- VARCHAR2(10)
  
BEGIN

  EXECUTE IMMEDIATE 'SELECT EMPNO
                          , ENAME
                       FROM EMP
                      WHERE EMPNO = :EMPNO
                        AND MGR = :MGR
                        AND ROWNUM <=1'
               INTO R_EMPNO, R_ENAME
              USING V_EMPNO, V_MGR;
                     
  DBMS_OUTPUT.PUT_LINE ( 'R_EMPNO CNT : ' || R_EMPNO );                        
  DBMS_OUTPUT.PUT_LINE ( 'R_ENAME CNT : ' || R_ENAME );                         

END;

1.2 IBATIS / MYBATIS[편집]

1.2.1 BINDING 처리된 경우[편집]

[ Literal Sql 개선 방법 ]
 IBATIS : #EMPNO#, MYBATIS : #{EMPNO} 사용하기

[ 정보 공유 ]
 JDBC의 PreparedStatement 객체 이용과 동일함
 SQL INJECTION 예방

<select id="emp_select" resultType="String" parameterType="Map">

    SELECT EMPNO, ENAME
     FROM  EMP
    WHERE EMPNO = #{empno}

</select>

1.2.2 BINDING 미처리 된 경우[편집]

[ Literal Sql 발생 이유 ]
 IBATIS : $EMPNO$, MYBATIS : ${EMPNO} 사용한 경우 

[ 정보 공유 ]
 1. JDBC의 Statement 객체 이용과 동일함
 2. SQL INJECTION 노출
 3. 하드파싱이므로 바인딩 처리한 SQL보다 Parsing Time 긺
 4. DB Shared Pool의 Library Cache영역에 불필요한 자원이 등록됨

<select id="emp_select" parameterType="HashMap" resultType="HashMap">

     SELECT EMPNO, ENAME
       FROM  EMP
      WHERE EMPNO = ${empno}

</select>