내포된 SQL (Embeded SQL)

  • 호스트 언어에 포함되는 SQL
  • SQL이 호스트 언어(고급 프로그래밍 언어)의 완전한 표현력을 갖고 있지 않기 때문에 모든 질의를 SQL로 표현할 수는 없다.
  • SQL은 호스트 언어가 갖고 있는 조건문, 반복문, 입출력 등과 같은 동작, 사용자와의 상호 작용, 질의 결과를 GUI로 보내는 등의 기능을 갖고 있지 않다.
  • C, C++, 자바 등의 언어로 작성하는 프로그램에 SQL 문을 삽입하여, 데이터베이스를 접근하는 부분에 대해 SQL에 없는 기능은 호스트 언어로 작성할 필요가 있다.
  • 데이터 구조가 불일치하는 문제(Impedance Mismatch)가 발생
  • ESQL/C : MSSQL SERVER 2005에서 C언어에 SQL문을 내포시키는 환경
  • 호스트 언어로 작성 중인 프로그램에 SQL문을 내포시킬 때 해당 호스트 언어의 컴파일러가 호스트 언어의 구문과 SQL문을 구별하는 방법 : 호스트 언어로 작성 중인 프로그램에 포함된 모든 SQL문에는 반드시 문장의 앞부분에 EXEC SQL을 붙인다.
  • EXEC SQLEXEC SQL부터 세미콜론(;) 사이에 들어 있는 문장이 내포된 SQL문임을 전컴파일러에게 알린다.
  • 전컴파일러(precompiler) : 코드에서 SQL문만 찾아서 번역하는 컴파일러
  • ESQL/C 전컴파일러는 내포된 SQL문을 C 컴파일러에서 허용되는 함수 호출로 변환한다.
  • 내포된 SQL문의 컴파일 과정

편집기 호스트 언어 + 내포된 SQL 전컴파일러 호스트 언어 + 함수 호출문 호스트 언어 컴파일러

오브젝트 프로그램 링커(DBMS가 제공하는 SQL라이브러리) 실행 프로그램

 


  ESQL/C

  • 정적인 SQL문과 동적인 SQL문 모드를 지원한다.
  • 정적인 SQL문은 C 프로그램에 내포된 완전한 Transact-SQL
  • 동적인 SQL문은 불완전한 Transact-SQL문으로서 일부 또는 전부를 질의가 수행될 때 입력가능하다.
  • 정적인 SQL문은 입력값과 출력 데이터를 위해서 C 프로그램의 변수들을 포함할 수 있다.
  • 호스트 변수(Host Variable) : SQL문에 포함된 C 프로그램의 변수
  • 호스트 변수를 사용할 때는 앞에 항상 콜론(:)이 붙는다.

#include <stdio.h>


int main() {

// 공유 변수 선언

EXEC SQL BEGIN DECLARE SECTION;

char name[10];

char title[10];

EXEC SQL END DECLARE SECTION;


// company 라는 DB에 kim 이라는 사용자로 접속

EXEC SQL CONNECT TO company USER kim;


printf("type employee's name : ");

gets(name);


// :title 과 :name 은 호스트 변수이다.

EXEC SQL 

SELECT title INTO :title FROM employee WHERE empname = :name;


printf("Employee's title is %s.", title);


return 0;

}


 


  불일치 문제와 커서

  • 호스트 언어는 단일 변수/레코드 위주의 처리(투플 위주의 방식)를 지원하는 반면에 SQL은 데이터 레코드들의 처리(집합 위주의 방식)를 지원하기 때문에 데이터 개수의 불일치 문제가 발생한다.
  • 커서(Cursor) : 불일치 문제의 해결책으로, 한 번에 한 투플씩 가져오는 수단
  • DECLARE CURSOR문을 사용하여 커서를 정의한다.
  • OPEN cursor 문은 질의를 수행하고, 질의 수행 결과의 첫 번째 투플 이전을 커서가 가리키도록 한다. 커서가 가리키는 투플이 현재 투플이다.
  • 그 다음에 FETCH문은 커서를 다음 투플로 이동하고, 그 투플의 애트리뷰트 값들을 FETCH문에 명시된 호스트 변수들에 복사한다.
  • CLOSE cursor문은 커서를 닫는다.
  • 정적인 커서 예시

EXEC SQL BEGIN DECLARE SECTION;

char name[10] = “박영창”;

char title[10];

EXEC SQL END DECLARE SECTION;

EXEC SQL

DECLARE title_cursor CURSOR FOR // 커서 정의


SELECT TITLE FROM EMPLOYEE WHERE EMPNAME = :name;


EXEC SQL OPEN title_cursor; // 질의 실행


EXEC SQL FETCH title_cursor INTO :title; // 결과를 호스트 변수(title)에 저장


  • 만일 갱신할 투플들에 대해 커서를 정의할 때는 커서 선언부에 FOR UPDATE OF절을 반드시 포함시키고, 수정할 애트리뷰트들을 함께 명시해야 한다.

EXEC SQL


DECLARE title_cursor CURSOR FOR


SELECT title FROM employee FOR UPDATE OF title;

UPDATE employee SET title = :newtitle WHERE CURRENT OF title_cursor;


// where current of : ‘현재 투플에 대해서’ 라는 의미를 가진다.




  SQL 통신 영역 (SQL Communication Area, SQLCA)

  • C 프로그램에 내포된 SQL문에 발생하는 에러들을 사용자에게 알려준다.
  • 사용자는 SQLCA 데이터 구조의 에러 필드와 상태 표시자를 검사하여 내포된 SQL문이 성공적으로 수행되었는지의 여부를 파악할 수 있다.
  • SQLCA 데이터 구조 중에서 가장 중요하고 많이 사용되는 필드는 SQLCODE 변수이다.
  • SQLCODE 의 값이 0이면 마지막에 내포된 SQL문이 성공적으로 끝났음을 의미한다.

EXEC SQL

DECLARE c1 CURSOR FOR

SELECT empno, empname, title, manager, salary, dno FROM employee;

 

EXEC SQL OPEN c1;


// 커서가 가리킬 게 없으면 SQLCODE 는 1을 반환하고 질의는 종료된다.

while (SQLCODE == 0) {

EXEC SQL


// 커서가 투플을 하나씩 가리키므로 커서 이동할 때마다 호스트 변수에 저장한다.

FETCH c1 INTO :eno, :name, :title, :manager, :salary, :dno;

if (SQLCODE == 0)

printf(“%4d %12s %12s %4d %8d %2d”, eno, name, title, manager, salary, dno);

}

EXEC SQL CLOSE c1;





+ Recent posts