V9.7에서 소개된 개념으로 FixPack5에서 약간 기능(locking 처리)  개선되어진 것으로 알고 있다.

이 기능이 업무 단에 실질적으로 적용될 가능성은 없을 것 같지만, 개발자 측면에서는 편의성을 제공해 주는 기능이 아닐까 싶다.

routine 을 프로그래밍 하면서, 함수나 저장 프로시저(stored procedure)의 로직 검증을 하기 위해 매번 삭제하고 컴파일하여 db에 반영(deploy)하는 작업을 거쳐야 한다. 어떤 면에서는 불필요하게 반영(deploy)하는 것을 꼭 해야하나? 하는 의문이 들 것이다.

특히 운영 시스템에 routine들을 적용해야 하는 시점에서 검증을 하기 위해 컴파일해서 반영(deploy)하는 것도 때로는 부담이 되고 번거롭게 하는 과정일 수도 있을 것이다.

이렇게 db에 반영하지 않고 로직 compile하여 실행시키는 일련의 작업만 하도록 제공하는 것이 “익명 블록”이다. PLSQL이나 SQLPL 작업 시 로직 검증은 편하게 할 수 있는 방법이 되지 않을까 싶다.

이 테스트는 DB2_COMPATIBILITY_VECTOR=ORA 적용하고 수행되었다.

익명 블록 코드 예 - 3번 반복하면서 시간소 및 반복 회수를 도출하는 로직

db2 +p -td@ -v <<EOF
connect to sample @
set serveroutput on @

declare
    ret_val integer ;
    ret_time timestamp;
   
begin
      for k in 1..3 loop
          select k, current timestamp into ret_val, ret_time from dual;
          dbms_output.put_line('count number: ' || ret_val);
          dbms_output.put_line('loop time: ' || ret_time) ;
      end loop ;
end;
@
set serveroutput off @
terminate @
EOF

 

실행 결과

블록을 컴파일하면 컴파일과 동시에 실행이 되어 진다. 로직에 대한 논리적인 이름(껍데기?)을 갖고 있지 못하기에 당연한 결과일 수 있을 것이다.

connect to sample
 
   Database Connection Information
 
Database server        = DB2/LINUXX8664 9.7.4
SQL authorization ID   = ORA974
Local database alias   = SAMPLE
 
 
set serveroutput on
DB20000I  The SET SERVEROUTPUT command completed successfully.
 
declare ret_val integer ; ret_time timestamp; begin for k in 1..3 loop select k, current timestamp into ret_val, ret_time from dual; dbms_output.put_line('count number: ' || ret_val); dbms_output.put_line('loop time: ' || ret_time) ; end loop ; end;
DB20000I  The SQL command completed successfully.
 
count number: 1
loop time: 2011-10-31-00.03.21.099553
count number: 2
loop time: 2011-10-31-00.03.21.124113
count number: 3
loop time: 2011-10-31-00.03.21.124266
 
set serveroutput off
DB20000I  The SET SERVEROUTPUT command completed successfully.
 
terminate
DB20000I  The TERMINATE command completed successfully.

DB2 V9.7 FixPack3 에서 도입된 기능이다.

저장 프로시저(Stored Procedure) 내부에서 호출되는 저장 프로시저의 트랜잭션 처리를 “호출한 저장 프로시저 트랜잭션 상태”와 상관없이 DB에 반영(commit)할 수 있게 하는 기능이다.

다른 DBMS에서는 어떤 용도로 사용되는지 찾아보질 않아 모르겠지만, 곰곰이 생각해 보면 업무적으로 “특수한 요건”일 때 적용이 될 법하고, 이외는 “호출한/호출당한 저장 프로시저”의 트랜잭션 수행 기록을 남기는 용도로 사용할 수도 있지 않나 싶다.

먼가 중요한 처리를 담당하는 “저장 프로시저”인 경우, 이 저장 프로시저가 수행될 때 마다 처리한 트랜잭션들을 기록하도록 하기 위해 (commit 이던 rollback이던) “자율 트랜잭션”을 사용할 필요가 있지 않을까 하는 생각을 해본다.

테스트는 오라클 호환 벡터를 설정하고 테스트를 하였다.(오라클 관련 호환성 기능 테스트를 병행하고 있었기에..)  (DB2_COMPATIBILITY_VECTOR=ORA)

호출되는 내부 저장 프로시저 생성

db2 +p -td"@" -v << EOF
connect to sample @
drop table t1 @
create table t1(c1 timestamp) @
create or replace procedure sp2()
language sql
autonomous
begin
      insert into t1 values (current timestamp) ;
end
@
terminate @
EOF

선언부에 “Autonomous”를 명시한다.

 

호스트 저장 프로시저 생성

db2 +p -td"@" -v << EOF
connect to sample @
drop table t3@
create table t3 (c1 timestamp)@
create or replace procedure sp3()
begin
       insert into t3 values (current timestamp) ;
       call sp2();
end
@
terminate @
EOF

프로시저 sp2를 auto commit를 해제하고 수행 후, rollback을 수행함으로써 autonomous가 적용되었는지를 확인한다.

저장 프로시저 실행

$ db2 +c "call sp3()"

  Return Status = 0


$ db2 rollback

DB20000I  The SQL command completed successfully.

 

SP3프로시저의 수행 결과 확인

$ db2 "select * from t3"

C1
--------------------------

  0 record(s) selected.

SP2 프로시저의 수행 결과 확인

$ db2 "select * from t1"

C1
--------------------------
2011-10-17-17.46.39.148931

  1 record(s) selected.

+ Recent posts