[번역] Embedded SQL - 01

Language/Pro*C 2015. 5. 20. 17:09

목 차
▣ 호스트 변수 ( Host Variables )
▣ 지시자 변수 ( Indicator Variables )
▣ 기본 SQL 문장 ( The Basic SQL Statements )
▣ The DML Returning Clause
▣ 커서 ( Cursors )
▣ 최적화 힌트 ( Optimizer Hints )
▣ CURRENT OF절 ( The CURRENT OF Clause )
▣ 커서문 ( The Cursor Statements )
▣ Non-Scrollable 커서를 사용하는 예제
▣ Scrollable 커서를 사용하는 예제

1) 호스트 변수 ( Host Variables )
오라클은 호스트변수를 프로그램에 데이터와 상태정보를 넘기는데 사용하고,
프로그램은 오라클에 데이터를 넘기는데 사용한다.

1-1) 입출력 호스트 변수
SELECT나 FETCH문의 INTO 절의 호스트 변수를 출력 호스트변수라고 한다.
그이외의 SQL문의 호스트 변수는 오라클에 값을 입력하는데 사용하므로 입력 호스트
변수라고 한다.
Attention : ORDER BY 절에 호스트 변수를 사용할 수 있다. 하지만 이것은 상수나
문자로서 간주되며 아래의 예처럼 쓰 일 수 있다.
EXEC SQL SELECT ename, empno INTO :name,:number
FROM emp ORDER BY :ord;
위의 예처럼 호스트 변수를 포함하고 있지만(:ord)여기서는 이변수를
상수로서 간주하며 설정된 값과는 관계없이 Ordering은 행해지지 않는다.

SQL키워드나 데이터베이스 오브젝트이름를 지원하기위한 입력호스트 변수로는 사용할
수 없다. 그래서 데이터선언문(DDL - ALTER,CREATE,DROP등등)에서 입력호스트변수를
사용할 수 없다. 아래의 예제에서는 DROP TABLE문이 유효하지 않은 예제를 보여주고
있다. :

char table_name[30];

printf("Table name? ");

gets(table_name);

EXEC SQL DROP TABLE :table_name; -- 호스트 변수는 유효하지 않음

데이터베이스 오브젝트 이름을 실행시에 변경할 필요가 있다면 dynamic SQL를
사용하면된다. 이에 대해서는 앞으로 다룰 "Oracle Dynamic SQL"장에서 살펴
보기로 한다.

오라클이 입력호스트변수가 있는 SQL문을 실행하기전에, 프로그램은 그들에게
값을 할당해야만 한다. 아래의 예를 보자 :

int emp_number;

char temp[20];

VARCHAR emp_name[20];
/* 입력호스트 변수를 위한 값을 얻는다 */
printf("Employee number? ");

gets(temp);

emp_number = atoi(temp);

printf("Employee name? ");

gets(emp_name.arr);

emp_name.len = strlen(emp_name.arr);

EXEC SQL INSERT INTO EMP (EMPNO, ENAME)
VALUES (:emp_number, :emp_name);

2) 지시자 변수 ( Indicator Variables )
호스트 변수에대한 결과코드를 지시자변수가 가지게 된다. 그래서 지시자 변수는
호스트 변수를 감시할수 있는것이다.
지시자변수는 입력 호스트 변수에 NULL을 할당하기위해서 사용되며, 출력호스트
변수에 잘려진 값이나 NULL을 감지하기위해서 INTO절에 사용한다.

◐ 입력시 프로그램이 지시자변수에 할당할수 있는 값의 의미






◐ 출력시 오라클이 지시자변수에 할당할수 있는 값의 의미


다음을 꼭 기억하도록 하자.
지시자 변수는 2바이트 정수로 정의 되어야만하고, SQL문장에서 콜른(:)을 앞에
붙이며 호스트변수 바로뒤에 와야한다.

2-1) NULL삽입
INSERT문에서 각컬럼이 null이되기를 원한때, 아래의 예처럼 -1로 지시자 변수를
설정한다.

set ind_comm = -1;
EXEC SQL INSERT INTO emp (empno, comm)
VALUES (:emp_number, :commission:ind_comm);

아래와같이 NULL로 하드코딩할수도 있다.

EXEC SQL INSERT INTO emp (empno, comm)
VALUES (:emp_number, NULL);

통상적으로, 아래의 예처럼 INSERT문에 NULL을 입력할 수 있다.

printf("Enter employee number or 0 if not available: ");

scanf("%d", &emp_number);

if (emp_number == 0)
ind_empnum = -1;
else
ind_empnum = 0;

EXEC SQL INSERT INTO emp (empno, sal)
VALUES (:emp_number:ind_empnum, :salary);

2-2) NULL 반환
아래의 예처럼 NULL반환값을 조작하는데 사용할 수 있다.

EXEC SQL SELECT ename, sal, comm
INTO :emp_name, :salary, :commission:ind_comm
FROM emp
WHERE empno = :emp_number;

if (ind_comm == -1)
pay = salary; /* commission is NULL; ignore it */
else
pay = salary + commission;

2-3) Test for NULLs
NULL값을 검사하기위해서 WHERE절에 지시자 변수를 아래의 예처럼 사용할 수 있다.

EXEC SQL SELECT ename, sal
INTO :emp_name, :salary
FROM emp
WHERE :commission INDICATOR :ind_comm IS NULL ...

그러나, 다른값이나 각각의 값의 NULL을 비교하기위해서 관계연산자를 사용할 수는
없다. 예를들어, 아래의 SELECT문은 COMM컬럼이 한개이상의 NULL을 포함하고 있으면
쿼리를 실패할것이다.

EXEC SQL SELECT ename, sal
INTO :emp_name, :salary
FROM emp
WHERE comm = :commission;

아래의 예제는 동일한 값을 어떻게 비교하는지 보여주고 있다.

EXEC SQL SELECT ename, sal
INTO :emp_name, :salary
FROM emp
WHERE (comm = :commission) OR ((comm IS NULL) AND
(:commission INDICATOR :ind_comm IS NULL));


출처 - http://younbok.egloos.com/9342725

: