-
9.2 Embedded SQL데이터베이스 시스템 2024. 11. 20. 07:16
개요
임베디드 SQL 문장은 host language라고 불리는 다른 언어로 작성된 프로그램에 나타난다. 임베디드 SQL은 SQL을 호스트 언어 문장과 구분하기 위해 EXEC SQL 키워드로 시작하며, 그 뒤에 SQL 문과 세미콜론이 온다.
임베디드 SQL을 포함하는 프로그램은 두 단계로 컴파일된다:- 프리컴파일러(Precompiler): SQL 문을 호스트 언어 문장 및 함수 호출로 변환한다.
- 호스트 언어 컴파일러(Host Language Compiler): 호스트 언어 프로그램을 실행 가능한 프로그램으로 변환한다.
임베디드 SQL은 SQL 표준에 정의되어 있으며, C, COBOL, FORTRAN과 같은 오래된 호스트 언어에서 일반적으로 지원된다. Ex: Oracle Database의 C 구현은 Pro*C라고 한다.
임베디드 SQL은 SQL 언어 개발 직후에 개발된 초기 데이터베이스 프로그래밍 기술이며, Python이나 MySQL과 같은 최신 언어 및 데이터베이스에서는 지원되지 않는다.
SQLJ는 Java를 위해 설계된 임베디드 SQL의 변형이다. SQLJ는 표준 임베디드 SQL과 유사하지만, 구문이 Java에 맞게 조정되었다. SQLJ는 널리 지원되지 않으며, 이는 Java와 같은 객체 지향 언어가 일반적으로 임베디드 SQL 대신 API를 사용하기 때문이다.
이 섹션은 C와 Oracle Database에서의 임베디드 SQL에 대해 설명한다.1. C 프로그램은
int main()
으로 시작하며return 0;
으로 끝난다.
2.printf()
는 텍스트를 출력하는 C 문장이다.
3. 임베디드 SQL 문장은EXEC SQL
로 시작하며 세미콜론으로 끝난다.
4. 프리컴파일러는 임베디드 SQL을 C 문장과 함수 호출로 변환한다.Connections
임베디드 SQL을 포함하는 프로그램은 쿼리를 실행하기 전에 데이터베이스에 연결해야 한다. 연결은 호스트 프로그램과 데이터베이스 서버 간의 통신 링크를 말한다. 연결은 데이터베이스 위치를 식별하고 로그인 자격 증명을 제공한다. 연결이 설정되면 모든 SQL 쿼리는 지정된 데이터베이스에서 실행된다.
연결은 세 가지 임베디드 SQL 문장으로 관리된다:
CONNECT TO Database AS ConnectionName USER AccountName USING Password;
Database로 지정된 데이터베이스에 ConnectionName이라는 이름의 연결을 생성한다. Database의 구문은 컴퓨팅 시스템에 따라 다르며, 예를 들어 인터넷 주소일 수 있다.SET CONNECTION ConnectionName;
ConnectionName과 연관된 데이터베이스를 '활성' 데이터베이스로 설정한다. 이후의 임베디드 SQL 문장은 해당 데이터베이스로 전달된다.DISCONNECT ConnectionName;
연결을 종료한다. 쿼리 결과를 위한 메모리와 같은 연결과 연관된 모든 리소스가 해제된다.
호스트 프로그램은 여러 데이터베이스와 통신하기 위해 여러 연결을 생성할 수 있지만, 한 번에 하나의 연결만 활성 상태가 될 수 있다.
1.
CONNECT TO
문은 인터넷 주소 100.320.420.999에 있는 데이터베이스에 대한 연결을 생성한다.
2. FlightConnection이 활성 상태이다.
3. 이후의 쿼리는 FlightConnection 데이터베이스를 참조한다.
4. 연결이 더 이상 필요하지 않을 때, 연관된 리소스를 해제한다.Shared variables 공유 변수
공유 변수는 SQL 문에 나타나는 호스트 언어 변수이다. SELECT 문 결과는 공유 변수에 할당되어 호스트 언어에서 추가로 처리된다. 공유 변수는 BEGIN DECLARE SECTION과 END DECLARE SECTION 문 사이에 선언되어야 한다.
- 공유 변수 선언
공유 변수 선언은 호스트 언어 데이터 타입을 지정한다. 호스트 언어의 데이터 타입이 데이터베이스 데이터 타입과 항상 일치하지 않으므로, 프리컴파일러는 데이터 타입을 변환하는 코드를 생성해야 한다. 변환 문제를 최소화하기 위해 프로그래머는 공유 변수와 열의 데이터 타입을 최대한 유사하게 맞춘다. - SELECT 문에서의 사용
공유 변수는 SELECT 문에서 INTO 절에 나타난다. 공유 변수를 데이터베이스 열과 구분하기 위해 공유 변수 앞에 콜론(:)이 붙는다.
SELECT 문이 실행되면 SELECT 절에서 반환된 열 값이 INTO 절의 공유 변수에 할당된다. - 제한 사항
INTO 절은 단일 행을 반환하는 문에서만 작동한다. 문이 여러 행을 반환하면 오류가 발생한다. 여러 행을 반환하는 문은 아래에서 설명하는 커서를 사용하여 처리된다.
1. 세 개의 공유 변수가 `BEGIN DECLARE SECTION`과 `END DECLARE SECTION` 사이에 선언된다.
2. C 코드는 사용자가 항공편 번호를 입력하도록 허용하며, 입력된 번호가 공유 변수 `flight`에 할당된다.
3. 쿼리는 열 `FlightNumber`가 공유 변수 `flight`와 동일한 행을 선택한다.
4. 공유 변수 `airline`은 `AirlineName` 열의 값을 할당받고, 공유 변수 `airport`는 `AirportCode` 열의 값을 할당받는다.
5. C 코드는 SELECT 문 결과를 출력한다.Cursors 커서
커서는 결과 테이블의 개별 행을 식별하는 임베디드 SQL 변수이다. 여러 행을 반환하는 쿼리를 처리하기 위해 커서가 필요하다. 커서는 다음 네 가지 임베디드 SQL 문으로 관리된다:
DECLARE CursorName CURSOR FOR Statement;
CursorName이라는 이름의 커서를 생성하고 쿼리 Statement와 연관시킨다.OPEN CursorName;
CursorName과 연관된 쿼리를 실행하며, 커서를 결과 테이블의 첫 번째 행 앞에 위치시킨다.FETCH FROM CursorName INTO :SharedVariable1, :SharedVariable2, ... ;
CursorName을 결과 테이블의 다음 행으로 이동시키고, 선택된 값을 공유 변수에 복사한다.CLOSE CursorName;
커서와 연관된 결과 테이블을 해제한다.
커서 상태 확인
결과 테이블 행이 모두 읽히면, 커서는 마지막 행을 지나 더 이상 데이터를 가져올 수 없다. 프로그램은 SQLSTATE라는 임베디드 SQL 변수의 값을 확인하여 이 상태를 감지할 수 있다.- "00000": 커서가 유효한 행을 가리키고 있음을 나타낸다.
- 다른 값: 커서가 마지막 행을 지나갔거나, 기타 오류 조건을 나타낸다.
SQLSTATE와 기타 임베디드 SQL 변수를 호스트 프로그램에서 사용할 수 있도록 하려면 INCLUDE SQLCA 문을 포함해야 한다.
1. DECLARE CURSOR는 FlightCursor라는 이름의 커서를 생성하고, 해당 커서를 SELECT 쿼리와 연관시킨다.
2. OPEN은 쿼리를 실행하고 FlightCursor를 결과 테이블의 첫 번째 행 앞에 위치시킨다.
3. FETCH는 커서를 첫 번째 행으로 이동시키고, 열 값을 해당 공유 변수에 할당한다.
4. INCLUDE는 C 프로그램에서 SQLSTATE를 선언한다. 값 "00000"은 커서가 유효한 행을 가리키고 있음을 나타낸다.
5. 커서가 유효한 행을 가리키는 동안, 쿼리 결과를 출력하고 다음 행을 가져온다.
6. 커서가 마지막 행을 지난 후, while루프는 종료되고 커서는 해제된다.
FETCH
- moves a cursor to the next row of a result table.
- assigns query results to shared variables.
OPEN
- executes a query.
- positions a cursor before the first row of a result table.
DECLARE
- associates a cursor name with a query.
CLOSE
- releases resources associated with a cursor.
Dynamic SQL
특정 경우에 임베디드 SQL 문은 프로그램 실행 중에 생성된다. Ex: 웹 쇼핑 프로그램에서 호스트 프로그램은 사용자 상호작용에 따라 SQL 문을 포함하는 문자열 변수를 생성할 수 있다.
- 동적 SQL(Dynamic SQL): 실행 시간에 생성된 임베디드 SQL 문.
- 정적 SQL(Static SQL): 프로그램 코드에 고정된 SQL 문.
정적 SQL 문은 프리컴파일러에 의해 컴파일되지만, 동적 SQL은 프로그램 실행 중에 컴파일된다. 이로 인해 정적 SQL이 동적 SQL보다 실행 속도가 더 빠르다.
동적 SQL은 두 가지 임베디드 SQL 문으로 관리된다:PREPARE StatementName FROM :StatementString;
공유 변수 StatementString에 있는 쿼리를 컴파일하고 이를 StatementName과 연관시킨다.EXECUTE StatementName;
StatementName과 연관된 쿼리를 실행한다.
EXECUTE 문 변형
EXECUTE StatementName USING :SharedVariable1, :SharedVariable2, ...;
StatementString의 플레이스홀더를 공유 변수 값으로 대체한다.EXECUTE IMMEDIATE :StatementString;
StatementString에 있는 쿼리를 컴파일하고 실행한다. EXECUTE IMMEDIATE는 PREPARE와 EXECUTE의 작업을 수행하지만, 컴파일된 쿼리를 저장하거나 이름을 지정하지 않는다.
PREPARE는 컴파일된 쿼리에 이름을 지정하고 저장하여 여러 EXECUTE 문에서 사용할 수 있도록 한다. 동일한 쿼리를 여러 번 실행해야 할 때, EXECUTE가 EXECUTE IMMEDIATE보다 더 효율적이다.
호스트 언어 코드는 특정 동적 쿼리에 따라 달라지기 때문에 동적 SQL 프로그래밍은 어려울 수 있다.
Ex: 단일 행을 삭제하는 쿼리는 커서를 사용하여 여러 행을 선택하는 쿼리와 다르게 작성된다.
따라서 동적 SQL은 제한된 변형을 가진 특정 쿼리 유형을 생성할 때 가장 효과적이다.1. 두 개의 공유 변수가 선언된다. `queryString`은 나중에 SQL 문을 포함하게 된다.
2. 사용자가 입력한 SQL 쿼리가 `queryString`에 저장된다.
3. 쿼리가 컴파일되어 `QueryName`으로 저장된다.
4. 사용자가 항공편 번호 692를 입력한다. 쿼리가 실행되어 항공편 번호 692를 포함하는 행을 삭제한다.'데이터베이스 시스템' 카테고리의 다른 글
10.1 Application programming interfaces (0) 2024.11.22 9.3 Procedural SQL (0) 2024.11.21 9.1 Programming languages (0) 2024.11.19 8.4 Relational algebra (0) 2024.11.18 8.3 View tables (0) 2024.11.17