Pro C, COMMIT/ROLLBACK
Pro C 프로그램 한개는 하나의 트랜잭션으로 실행되므로 프로그램의 끝에서는 COMMIT을 실행해야만 DB에 영구적으로 반영된다.
DDL은 한 문장단위로 트랜잭션이 자동으로 COMMIT되므로 명시적으로 COMMIT명령을 실행할 필요는 없다.
DML은 COMMIT 명령을 실행해야만 영구적으로 반영되므로 프로그램이 종료하기 전에 꼭 COMMIT명령을 실행할 필요가 있다.
DDL이 실행되기 전과 후에 자동으로 트랜잭션이 COMMIT되기 때문에 그 때까지 반영되지 않고 있던 모든 문장들이 반영되므로 주의가 필요하다.
EXEC SQL WHENEVER SQLERROR GOTO err_proc;
위와 같은 방법으로 오류발생시 특정 처리루틴으로 분기한 경우, 그 루틴의 ROLLBACK문장에서 또 오류가 발생했다면, 재귀호출과 같은 상태가 되므로 무한루프가 발생하게 된다. 그러므로 ROLLBACK문장을 실행하기 전에는 무한루프를 방지하기 위해서 다음과 같은 문장을 먼저 실행할 필요가 있다.
EXEC SQL WHENEVER SQLERROR CONTINUE;
Pro C 프로그램 한개는 하나의 트랜잭션으로 실행되므로 프로그램의 끝에서는 COMMIT을 실행해야만 DB에 영구적으로 반영된다.
DDL은 한 문장단위로 트랜잭션이 자동으로 COMMIT되므로 명시적으로 COMMIT명령을 실행할 필요는 없다.
DML은 COMMIT 명령을 실행해야만 영구적으로 반영되므로 프로그램이 종료하기 전에 꼭 COMMIT명령을 실행할 필요가 있다.
DDL이 실행되기 전과 후에 자동으로 트랜잭션이 COMMIT되기 때문에 그 때까지 반영되지 않고 있던 모든 문장들이 반영되므로 주의가 필요하다.
EXEC SQL COMMIT WORK;
EXEC SQL COMMIT WORK RELEASE; /* RELEASE는 접속해제 */
EXEC SQL ROLLBACK WORK;
EXEC SQL ROLLBACK WORK RELEASE;
EXEC SQL COMMIT WORK RELEASE; /* RELEASE는 접속해제 */
EXEC SQL ROLLBACK WORK;
EXEC SQL ROLLBACK WORK RELEASE;
EXEC SQL WHENEVER SQLERROR GOTO err_proc;
위와 같은 방법으로 오류발생시 특정 처리루틴으로 분기한 경우, 그 루틴의 ROLLBACK문장에서 또 오류가 발생했다면, 재귀호출과 같은 상태가 되므로 무한루프가 발생하게 된다. 그러므로 ROLLBACK문장을 실행하기 전에는 무한루프를 방지하기 위해서 다음과 같은 문장을 먼저 실행할 필요가 있다.
EXEC SQL WHENEVER SQLERROR CONTINUE;
lEXEC SQL WHENEVER SQLERROR CONTINUE;
위의 문장은 SQLERROR가 발생해도 대응치 않고 그냥 다음을 실행하라는 의미이다.
오류발생시 오류메시지를 출력하고 ROLLBACK을 실행한 후에 프로그램을 종료하는 예
위의 문장은 SQLERROR가 발생해도 대응치 않고 그냥 다음을 실행하라는 의미이다.
오류발생시 오류메시지를 출력하고 ROLLBACK을 실행한 후에 프로그램을 종료하는 예
#include <stdio.h>
#include "sqlca.h"
#include "sqlca.h"
int main(void) {
EXEC SQL BEGIN DECLARE SECTION;
char *connstr = "scott/ojtit@orcl";
int empno;
VARCHAR job[20];
int deptno;
EXEC SQL END DECLARE SECTION;
empno = 1000;
EXEC SQL CONNECT :connstr;
if(sqlca.sqlcode == 0) {
printf("오라클 연결 성공\n");
}else{
printf("오류 : 오라클 연결 실패\n");
}
EXEC SQL WHENEVER NOT FOUND GOTO error_routine;
EXEC SQL
DELETE FROM
EMPLOYEES
WHERE
empno = :empno;
EXEC SQL COMMIT WORK;
EXEC SQL
SELECT
empno, job, deptno
INTO
:empno, :job, :deptno
FROM
EMPLOYEES
WHERE
empno = :empno;
job.arr[job.len] = '\0';
printf("empno=%d, job=%s, deptno=%d \n", empno, job.arr, deptno);
printf("프로그램 종료\n");
return 0;
error_routine:
char *connstr = "scott/ojtit@orcl";
int empno;
VARCHAR job[20];
int deptno;
EXEC SQL END DECLARE SECTION;
empno = 1000;
EXEC SQL CONNECT :connstr;
if(sqlca.sqlcode == 0) {
printf("오라클 연결 성공\n");
}else{
printf("오류 : 오라클 연결 실패\n");
}
EXEC SQL WHENEVER NOT FOUND GOTO error_routine;
EXEC SQL
DELETE FROM
EMPLOYEES
WHERE
empno = :empno;
EXEC SQL COMMIT WORK;
EXEC SQL
SELECT
empno, job, deptno
INTO
:empno, :job, :deptno
FROM
EMPLOYEES
WHERE
empno = :empno;
job.arr[job.len] = '\0';
printf("empno=%d, job=%s, deptno=%d \n", empno, job.arr, deptno);
printf("프로그램 종료\n");
return 0;
error_routine:
sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml] = '\0';
printf("오류코드=%d, 오류메시지=%s \n",
sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
EXEC SQL ROLLBACK WORK RELEASE;
return 1;
}
printf("오류코드=%d, 오류메시지=%s \n",
sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
EXEC SQL ROLLBACK WORK RELEASE;
return 1;
}