10. 프라그마(Pragma)#
개요#
프라그마(Pragma)를 사용하면 프라그마의 종류에 따라 컴파일 동작이 달라진다. 프라그마는 저장 프로시저, 저장 함수, 저장 패키지에서 사용할 수 있다.
종류#
Altibase에서 사용할 수 있는 프라그마는 아래와 같다. 각각의 프라그마에 대해서는 다음 절에서 설명한다.
-
자율 트랜잭션 프라그마(Autonomous_Transaction Pragma)
-
예외 초기화 프라그마(Exception_Init Pragma)
구문#
자율 트랜잭션 프라그마(Autonomous_Transaction Pragma)#
구문#
기능#
자율 트랜잭션 프라그마(Autonomous transaction Pragma)를 사용하면 PSM 객체가 트랜잭션 내에서 동작하는 방식을 변경할 수 있다. 자율 트랜잭션 프라그마는 PSM 객체 생성의 컴파일 시에 설정된다.
자율 트랜잭션 프라그마가 설정된 PSM 객체는 독립적으로 동작하여 주 트랜잭션과 자원을 공유하지 않는다. 따라서 락, 커밋, 복구 등의 동작이 독립적으로 수행된다. 자율 트랜잭션 프라그마는 모듈 중심 또는 재사용성이 높은 프로그램을 작성할 때 유용하다.
자율 트랜잭션 프라그마를 정의할 수 있는 위치는 아래와 같다.
-
최상위 저장 프로시저
-
최상위 저장 함수
-
최상위 저장 패키지의 서브 프로그램
-
트리거의 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]