콘텐츠로 이동

10. 프라그마(Pragma)#

개요#

프라그마(Pragma)를 사용하면 프라그마의 종류에 따라 컴파일 동작이 달라진다. 프라그마는 저장 프로시저, 저장 함수, 저장 패키지에서 사용할 수 있다.

종류#

Altibase에서 사용할 수 있는 프라그마는 아래와 같다. 각각의 프라그마에 대해서는 다음 절에서 설명한다.

  • 자율 트랜잭션 프라그마(Autonomous_Transaction Pragma)

  • 예외 초기화 프라그마(Exception_Init Pragma)

구문#

자율 트랜잭션 프라그마(Autonomous_Transaction Pragma)#

구문#

autonomous_pragma

기능#

자율 트랜잭션 프라그마(Autonomous transaction Pragma)를 사용하면 PSM 객체가 트랜잭션 내에서 동작하는 방식을 변경할 수 있다. 자율 트랜잭션 프라그마는 PSM 객체 생성의 컴파일 시에 설정된다.

자율 트랜잭션 프라그마가 설정된 PSM 객체는 독립적으로 동작하여 주 트랜잭션과 자원을 공유하지 않는다. 따라서 락, 커밋, 복구 등의 동작이 독립적으로 수행된다. 자율 트랜잭션 프라그마는 모듈 중심 또는 재사용성이 높은 프로그램을 작성할 때 유용하다.

autonomous_pragma_overview

자율 트랜잭션 프라그마를 정의할 수 있는 위치는 아래와 같다.

  • 최상위 저장 프로시저

  • 최상위 저장 함수

  • 최상위 저장 패키지의 서브 프로그램

  • 트리거의 psm_body

자율 트랜잭션과 중첩 트랜잭션의 차이는 아래와 같다.

자율 트랜잭션 중첩 트랜잭션
예외처리 트랜잭션 단위의 예외처리 (자율 트랜잭션에서 오류 발생시 트랜잭션 수준의 복구) 문장 단위의 예외처리
트랜잭션 의존성 독립적인 트랜잭션 연관성 있는 트랜잭션과 의존적
가시성 자율 트랜잭션 종료 시에 다른 세션에서 상태 확인 가능. 중첩 트랜잭션의 종료 후에도 commit 수행이 되지 않았다면 다른 세션에서 확인 불가능
자원 공유 여부 다른 트랜잭션과 자원을 공유하지 않음 (lock, savepoint , rollback , commit은 독립적으로 동작) 연관성이 있는 트랜잭션과 자원 공유 (lock, savepoint , rollback , commit은 의존적으로 동작)

주의사항#

자율 트랜잭션은 주 트랜잭션과 잠금, 자원 사용, 커밋 종속성 여부를 공유하지 않으므로 주 트랜잭션이 복구(rollback)되더라도 자율 트랜잭션이 수행된 내용이 복구(rollback)되지 않는다.

자율 트랜잭션은 주 트랜잭션과 별도로 동작하기 때문에 주 트랜잭션에서 참조 중인 객체에 접근할 때 교착상태 (deadlock)에 빠질 수 있다.

예제#

저장 프로시저에서 pragma autonomous_transaction 선언#

iSQL> create table t1(c1 integer);
Create success.
iSQL> create or replace procedure proc1 as
pragma autonomous_transaction;
begin
insert into t1 values ( 1 );
commit;
end;
/
Create success.

저장 함수에서 pragma autonomous_transaction 선언#

iSQL> create table t1(c1 integer);
Create success.
iSQL> create or replace function sub2 return integer as
pragma autonomous_transaction;
begin
insert into t1 values ( 100 );
commit;
return 100;
end;
/
Create success

패키지 서브프로그램에서 pragma autonomous_transaction 선언#

iSQL> create table t1(c1 integer);
Create success.
iSQL> create or replace package pkg1 as
procedure sub1;
function sub2 return integer;
end;
/
Create success.
iSQL> create or replace package body pkg1 as
procedure sub1 as
pragma autonomous_transaction;
begin
insert into t1 values ( 1 );
commit;
end;
function sub2 return integer as
pragma autonomous_transaction;
begin
insert into t1 values ( 100 );
commit;
return 100;
end;
end;
/
Create success.

트리거에서 pragma autonomous_transaction 선언#

iSQL>create table t1( c1 integer );
Create success.
iSQL>create table t2( c1 integer );
Create success.
iSQL>insert into t1 values(1);
1 row inserted.
iSQL>create or replace trigger tri1
after insert on t1
for each row
pragma autonomous_transaction;
var1 integer;
var2 integer;
begin
var1 := 1;
select c1 into var2 from t1 where c1 = var1;
insert into t2 values( var2 + var1 );
commit;
end;
/
Create success.
iSQL>insert into t1 values ( 2 );
1 row inserted.
iSQL> select * from t1;
C1
--------------
1
2
2 rows selected.
iSQL> select * from t2;
C1
--------------
2
1 row selected.

예외 초기화 프라그마(Exception_Init Pragma)#

구문#

기능#

예외 초기화 프라그마(Exception init Pragma)는 사용자가 예외 변수를 Altibase의 에러 코드로 초기화 할 수 있는 기능이다. 사용자는 예외 핸들링의 OTHERS 핸들러를 대신하여 Altibase 에러 코드로 초기화된 예외 변수를 사용할 수 있다.

예외 초기화 프라그마를 정의할 수 있는 위치는 아래와 같다.

  • 저장 프로시저의 선언부

  • 저장 함수의 선언부

  • 저장 패키지의 선언부

  • 저장 패키지 서브프로그램의 선언부

exception_name#

초기화 할 예외 변수를 지정한다. 이 예외 변수는 프라그마와 동일한 블록에 선언되어야 한다.

error_code#

exception_name에서 설정한 예외가 발생할 때 발생하는 Altibase에러 코드 번호를 지정한다. Altibase에러 코드에 대한 자세한 정보는 Error Message Reference를 참고한다.

예제#

특정 예외가 발생#

에러 번호가 201070를 발생하는 저장 프로시저의 에러 메시지를 "Too many rows"로 초기화한다.

iSQL> create table t1(c1 integer);
Create success.
iSQL> insert into t1 values ( 1 );
1 row inserted.
iSQL> insert into t1 values ( 2 );
1 row inserted.
iSQL> select * from t1;
C1
--------------
1
2
2 rows selected.
iSQL> create or replace procedure proc1 as
v1 integer;
e1 exception;
pragma exception_init(e1, 201070 );
begin
select c1 into v1 from t1;
exception
when e1 then
println(SQLERRM);
println('catch exception');
end;
/
Create success.
iSQL> exec proc1;
Too many rows
at "SYS.PROC1", line 6
catch exception
Execute success.

위의 예제에서 예외 핸들러를 Others로 변경한 저장 프로시저#

iSQL> create table t1(c1 integer);
Create success.
iSQL> insert into t1 values ( 1 );
1 row inserted.
iSQL> insert into t1 values ( 2 );
1 row inserted.
iSQL> select * from t1;
C1
--------------
1
2
2 rows selected.
iSQL> create or replace procedure proc1 as
    v1 integer;
    e1 exception;
    begin
    select c1 into v1 from t1;
    exception
    when others then
    println(SQLERRM);
    println('catch exception');
    end;
    /
Create success.
iSQL> exec proc1;
Too many rows
at "SYS.PROC1", line 5
catch exception
Execute success.

예외변수e1에 초기화한 예외와 다른 에러가 발생한 경우#

초기화한 예외는 "Too many rows" 이며, 실제 발생한 에러는 "No data found" 이다.

iSQL> create or replace procedure proc2 as
v1 integer;
e1 exception;
pragma exception_init(e1, 201070 );
begin
select c1 into v1 from t1 where c1 = 3;
end;
/
Create success.
iSQL> exec proc2;
[ERR-3116A : No data found.
at "SYS.PROC2", line 6]