1. C/C++ 전처리기 소개#
C/C++ 전처리기#
소개#
C/C++ 전처리기 (precompiler)는 내장 SQL문이 포함된 소스 프로그램을 입력 받아, 내장 SQL문들을 Altibase CLI 함수 호출로 변환하여, 호스트 언어로 컴파일 될 수 있는 수정된 소스 프로그램을 생성한다.
사용자는 간단한 내장 SQL문을 사용하여 쉽게 응용 프로그램을 작성하고, 작성된 응용 프로그램을 전처리 한 후, compile, link 할 수 있다.
내장 SQL문을 이용한 프로그램 작성은 ODBC를 이용한 프로그램 작성에 비해 프로그램 작성법이 쉬우면서도 동등한 성능을 가지는 프로그램을 작성할 수 있다.
환경 설정#
C/C++ 전처리기로 전처리된 결과 파일을 컴파일 및 링크하기 위해서 필요한 환경 설정은 다음과 같다.
헤더파일
-
필요한 헤더파일은 ulpLibInterface.h이며, $ALTIBASE_HOME/include 디렉터리에 있다.
-
전처리된 응용 프로그램을 컴파일하기 위해서는 -I $ALTIBASE_HOME/include 옵션이 필요하다.
라이브러리
- 필요한 라이브러리는 libapre.a와 libodbccli.a이며, $ALTIBASE_HOME/lib 디렉토리에 있다.
-
컴파일된 오브젝트 파일은 다음의 옵션과 함께 링크해야 한다:
-L $ALTIBASE_HOME/lib -lapre, -lodbccli, -lpthread
주의사항
Altibase 클라이언트 라이브러리는 system signal 발생에 대해 안전하지 않다.
따라서 외부 원인에 의해 네트워크 접속이 종료된 경우, SIGPIPE 신호를 받아 진행중인 응용 프로그램이 강제로 종료될 수도 있다. 이러한 강제 종료를 막기 위해서는 SIGPIPE 신호를 사용자 애플리케이션에서 처리해야 한다. 그러나 SIGPIPE 신호 처리를 하던 중에 Altibase 클라이언트 라이브러리의 함수를 호출하면 프로그램이 멈출 수 있기 때문에 호출하면 안된다.
하지만 신호 처리가 끝난 후에는 Altibase 클라이언트 라이브러리의 함수를 호출하는 것이 가능하다.
전처리 실행#
C/C++ 전처리기는 내장 SQL문을 포함하는 C 또는 C++로 작성된 프로그램을 전처리하여 변환된 C 또는 C++ 프로그램을 생성한다. 입력 파일은 .sc 확장자를 가지는 C 또는 C++로 작성된 프로그램이며, 출력 파일은 .c 또는 .cpp를 확장자를 가진다. 출력파일의 확장자는 사용자가 지정할 수 있으며 기본적으로 .c이다.
실행방법
apre [ <apre-options> ] <filename>
실행인자
- <filename>
내장 SQL문을 포함하는 소스 프로그램으로, 확장자는 반드시 .sc이어야 한다. 소스 프로그램은 1개 이상 나열할 수 있으며 나열된 소스를 모두 처리하게 된다. 또한 *.sc와 같은 문법을 지원한다.
[예제 1] c로 작성된 프로그램을 전처리하는 명령을 보여준다. 전처리 후 생성되는 파일은 sample1.c 이다.
$ apre sample1.sc
[예제 2] 여러 개의 프로그램을 전처리하는 명령을 보여준다.
$ apre sample1.sc sample2.sc
$ apre *.sc
- <apre-options>
APRE*C/C++ 명령행 옵션이다. 자세한 설명은 다음 절 APRE*C/C++ 명령행 옵션을 참고한다.
실행화면
C/C++ 전처리기의 실행화면은 다음과 같다.
$ apre sample1.sc
--------------------------------------------------------
APRE C/C++ Precompiler.
Release Version 7.3.0.0.0
Copyright 2000, Altibase Corporation or its subsidiaries.
All rights reserved.
--------------------------------------------------------
명령행 옵션#
전처리시 명령행에 입력할 수 있는 여러 옵션들이 있다. 이 명령행 옵션들의 기능에 대한 설명은 아래와 같다.
실행 옵션
-h
APRE 실행 방법을 보여준다. 보여주는 화면은 다음과 같다.
$ apre -h
===========================================================
APRE (Altibase Precompiler) C/C++ Precompiler HELP Screen
===========================================================
Usage : apre [<options>] <filename>
-h : Display this help information.
-t <c|cpp> : Specify the file extension for the output file.
c - File extension is '.c' (default)
cpp - File extension is '.cpp'
-o <output_path> : Specify the directory path for the output file.
(default : current directory)
-mt : When precompiling a multithreaded application,
this option must be specified.
-I<include_path> : Specify the directory paths for files included using APRE C/C++.
(default : current directory)
-parse <none|partial|full>
: Control which non-SQL code is parsed.
-D<define_name> : Use to define a preprocessor symbol.
-v : Output the version of APRE.
-n : Specify when CHAR variables are not null-padded.
-unsafe_null : Specify to suppress errors when NULL values are fetched
and indicator variables are not used.
-align : Specify when using alignment in AIX.
-spill <values> : Specify the register allocation spill area size.
-keyword : Display all reserved keywords.
-debug <macro|symbol>
: Use for debugging.
macro - Display macro table.
symbol - Display symbol table.
-nchar_var <variable_name_list>
: Process the specified variables using
the Altibase national character set.
-nchar_utf16 : Set client nchar encoding to UTF-16.
-lines : Add #line directives to the generated code.
-silent : No display Copyright.
================================================
-t <c|cpp>#
C/C++ 전처리기로 전처리하여 생성되는 결과 파일의 확장자를 지정한다. c로 지정하면 .c 파일이 생성되고, cpp로 지정하면 .cpp 파일이 생성된다. 지정하지 않으면 .c 파일을 생성한다.
예제
C++로 작성된 프로그램을 전처리하는 명령을 보여준다. 전처리 후 생성되는 파일은 sample1.cpp 이다.
$ apre -t cpp sample1.sc
-o <output_path>#
C/C++ 전처리기로 전처리한 결과 파일이 생성될 위치를 지정한다. 지정하지 않으면, 현재 디렉토리에 결과 파일이 생성된다. 결과 파일이 생성될 위치는 하나만 지정할 수 있다.
-mt#
전처리할 파일이 멀티쓰레드 프로그램일 경우, 반드시 이 옵션을 지정하여야 한다. 이 옵션은 각각의 소스 파일(.sc)에 적용할 수 없으므로, 두 개 이상의 소스 파일을 전처리하여 실행 프로그램을 만드는 경우에는 모든 소스 파일에 이 옵션을 적용해야 한다.
EXEC SQL OPTION(THREADS=TRUE);
위 내장 SQL문으로 대신할 수 있다. 즉, 전처리할 파일 안에서 위 내장 SQL문을 선언하였다면 전처리 시 이 옵션은 생략 가능하다.
다만, 여러 파일을 한번에 전처리 할 경우, 이 옵션이 내장 SQL보다 우선 적용된다. 즉, 이 옵션을 선택하면 전처리 할 파일들은 모두 적용된다.
OPTION문에 대한 자세한 설명은 6장 내장 SQL문을 참조하기 바란다.
-I<include_path>#
전처리 시 사용될 헤더 파일의 위치를 지정한다. 지정하지 않으면, 전처리 시 사용되는 헤더파일은 현재 디렉토리에서 찾는다. 디렉토리 지정 시 절대경로와 상대경로 모두 가능하다.
예제
전처리 시 사용될 헤더파일의 위치를 지정하는 방법을 보여준다. 여기에서는 전처리 시 사용되는 헤더파일을 현재 디렉토리와 /include 디렉토리에서 순서대로 찾는다. 예제에서 보는 바와 같이 지정할 디렉토리가 하나 이상일 경우 -I 옵션을 여러 번 사용한다. 그리고 디렉토리는 절대경로, 상대경로 모두 가능하다.
$ apre -I. -I/include sample1.sc
-parse <none|partial|full>#
전처리시 소스파일에 대한 파싱 처리 범위를 결정한다. 위 옵션에 따라 소스파일에서 #include 로 포함하는 헤더파일에 대한 처리범위도 달라진다. -parse옵션을 주지 않았을 경우 partial로 처리된다.
none
EXEC SQL BEGIN/END DECLARE SECTION 안에 있는 호스트 변수 선언들과 매크로 명령들을 처리하며, 외부에 선언된 변수들과 매크로들은 무시된다. 소스파일 내의 내장SQL구문들은 모두 처리된다.
partial
모든 매크로 명령들을 처리하며, 호스트 변수는 EXEC SQL BEGIN/END DECLARE SECTION 안에 선언된 것들만 처리된다. #include로 포함된 헤더파일은 매크로 명령들만 처리된다. 반면 소스파일 내의 내장SQL구문들은 모두 처리된다.
full
전처리기에 내장된 C 파서가 동작하여 EXEC SQL BEGIN/END DECLARE SECTION 밖에 선언된 변수들도 처리가 되며, 모든 매크로 명령들이 처리된다. 또한, #include로 포함된 헤더파일의 매크로 명령들뿐 아니라 변수 선언부분도 처리 된다. 마지막으로 소스파일 내의 내장SQL구문들이 모두 처리된다.
그러나, 사용자가 이 옵션을 지정하여도 성능 저하가 발생할 수 있기 때문에, Altibase 전처리기는 #include를 사용하여 포함된 시스템 헤더 파일을 파싱하지 않는다. 따라서, 시스템 헤더 파일에 정의되어 있는 타입이 호스트 변수로 사용되면, 전처리 중에 오류가 발생한다. 이를 방지하기 위해 사용자는 시스템 헤더 파일에서 사용하고자 하는 타입을 Altibase가 제공하는 $ALTIBASE_HOME/include/aprePredefinedTypes.h 헤더 파일에 정의해야 한다.
단, "*.sc" 소스 파일에는 aprePredefinedTypes.h가 아닌 시스템 헤더 파일을 #include로 포함해야 한다. APRE 전처리 시에는 aprePredefinedTypes.h 파일을 자동으로 참조하지만, 컴파일 시에는 시스템 헤더 파일이 참조되어야 하기 때문이다.
주의사항
-parse 옵션을 full로 설정했을 경우 C 파서가 동작하기 때문에 C++ 소스 코드는 전처리 중 파싱 에러를 발생시킬 수 있다. 따라서 C++ 소스 코드에서는 -parse 옵션을 아예 사용하지 않던가 또는 -parse 옵션을 사용하더라도 partial/none으로 설정해 줘야 한다.
예제
$ apre -parse none -t cpp sample1.sc
$ apre -parse partial -t cpp sample1.sc
$ apre -parse full -t cpp sample1.sc
-D<define_name>#
전처리시 사용될 매크로 이름을 저장한다. 이 명령행 옵션은 코드 내에 #define매크로를 정의하는 것과 같은 기능을 한다.
예제
sample1.sc을 전처리하기 전 Altibase라는 매크로를 정의하고 싶다면 아래와 같이 명령행 옵션을 설정한다.
$ apre -DAltibase -t cpp sample1.sc
-v#
C/C++ 전처리기의 버전을 보여준다.
예제
C/C++ 전처리기의 버전을 확인하는 방법이다.
$ apre -v
Altibase Precompiler2(APRE) Ver. 7.3.0.0.1 XEON_LINUX_redhat_Enterprise_AS4-64bit-7.3.0.0.1-release-GCC3.4.6 (xeon-redhat-linux-gnu) Oct 23 2013 09:28:30
-n#
호스트 변수의 데이터 타입이 CHAR이며 null character ('\0')로 끝나지 않을 때 사용하는 옵션이다. 여러 개의 소스 파일(.sc)을 전처리하여 한 개의 실행 프로그램을 만드는 경우에는 필요한 모든 소스 파일에 이 옵션을 적용해야 한다. 입력 호스트 변수의 크기가 데이터베이스 칼럼 크기보다 작거나 같아야 한다.
-unsafe_null#
지시자 변수를 지정하지 않았을 경우, 널(null) 값을 Fetch해도 에러가 발생하지 않도록 설정하는 옵션이다. 여러 개의 소스 파일(.sc)을 전처리하여 한 개의 실행 프로그램을 만드는 경우에는 필요한 모든 소스 파일에 이 옵션을 적용해야 한다.
SELECT질의문 수행시 FETCH한 칼럼 값이 널인 경우에 지시자 변수 값이 설정되어 있지 않으면 에러가 발생한다.
-spill <values>#
AIX 장비에서 전처리할 때에만 이 옵션을 설정할 수 있으며, 다음과 같이 소스 파일 내에서도 지정할 수 있다.
#pragma options spill=<values>
-keyword#
Embedded SQL구문과 관련된 예약어 목록을 보여준다.
예제
$ apre -keyword
:: Keywords for C code ::
:: Keywords for C code ::
ALTIBASE_APRE APRE_BINARY APRE_BINARY2 APRE_BIT APRE_BLOB APRE_BLOB_LOCATOR APRE_BYTES APRE_CLOB APRE_CLOB_LOCATOR APRE_DUPKEY_ERR APRE_INTEGER APRE_NIBBLE APRE_NUMERIC APRE_VARBYTES MAX_CHAR_PTR SESC_DECLARE SESC_INCLUDE SES_BINARY SES_BIT SES_BLOB SES_BLOB_LOCATOR SES_BYTES SES_CLOB SES_CLOB_LOCATOR SES_DUPKEY_ERR SES_INTEGER SES_NIBBLE SES_NUMERIC SES_VARBYTES SQLFailOverCallback SQLLEN SQL_DATE_STRUCT SQL_TIMESTAMP_STRUCT SQL_TIME_STRUCT SQL_NUMERIC_STRUCT VARCHAR
:: Keywords for Embedded SQL statement ::
ABSOLUTE ADD AFTER AGER ALL ALLOCATE ALTER AND ANY ARCHIVE ARCHIVELOG AS ASC ASENSITIVE AT AUTOCOMMIT BACKUP BATCH BEFORE BEGIN BETWEEN BLOB_FILE BREAK BY CASCADE CASE CAST CLEAR_RECPTRS CLOB_FILE CLOSE COALESCE COLUMN COMMIT COMPILE CONNECT CONSTANT CONSTRAINT CONSTRAINTS CONTINUE CREATE CUBE CURSOR CYCLE DATABASE DEALLOCATE DECLARE DEFAULT DELETE DEQUEUE DESC DESCRIPTOR DIRECTORY DISABLE DISABLE_RECPTR DISCONNECT DISTINCT DO DROP EACH ELSE ELSEIF ELSIF ENABLE ENABLEALL_RECPTRS ENABLE_RECPTR END ENQUEUE ESCAPE EXCEPTION EXEC EXECUTE EXISTS EXIT EXTENTSIZE FALSE FETCH FIFO FIRST FIXED FLUSH FOR FOREIGN FOUND FREE FROM FULL FUNCTION GOTO GRANT GROUP GROUPING HAVING HOLD IDENTIFIED IF IMMEDIATE IN INDEX INDICATOR INNER INSENSITIVE INSERT INTERSECT INTO IS ISOLATION JOIN KEY LAST LEFT LESS LEVEL LIFO LIKE LIMIT LOB LOCAL LOCK LOGANCHOR LOOP MAXROWS MERGE MINUS MODE MOVE MOVEMENT NEW NEXT NOARCHIVELOG NOCYCLE NOPARALLEL NOT NULL OF OFF OFFLINE OLD ON ONERR ONLINE ONLY OPEN OPTION OR ORDER OTHERS OUT OUTER PARALLEL PARTITION PARTITIONS PREPARE PRIMARY PRIOR PRIVILEGES PROCEDURE PUBLIC QUEUE RAISE READ REBUILD RECOVER REFERENCES REFERENCING RELATIVE RELEASE RENAME REPLACE REPLICATION RESTRICT RETURN REVERSE REVOKE RIGHT ROLLBACK ROLLUP ROW ROWCOUNT ROWTYPE SAVEPOINT SCROLL SELECT SENSITIVE SEQUENCE SESSION SET SETS SOME SPLIT SQLCODE SQLERRM SQLERROR SQLLEN START STATEMENT STEP STORE SYNONYM TABLE TABLESPACE TEMPORARY THAN THEN THREADS TO TRIGGER TRUE TRUNCATE TYPE TYPESET UNION UNIQUE UNTIL UPDATE USER USING VALUES VARCHAR VARIABLE VIEW VOLATILE WAIT WAKEUP_RECPTR WHEN WHENEVER WHERE WHILE WITH WORK WRITE
-debug <macro|symbol>#
디버깅을 하기 위한 용도로 쓰이며, 소스 내에 정의된 매크로 이름이나 선언된 변수의 목록을 출력한다.
macro
정의된 매크로 이름의 정보를 저장하고 있는 매크로 목록을 출력한다.
symbol
선언된 변수들의 정보를 저장하고 있는 목록을 출력한다.
예제
sample1.sc안에 정의된 모든 매크로를 보여준다.
$ apre -debug macro sample1.sc
sample1.sc안에 선언된 변수의 정보를 보여준다.
$ apre -debug symbol sample1.sc
매크로와 변수 모두 출력한다.
$ apre -debug macro symbol sample1.sc
-lines#
전처리로 생성되는 .c 또는 .cpp 파일에 #line이 삽입되도록 설정하여, '*.sc' 소스 파일의 내용과 비교할 수 있다.
예제
sample.sc 파일이 전처리로 생성된 후에 #line을 있는 것을 확인할 수 있다.
$ apre -debug macro symbol sample1.sc
-nchar_utf16#
이 옵션은 전처리 할 때 내셔널 캐릭터 타입의 문자를 UTF-16으로 인코딩하도록 설정해주는 옵션이다. 이 옵션은 각각의 소스 파일(.sc)에 적용할 수 없으므로, 두 개 이상의 소스 파일을 전처리하여 실행 프로그램을 만드는 경우에는 모든 소스 파일에 이 옵션을 적용해야 한다. 이 옵션을 사용하지 않을 경우에는 기본적으로 ALTIBASE_NLS_USE에서 설정한 방식으로 인코딩된다.
그러나 ALTIBASE_NLS_USE에서 설정한 인코딩 방식을 사용할 시에는 유니코드 문자를 정확히 출력할 수 없으므로 조회 연산시에 데이터 손실이 발생할 수 있다.
예제
UTF-16으로 프로그램을 전처리한다.
$ apre -nchar_utf16 -t cpp sample.sc
-nchar_var <variable_name_list>#
Altibase가 지원하는 내셔널 캐릭터 타입의 데이터를 전처리기에서 처리하기 위해서 사용하는 옵션이다. 변수명과 변수명 사이에는 공백을 허용하지 않으며, 구조체 안의 멤버 변수는 여기에 지정할 수 없다.
-silent#
silent 모드를 켜는 옵션이다. silent 모드를 켜면 Copyright 등의 부가적인 설명들을 보여주지 않는다.
내장 SQL문을 이용한 프로그램 작성 순서 및 방법#
본 절에서는 내장 SQL문을 이용하여 프로그램을 작성할 경우, 어떤 순서와 방법으로 작성해야 하는지 전체적인 흐름에 대하여 간단히 설명한다.
다음 설명을 통해 프로그램 작성 순서 및 방법에 대해 알아보고 프로그램의 전체적인 흐름을 파악해보자.
호스트 변수 선언#
프로그램 작성 시 가장 먼저 해야 할 일은 사용할 호스트 변수와 지시자 변수들의 선언이다. -partial 명령행 옵션으로 "full"을 사용하지 않을 경우, 호스트 변수는 호스트 변수 선언부에 선언해야 한다.
호스트 변수와 지시자 변수에 대한 자세한 설명은 2장을 참조하기 바란다.
호스트 변수 선언 시 주의 사항
-
중첩된 구조체를 호스트 변수로 사용할 수 없다. 즉, 구조체의 구성 요소는 구조체일 수 없다.
-
매크로는 배열 타입의 호스트 변수 선언 시 배열 요소 개수를 지정하는 용도로만 사용 가능하다. 예를 들어 내장 SQL문에서 호스트 변수를 사용할 수 있는 위치에 매크로 정의를 사용할 수 없다.
-
문자형 타입(char, varchar)으로 호스트 변수 선언 시 호스트 변수 크기는 대응되는 칼럼 크기보다 1 크게 선언하여야 한다. 그렇지 않으면 SELECT문이나 FETCH문 수행 후 칼럼값이 잘려서 반환되기 때문에 sqlca.sqlcode값이 SQL_SUCCESS_WITH_INFO가 된다.
배열 호스트 변수 선언 시 주의 사항
배열 호스트 변수 사용에 대한 자세한 설명은 9장을 참조하기 바란다.
-
배열 호스트 변수는 1차원 배열만을 허용한다. 예외적으로, 문자열 표현을 위해 'char' 타입과 'varchar' 타입에 한해 2차원 배열을 허용한다.
-
호스트 변수가 구조체의 배열인 경우 지시자 변수를 사용할 수 없다.
-
SELECT문 또는 FETCH문의 INTO절에 구조체의 배열을 호스트 변수로 사용할 경우 출력 호스트 변수는 하나만 사용할 수 있다. 즉 다른 호스트 변수들과 함께 사용할 수 없다. 따라서 INTO절에 사용할 호스트 변수가 구조체의 배열 타입이라면 이 구조체의 구성 요소 개수는 SELECT절의 칼럼 개수와 동일해야 한다.
-
마찬가지로 INSERT문의 VALUES절에 구조체의 배열을 호스트 변수로 사용할 경우 입력 호스트 변수는 하나만 사용할 수 있다. 즉 다른 호스트 변수들과 함께 사용할 수 없다. 따라서 VALUES절에 사용할 호스트 변수가 구조체의 배열 타입이라면 이 구조체의 구성 요소 개수는 INSERT문의 칼럼 개수와 동일해야 한다.
-
'varchar' 타입도 내부적으로 구조체이므로 위의 제한 사항이 적용된다.
-
배열 타입과 배열이 아닌 타입을 함께 사용할 수 없다.
-
SELECT문 또는 FETCH문 수행 시 배열 타입의 출력 호스트 변수를 사용하였다면 반환되는 레코드 개수가 배열 크기보다 작을 경우 sqlca.sqlcode는 SQL_SUCCESS이다.
-
SELECT문 또는 CURSOR문 수행 시 입력 호스트 변수는 배열일 수 없다.
-
FOR절은 입력 호스트 변수가 배열일 경우 INSERT문, UPDATE문, DELETE문을 사용하고, 출력 호스트 변수가 배열이면 FETCH문에서 사용할 수 있다.
-
AUTOCOMMIT 모드의 경우 배열 타입의 호스트 변수를 사용할 경우 배열 전체가 하나의 트랜잭션이 아니고 배열 요소 각각이 하나의 트랜잭션이다. 따라서 배열 요소 중 일부는 성공하고 일부는 실패한다면 성공한 트랜잭션의 변경 사항은 데이터베이스 서버에 영구히 저장된다.
-
포인터 타입은 배열로 선언할 수 없다.
지시자 변수 선언 시 주의 사항
-
지시자 변수의 데이터 타입은 'int' 타입이어야 한다.
-
입력 호스트 변수로 'varchar' 타입 사용시 별도의 지시자 변수를 지정하지 않은 경우 구성 요소 len의 값을 반드시 지정하여야 한다. len에는 arr의 값이 NULL 이 아니면 arr 값의 길이를, NULL 이면 -1을 지정하여야 한다.
-
호스트 변수가 숫자형 데이터 타입일 때, 지시자 변수가 -1이 아닌 경우 지시자 변수값은 무의미하다.
-
호스트 변수의 타입이 이진 데이터 타입일 경우 반드시 지시자 변수를 사용하여야 한다.
호스트 변수 선언부
호스트 변수 선언부에 대한 자세한 설명은 3장을 참조하기 바란다.
- 호스트 변수의 데이터 타입으로 사용할 자료형 정의(typedef)는 호스트 변수 선언부에서 정의되어야 한다.
예제
다음은 호스트 변수를 선언하는 예를 보여준다.
< 예제 프로그램 : insert.sc >
/* declare host variables */
EXEC SQL BEGIN DECLARE SECTION;
char usr[10];
char pwd[10];
char s_gno[10+1];
char s_gname[20+1];
char s_goods_location[9+1];
int s_stock;
double s_price;
EXEC SQL END DECLARE SECTION;
데이터베이스 서버에 연결#
호스트 변수의 선언이 끝나면 다른 내장 SQL문의 수행에 앞서 데이터베이스 서버에 연결하여야 한다.
모든 내장 SQL문은 데이터베이스 서버와의 연결이 성공하고 난 뒤 수행 가능하다.
데이터베이스 서버와의 연결에 대한 자세한 설명은 6장을 참조하기 바란다.
CONNECT문, 다중 연결, SESSION 관련 주의 사항
-
프로그램 안에서 connect 후 같은 연결 이름으로 다시 connect를 시도한다면, connect 이전에 반드시 DISCONNECT문을 수행해야 한다.
-
USING절을 이용하여 연결 방식을 지정할 경우, CONNTYPE을 2 또는 3으로 지정한다면 DSN 또는 PORT_NO를 함께 지정하더라도 DSN, PORT_NO 옵션은 무시되고 로컬 데이터베이스 서버로 연결을 시도한다.
-
connect 시 연결 옵션 2개 지정하여 수행하는 경우 처음 옵션으로 연결 성공하면 sqlca.sqlcode는 SQL_SUCCESS이고, 처음 실패하고 두 번째 옵션으로 연결 성공하면 sqlca.sqlcode는 SQL_SUCCESS_WITH_INFO이고, 둘 다 실패하면 sqlca.sqlcode는 SQL_ERROR이다.
-
한 connection 당 내장 SQL문은 최대 1024개까지만 허용한다.
-
AUTOCOMMIT OFF session에서 commit을 하지 않고 프로그램을 종료할 경우, commit 하지 않은 SQL문은 모두 rollback 처리 된다. 그러나 DISCONNECT문을 수행하고 프로그램을 종료할 경우, 수행한 모든 내장 SQL문이 commit 처리된다.
-
다음의 내장 SQL문에서는 AT절을 허용하지 않는다.
INCLUDE문: EXEC SQL INCLUDE …
OPTION문: EXEC SQL OPTION …
WHENEVER문: EXEC SQL WHENEVER …
예제
다음은 데이터베이스 서버에 연결하는 예를 보여준다.
< 예제 프로그램 : connect1.sc >
/* declare host variables */
EXEC SQL BEGIN DECLARE SECTION;
char usr[10];
char pwd[10];
EXEC SQL END DECLARE SECTION;
/* set username */
strcpy(usr, "SYS");
/* set password */
strcpy(pwd, "MANAGER");
EXEC SQL CONNECT :usr IDENTIFIED BY :pwd;
if (sqlca.sqlcode == SQL_SUCCESS) /* check sqlca.sqlcode */
{
printf("Success connection to altibase server\n\n");
}
else
{
printf("Error : [%d] %s\n\n", SQLCODE, sqlca.sqlerrm.sqlerrmc);
exit(1);
}
내장 SQL문 수행#
데이터베이스 서버에 연결 성공 후 내장 SQL문을 수행할 수 있다. 여기에서 내장 SQL문은 SELECT, INSERT 등의 DML, CREATE 등의 DDL, 시스템 제어문, 커서 관련 SQL문, 동적 SQL문 등 Altibase SQL문을 수행할 수 있는 모든 내장 SQL문을 의미한다.
다양한 내장 SQL문들의 사용 방법에 대한 자세한 설명은 6장, 8장, 9장, 10장 그리고 11장을 참조하기 바란다.
예제
다양한 내장 SQL문의 사용 예를 보여준다.
[예제 1] 다음은 UPDATE문의 사용 예를 보여준다.
< 예제 프로그램 : update.sc >
/* declare host variables */
EXEC SQL BEGIN DECLARE SECTION;
int s_eno;
short s_dno;
varchar s_emp_job[15+1];
EXEC SQL END DECLARE SECTION;
s_eno = 2;
s_dno = 1001;
strcpy(s_emp_job.arr, "ENGINEER");
s_emp_job.len = strlen(s_emp_job.arr);
EXEC SQL UPDATE EMPLOYEES
SET DNO = :s_dno,
EMP_JOB = :s_emp_job
WHERE ENO = :s_eno;
[예제 2] 다음은 CURSOR문의 사용 예를 보여준다.
< 예제 프로그램 : hostvar.h >
EXEC SQL BEGIN DECLARE SECTION;
typedef struct department
{
short dno;
char dname[30+1];
char dep_location[9+1];
int mgr_no;
} department;
typedef struct dept_ind
{
int dno;
int dname;
int dep_location;
int mgr_no;
} dept_ind;
EXEC SQL END DECLARE SECTION;
< 예제 프로그램 : cursor1.sc >
/* specify path of header file */
EXEC SQL OPTION (INCLUDE=./include);
/* include header file for precompile */
EXEC SQL INCLUDE hostvar.h;
/* declare host variables */
EXEC SQL BEGIN DECLARE SECTION;
/* structure host variables */
department s_department;
/* structure indicator variables */
dept_ind s_dept_ind;
EXEC SQL END DECLARE SECTION;
/* declare cursor */
EXEC SQL DECLARE DEPT_CUR CURSOR FOR
SELECT *
FROM DEPARTMENTS;
/* open cursor */
EXEC SQL OPEN DEPT_CUR;
/* fetch cursor in loop */
while(1)
{
/* use indicator variables to check null value */
EXEC SQL FETCH DEPT_CUR INTO :s_department :s_dept_ind;
if (sqlca.sqlcode == SQL_SUCCESS) /* check sqlca.sqlcode */
{
printf("%d %s %s %d\n",
s_department.dno, s_department.dname,
s_department.dep_location,
s_department.mgr_no);
}
else if (sqlca.sqlcode == SQL_NO_DATA)
{
break;
}
else
{
printf("Error : [%d] %s\n", SQLCODE, sqlca.sqlerrm.sqlerrmc);
break;
}
}
/* close cursor */
EXEC SQL CLOSE DEPT_CUR;
실행 시간 에러 처리#
모든 내장 SQL문 수행 후 반드시 수행 결과를 확인하여야 한다. 내장 SQL문의 수행 결과는 sqlca.sqlcode에 저장되며 결과에 따라 SQLSTATE, SQLCODE 등의 값을 참조할 수 있다.
내장 SQL문의 수행 결과를 확인하기 위해 참조할 수 있는 다양한 변수들에 대한 자세한 설명은 7장을 참조하기 바란다.
실행 시간 에러처리 관련 주의 사항
다음은 SQLCA, SQLCODE, SQLSTATE와 WHENEVER문 등 실행시간 에러처리와 관련한 주의 사항이다.
-
모든 내장 SQL문 수행 후에는 반드시 sqlca.sqlcode값을 체크하여 에러처리를 정확히 해주어야 한다.
-
SELECT문에서 출력 호스트 변수의 크기가 대응되는 칼럼 크기보다 작을 경우, 호스트 변수에는 호스트 변수 크기만큼 데이터가 잘려서 저장되고, 이 때의 sqlca.sqlcode값은 SQL_SUCCESS_WITH_INFO이다.
-
update, delete 연산 시 영향받은 레코드 개수가 0개이면 이 때의 sqlca.sqlcode값은 SQL_NO_DATA이다. update, delete 연산 시 영향받은 레코드 개수 확인 방법은 sqlca.sqlerrd[2]값을 참조하면 되고, 위의 경우 이 값은 0이다.
-
SQLCODE에는 에러코드가 음수값으로 저장되어 있는 반면 Error Message Reference 에는 에러코드가 16진수 양수값으로 설명되어 있다. 따라서 Error Message Reference 참조 시 SQLCODE의 절대값을 16진수로 변환하여 참조하여야 한다.
-
WHENEVER문의 적용범위는 프로그램의 흐름과는 다르며, 현재 파일내에서만 유효하다.
-
WHENEVER문은 적용하고자 하는 내장 SQL문 이전에 선언하여야 한다.
-
WHENEVER문은 connection에 독립적이다. 즉, connection이 하나 이상인 파일에서 WHENEVER문을 선언하면 connection이 다르더라도 해당 범위의 모든 내장 SQL문이 영향을 받는다.
예제
다음은 내장 SQL문 수행 후 수행 결과를 확인하는 예를 보여준다.
< 예제 프로그램 : delete.sc >
/* declare host variables */
EXEC SQL BEGIN DECLARE SECTION;
int s_eno;
short s_dno;
EXEC SQL END DECLARE SECTION;
s_eno = 5;
s_dno = 1000;
EXEC SQL DELETE FROM EMPLOYEES
WHERE ENO > :s_eno AND
DNO > :s_dno AND
EMP_JOB LIKE 'P%';
/* check sqlca.sqlcode */
if (sqlca.sqlcode == SQL_SUCCESS)
{
/* sqlca.sqlerrd[2] holds the
rows-processed(deleted) count */
printf("%d rows deleted\n\n", sqlca.sqlerrd[2]);
}
else
{
printf("Error : [%d] %s\n\n",
SQLCODE, sqlca.sqlerrm.sqlerrmc);
}
데이터베이스 서버와의 연결 해제#
모든 내장 SQL문의 수행이 끝나고 프로그램을 종료하기 전에 데이터베이스 서버와의 연결을 해제한다. 데이터베이스 서버와의 연결 해제 시 이 연결에 할당된 자원들이 모두 해제된다. 데이터베이스 서버와의 연결이 해제된 이후에는 내장 SQL문을 수행할 수 없다.
데이터베이스 서버와의 연결 해제에 대한 자세한 설명은 6장을 참조하기 바란다.
예제
다음은 데이터베이스 서버와의 연결을 해제하는 예를 보여준다.
< 예제 프로그램 : connect1.sc >
EXEC SQL DISCONNECT;
Make 방법#
precompiler를 이용하여 프로그램을 작성할 경우의 전처리 과정이다
apre [<apre - option>] <filename>
예제
다음은 connect1.sc 파일을 전처리하는 예를 보여준다.
$ apre connect1.sc