본문 바로가기
왕푸짐 이벤트

[이벤트 둘!/정답 및 당첨자 발표] 당신의 오라클 내공을 보여주세요!

by EXEM 2010. 10. 5.

Oracle ACE "Dion Cho" 가 직접 출제하는 주옥같은 문제!
당신의 오라클 내공 보여주세요
가장 좋은 정답을 제출한 분께
5만원 상품권을 드립니다

지금 바로 도전하세요~!                                  지난달 당첨자 및 정답 발표

다음과 같이 테이블 T1을 만들고, Unique 인덱스 T1_N1을 만듭니다.
SQL> create table t1  2  as  3  select level as c1, level as c2  4  from dual  5  connect by level <= 1000;Table created.SQL> create unique index t1_n1 on t1(c1);Index created.
그리고 다음과 같은 작업을 수행합니다.
SQL> { Unique 인덱스 T1_n1을 경유해 테이블 T1을 업데이트하는 어떤 작업 };
위에서 수행한 작업에 대해 TKPROF 리포트를 만들면 다음과 같은 결과가 나옵니다.
UPDATE T1 SET C2 = :B1 +1WHERE C1 = :B2call     count       cpu    elapsed       disk      query    current      rows------- ------  -------- ---------- ---------- ---------- ----------  --------Parse        1      0.00       0.00          0          0          0         0Execute      1      0.03       0.03          0       1011       1022      1000Fetch        0      0.00       0.00          0          0          0         0------- ------  -------- ---------- ---------- ---------- ----------  --------total        2      0.03       0.03          0       1011       1022      1000
위의 결과를 보면 UPDATE 문은 분명히 한번(Execute=1) 수행되었지만 총 1,000건(rows=1000)이 변경된 것으로 보고되고 있습니다. 어떻게 이것이 가능할까요?

{ Unique 인덱스 T1_n1을 경유해 테이블 T1을 업데이트하는 어떤 작업 }에 가장 알맞은 코드를 작성해서 보내주시는 것이 이번 퀴즈의 문제입니다. 단, 실제로 동작하는 코드라는 것을 확인하기 위해서 반드시 SQL*Plus의 SPOOL 결과를 보내주신 경우에만 정답으로 인정하겠습니다.

정답발표

정답제출: quiz@ex-em.com

정답자 발표 : 2010년 10월 5일 화요일 오후 2시
--------------------------------------------------------------------
퀴즈 정답 접수가 마감되었습니다. 

<퀴즈 당첨자>

구**  sa***@gmail.com


많은 분들이 정답을 보내주셨습니다~
참여해주신 모든 분들께 진심으로 감사드립니다. 
정답이 아래에 공개됩니다!  


<퀴즈 정답> 

이번 달은 문제가 조금 애매했던 관계로 도전자가 조금 적었습니다. 하지만 출제자의 의도를 완벽하게 파악해서 답변을 제시해주신 분이 있습니다.

이번 문제의 정답은 배치 DML입니다. 아래와 같이 FORALL 구문을 이용해서 UPDATE 문을 수행합니다.

SQL> ALTER SESSION SET SQL_TRACE = TRUE;

세션이 변경되었습니다.

SQL> DECLARE
  2  
  3  CURSOR CUR IS
  4  SELECT C1 FROM HSKOO.T1;
  5  
  6  TYPE T1_C1 IS TABLE OF HSKOO.T1.C1%TYPE;
  7  
  8  T1_C1S T1_C1;
  9  
 10  BEGIN
 11      OPEN CUR;
 12      FETCH CUR BULK COLLECT INTO T1_C1S;
 13      CLOSE CUR;
 14  
 15      FORALL X IN T1_C1S.FIRST..T1_C1S.LAST
 16      UPDATE HSKOO.T1
 17         SET C2 = T1_C1S(X) + 1
 18       WHERE C1 = T1_C1S(X);
 19  
 20  END;
 21  /

PL/SQL 처리가 정상적으로 완료되었습니다.

SQL> SPOOL OFF
FORALL 구문을 사용하면 오라클은 내부적으로 배열 프로세싱(Array Processing)을 사용합니다. 따라서 아래와 같이 단 한건만 UPDATE하는 구문임에도 불구하고 한번 실행에서 여러 개(여기서는 1,000개)의 로우를 한번에 UPDATE하는 것으로 보고되는 것입니다.
UPDATE HSKOO.T1 SET C2 = :B1 + 1 
WHERE
 C1 = :B2 


call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.06       0.36          0       1002       1024        1000
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      0.06       0.36          0       1002       1024        1000

 

정답을 맞추신 분께 다시 한번 축하말씀드리며, 다음 번에 보다 단순하면서도 재미있는 문제를 준비하도록 하겠습니다. 참여해 주신 모든 분께 감사드립니다.^^

댓글