이 섹션에서는 Embedded SQL 프로그램에서 예외 조건 및 경고를 처리하는 방법을 설명합니다. 이를 위해 두 가지 비독점적 시설이 있습니다.
항상명령.sqlca변수.배트맨 토토 및 경고를 포착하는 간단한 방법 중 하나는 특정 조건이 발생할 때마다 실행될 특정 작업을 설정하는 것입니다. 일반적으로:
언제든지 SQL을 실행조건액션;
조건다음 중 하나일 수 있습니다:
액션다음 중 하나일 수 있습니다.
계속 #이것은 사실상 조건이 무시된다는 의미입니다. 이것이 기본값입니다.
이동라벨다음으로 이동라벨 #지정된 라벨로 점프(C 사용고토성명).
SQLPRINT #표준 오류에 메시지를 인쇄합니다. 이는 간단한 프로그램이나 프로토타이핑 중에 유용합니다. 메시지의 세부정보를 구성할 수 없습니다.
중지 #전화출구(1), 프로그램이 종료됩니다.
휴식하세요 #C 문 실행휴식. 이는 루프 또는에서만 사용해야 합니다.스위치문장.
계속하세요 #C 문 실행계속. 이는 루프 문에서만 사용해야 합니다. 실행되면 제어 흐름이 루프의 맨 위로 돌아갑니다.
전화이름 (인수)DO이름 (인수) #지정된 인수를 사용하여 지정된 C 함수를 호출합니다. (이 사용법은 의 의미와 다릅니다.전화그리고DO일반적인 PostgreSQL 문법에서.)
SQL 표준은 작업만을 제공합니다.계속그리고이동(및다음으로 이동).
다음은 간단한 프로그램에서 사용할 수 있는 예입니다. 경고가 발생하면 간단한 메시지를 인쇄하고 오류가 발생하면 프로그램을 중단합니다.
SQLWARNING SQLPRINT 시 SQL 실행; SQLERROR가 중지될 때마다 SQL을 실행합니다.
성명서언제든지 SQL을 실행은 C 문이 아닌 SQL 전처리기의 지시어입니다. 설정된 오류 또는 경고 동작은 첫 번째 사이에 동일한 조건에 대해 다른 동작이 설정되지 않는 한 핸들러가 설정된 지점 아래에 나타나는 모든 내장 SQL 문에 적용됩니다.언제든지 SQL을 실행및 C 프로그램의 제어 흐름에 관계없이 조건을 유발하는 SQL 문. 따라서 다음 두 C 프로그램 발췌 중 어느 것도 원하는 효과를 얻지 못할 것입니다.
/*
* 틀렸어
*/
int main(int argc, char *argv[])
...
if (상세)
SQLWARNING SQLPRINT가 발생할 때마다 SQL을 실행합니다.
...
EXEC SQL 선택 ...;
...
/*
* 틀렸어
*/
int main(int argc, char *argv[])
...
set_error_handler();
...
EXEC SQL 선택 ...;
...
정적 무효 set_error_handler(void)
SQLERROR가 중지될 때마다 EXEC SQL;
보다 강력한 오류 처리를 위해 Embedded SQL 인터페이스는 이름이 포함된 전역 변수를 제공합니다.sqlca(SQL 통신 영역) 다음과 같은 구조를 가지고 있습니다.
구조체
숯 sqlcaid[8];
긴 sqlabc;
긴 SQL코드;
구조체
int sqlerrml;
char sqlerrmc[SQLERRMC_LEN];
sqlerrm;
숯 sqlerrp[8];
긴 sqlerrd[6];
숯 sqlwarn[8];
char sqlstate[5];
sqlca;
(다중 스레드 프로그램에서 모든 스레드는 자동으로 자체 복사본을 얻습니다.sqlca. 이는 표준 C 전역 변수 처리와 유사하게 작동합니다.errno.)
sqlca경고와 배트맨 토토를 모두 다룹니다. 명령문 실행 중에 여러 경고 또는 배트맨 토토가 발생하는 경우sqlca마지막 항목에 대한 정보만 포함됩니다.
마지막에 배트맨 토토가 발생하지 않은 경우SQL성명,sqlca.sqlcode0이 되고sqlca.sqlstate될 것이다"00000". 경고 또는 배트맨 토토가 발생한 경우sqlca.sqlcode음수가 되며sqlca.sqlstate다음과 다를 것입니다"00000". 긍정적인sqlca.sqlcode마지막 쿼리에서 0행을 반환하는 등 무해한 조건을 나타냅니다.sqlcode그리고sqlstate두 가지 다른 배트맨 토토 코드 구성표가 있습니다. 자세한 내용은 아래에 표시됩니다.
마지막 SQL 문이 성공했다면, 그러면sqlca.sqlerrd[1]해당되는 경우 처리된 행의 OID를 포함하며sqlca.sqlerrd[2]명령에 적용 가능한 경우 처리되거나 반환된 행의 수가 포함됩니다.
배트맨 토토 또는 경고가 발생한 경우sqlca.sqlerrm.sqlerrmc배트맨 토토를 설명하는 문자열이 포함됩니다. 필드sqlca.sqlerrm.sqlerrml다음에 저장된 오류 메시지의 길이를 포함합니다.sqlca.sqlerrm.sqlerrmc(결과strlen(), C 프로그래머에게는 그다지 흥미롭지 않습니다). 일부 메시지는 너무 길어 고정 크기에 맞지 않습니다.sqlerrmc배열; 잘립니다.
경고가 있을 경우,sqlca.sqlwarn[2]다음으로 설정됨W. (다른 모든 경우에는 다음과 다른 것으로 설정됩니다.W.) 만약sqlca.sqlwarn[1]다음으로 설정됨W, 호스트 변수에 저장될 때 값이 잘렸습니다.sqlca.sqlwarn[0]다음으로 설정됨W다른 요소 중 하나라도 경고를 표시하도록 설정된 경우.
필드sqlcaid, sqlabc, sqlerrp및 나머지 요소sqlerrd그리고sqlwarn현재 유용한 정보가 없습니다.
구조sqlca은 SQL 표준에 정의되어 있지 않지만 다른 여러 SQL 데이터베이스 시스템에서 구현됩니다. 정의는 핵심적으로 비슷하지만 이식 가능한 애플리케이션을 작성하려면 다양한 구현을 주의 깊게 조사해야 합니다.
여기에 다음의 사용을 결합한 한 가지 예가 있습니다.언제든지그리고sqlca, 내용 인쇄sqlca배트맨 토토가 발생한 경우. 이는 more를 설치하기 전에 애플리케이션을 디버깅하거나 프로토타입하는 데 유용할 수 있습니다.“사용자 친화적인”배트맨 토토 핸들러.
SQLERROR 호출 시 SQL 실행 print_sqlca();
무효
print_sqlca()
fprintf(stderr, "==== sqlca ====\n");
fprintf(stderr, "sqlcode: %ld\n", sqlca.sqlcode);
fprintf(stderr, "sqlerrm.sqlerrml: %d\n", sqlca.sqlerrm.sqlerrml);
fprintf(stderr, "sqlerrm.sqlerrmc: %s\n", sqlca.sqlerrm.sqlerrmc);
fprintf(stderr, "sqlerrd: %ld %ld %ld %ld %ld %ld\n", sqlca.sqlerrd[0],sqlca.sqlerrd[1],sqlca.sqlerrd[2],
sqlca.sqlerrd[3],sqlca.sqlerrd[4],sqlca.sqlerrd[5]);
fprintf(stderr, "sqlwarn: %d %d %d %d %d %d %d %d\n", sqlca.sqlwarn[0], sqlca.sqlwarn[1], sqlca.sqlwarn[2],
sqlca.sqlwarn[3], sqlca.sqlwarn[4], sqlca.sqlwarn[5],
sqlca.sqlwarn[6], sqlca.sqlwarn[7]);
fprintf(stderr, "sqlstate: %5s\n", sqlca.sqlstate);
fprintf(stderr, "===============\n");
결과는 다음과 같습니다(여기서는 철자가 틀린 테이블 이름으로 인한 오류):
==== sqlca ==== SQL코드: -400 sqlerrm.sqlerrml: 49 sqlerrm.sqlerrmc: "pg_databasep" 관계가 38행에 존재하지 않습니다. SQLerrd: 0 0 0 0 0 0 SQLwarn: 0 0 0 0 0 0 0 0 SQL상태: 42P01 ===============
SQLSTATE대.SQLCODE #필드sqlca.sqlstate그리고sqlca.sqlcode오류 코드를 제공하는 두 가지 다른 체계입니다. 둘 다 SQL 표준에서 파생되었지만SQLCODE은 표준의 SQL-92 버전에서 더 이상 사용되지 않는 것으로 표시되었으며 이후 버전에서는 삭제되었습니다. 따라서 새로운 애플리케이션을 사용하는 것이 좋습니다.SQLSTATE.
SQLSTATE은 5자리 배열입니다. 5개 문자에는 다양한 오류 및 경고 조건의 코드를 나타내는 숫자 또는 대문자가 포함됩니다.SQLSTATE계층 구조가 있습니다. 처음 두 문자는 조건의 일반 클래스를 나타내고, 마지막 세 문자는 일반 조건의 하위 클래스를 나타냅니다. 성공적인 상태는 코드로 표시됩니다.00000.SQLSTATE코드는 대부분 SQL 표준에 정의되어 있습니다.PostgreSQL서버가 기본적으로 지원함SQLSTATE배트맨 토토 코드; 따라서 모든 애플리케이션에서 이 배트맨 토토 코드 체계를 사용하면 높은 수준의 일관성을 얻을 수 있습니다. 자세한 내용은 참조PostgreSQL : 문서 : 18 : 부록 A. PostgreSQL 토토 코드.
SQLCODE24800_25302PostgreSQL특정한 것을 할당했습니다SQLCODE사용을 위한 값으로 아래에 숫자 값 및 기호 이름이 나열되어 있습니다. 이는 다른 SQL 구현으로 이식할 수 없다는 점을 기억하십시오. 애플리케이션을 다음으로 쉽게 포팅하기 위해SQLSTATE구성표, 해당SQLSTATE또한 나열됩니다. 그러나 두 체계 사이에는 일대일 또는 일대다 매핑이 없으므로(실제로 다대다) 전역 매핑을 참조해야 합니다.SQLSTATE목록 등록PostgreSQL : 문서 : 18 : 부록 A. PostgreSQL 토토 코드각 경우에.
이들은 할당된 것입니다SQLCODE값:
ECPG_NO_ERROR) #오류가 없음을 나타냅니다. (SQLSTATE 00000)
ECPG_NOT_FOUND) #이것은 마지막 명령이 0개의 행을 검색 또는 처리했거나 현재 커서의 끝에 있음을 나타내는 무해한 조건입니다. (SQLSTATE 02000)
루프에서 커서를 처리할 때 다음과 같이 루프를 중단할 시기를 감지하는 방법으로 이 코드를 사용할 수 있습니다.
그 동안 (1)
EXEC SQL 가져오기 ... ;
if (sqlca.sqlcode == ECPG_NOT_FOUND)
휴식;
하지만발견되지 않으면 중단하세요이 작업은 내부적으로 효과적으로 수행되므로 명시적으로 작성해도 일반적으로 이점이 없습니다.
ECPG_OUT_OF_MEMORY) #가상 메모리가 소진되었음을 나타냅니다. 숫자 값은 다음과 같이 정의됩니다.-ENOMEM. (SQLSTATE YE001)
ECPG_UNSUPPORTED) #전처리기가 라이브러리가 알지 못하는 무언가를 생성했음을 나타냅니다. 아마도 호환되지 않는 버전의 전처리기와 라이브러리를 실행하고 있을 수 있습니다. (SQLSTATE YE002)
ECPG_TOO_MANY_ARGUMENTS) #이것은 명령이 예상한 것보다 더 많은 호스트 변수를 명령이 지정했음을 의미합니다. (SQLSTATE 07001 또는 07002)
ECPG_TOO_FEW_ARGUMENTS) #이는 명령이 예상한 것보다 적은 수의 호스트 변수를 명령이 지정했음을 의미합니다. (SQLSTATE 07001 또는 07002)
ECPG_TOO_MANY_MATCHES) #이것은 쿼리가 여러 행을 반환했지만 명령문은 하나의 결과 행만 저장하도록 준비되었음을 의미합니다(예: 지정된 변수가 배열이 아니기 때문에). (SQLSTATE 21000)
ECPG_INT_FORMAT) #호스트 변수 유형은 다음과 같습니다.int그리고 데이터베이스의 데이터가 다른 유형이고 다음과 같이 해석될 수 없는 값을 포함하고 있습니다.int. 도서관은strtol()이 변환을 위해. (SQLSTATE 42804)
ECPG_UINT_FORMAT) #호스트 변수 유형은 다음과 같습니다.부호 없는 정수그리고 데이터베이스의 데이터가 다른 유형이고 다음과 같이 해석될 수 없는 값을 포함하고 있습니다.부호 없는 정수. 도서관은strtoul()이 변환을 위해. (SQLSTATE 42804)
ECPG_FLOAT_FORMAT) #호스트 변수 유형은 다음과 같습니다.플로트그리고 데이터베이스의 데이터가 다른 유형이고 다음으로 해석될 수 없는 값을 포함하고 있습니다.플로트. 도서관은스트르토드()이 변환을 위해. (SQLSTATE 42804)
ECPG_NUMERIC_FORMAT) #호스트 변수 유형은 다음과 같습니다.숫자그리고 데이터베이스의 데이터가 다른 유형이고 다음으로 해석될 수 없는 값을 포함하고 있습니다.숫자값. (SQLSTATE 42804)
ECPG_INTERVAL_FORMAT) #호스트 변수 유형은 다음과 같습니다.간격그리고 데이터베이스의 데이터가 다른 유형이고 다음과 같이 해석될 수 없는 값을 포함하고 있습니다.간격값. (SQLSTATE 42804)
ECPG_DATE_FORMAT) #호스트 변수 유형은 다음과 같습니다.날짜그리고 데이터베이스의 데이터가 다른 유형이고 다음과 같이 해석될 수 없는 값을 포함하고 있습니다.날짜값. (SQLSTATE 42804)
ECPG_TIMESTAMP_FORMAT) #호스트 변수 유형은 다음과 같습니다.타임스탬프그리고 데이터베이스의 데이터가 다른 유형이고 다음으로 해석될 수 없는 값을 포함하고 있습니다.타임스탬프값. (SQLSTATE 42804)
ECPG_CONVERT_BOOL) #이것은 호스트 변수가 유형임을 의미합니다.부울그리고 데이터베이스의 데이터는 둘 다 아닙니다''아니요'f'. (SQLSTATE 42804)
ECPG_EMPTY) #다음으로 보낸 성명서PostgreSQL서버가 비어있습니다. (이것은 일반적으로 Embedded SQL 프로그램에서 발생할 수 없으므로 내부 오류를 가리킬 수 있습니다.) (SQLSTATE YE002)
ECPG_MISSING_INDICATOR) #널 값이 반환되었으며 널 표시 변수가 제공되지 않았습니다. (SQLSTATE 22002)
ECPG_NO_ARRAY) #배열이 필요한 곳에 일반 변수가 사용되었습니다. (SQLSTATE 42804)
ECPG_DATA_NOT_ARRAY) #데이터베이스가 배열값이 필요한 곳에 일반 변수를 반환했습니다. (SQLSTATE 42804)
ECPG_ARRAY_INSERT) #값은 배열에 삽입될 수 없습니다. (SQLSTATE 42804)
ECPG_NO_CONN) #프로그램이 존재하지 않는 연결에 접근을 시도했습니다. (SQLSTATE 08003)
ECPG_NOT_CONN) #프로그램이 존재하지만 열려있지 않은 연결에 접근을 시도했습니다. (내부 오류입니다.) (SQLSTATE YE002)
ECPG_INVALID_STMT) #당신이 사용하려는 명령문은 준비되지 않았습니다. (SQLSTATE 26000)
ECPG_INFORMIX_DUPLICATE_KEY) #중복 키 오류, 고유 제약 조건 위반(Informix 호환 모드). (SQLSTATE 23505)
ECPG_UNKNOWN_DESCRIPTOR) #지정된 설명자를 찾을 수 없습니다. 사용하려는 명세서가 준비되지 않았습니다. (SQLSTATE 33000)
ECPG_INVALID_DESCRIPTOR_INDEX) #지정된 설명자 인덱스가 범위를 벗어났습니다. (SQLSTATE 07009)
ECPG_UNKNOWN_DESCRIPTOR_ITEM) #잘못된 설명 항목이 요청되었습니다. (내부 오류입니다.) (SQLSTATE YE002)
ECPG_VAR_NOT_NUMERIC) #동적 명령문을 실행하는 동안 데이터베이스는 숫자 값을 반환했으며 호스트 변수는 숫자가 아닙니다. (SQLSTATE 07006)
ECPG_VAR_NOT_CHAR) #동적 명령문 실행 중 데이터베이스가 숫자가 아닌 값을 반환했으며 호스트 변수는 숫자였습니다. (SQLSTATE 07006)
ECPG_INFORMIX_SUBSELECT_NOT_ONE) #하위 쿼리의 결과가 단일 행이 아닙니다(Informix 호환 모드). (SQLSTATE 21000)
ECPG_PGSQL) #다음으로 인해 발생한 일부 오류PostgreSQL서버. 메시지에는 다음의 오류 메시지가 포함되어 있습니다.PostgreSQL서버.
ECPG_TRANS) #그PostgreSQL서버가 트랜잭션을 시작, 커밋 또는 롤백할 수 없다는 신호를 보냈습니다. (SQLSTATE 08007)
ECPG_CONNECT) #데이터베이스 연결 시도가 성공하지 못했습니다. (SQLSTATE 08001)
ECPG_DUPLICATE_KEY) #중복 키 오류, 고유 제약 조건 위반. (SQLSTATE 23505)
ECPG_SUBSELECT_NOT_ONE) #하위 쿼리의 결과는 단일 행이 아닙니다. (SQLSTATE 21000)
ECPG_WARNING_UNKNOWN_PORTAL) #잘못된 커서 이름이 지정되었습니다. (SQLSTATE 34000)
ECPG_WARNING_IN_TRANSACTION) #거래가 진행 중입니다. (SQLSTATE 25001)
ECPG_WARNING_NO_TRANSACTION) #활성(진행 중인) 거래가 없습니다. (SQLSTATE 25P01)
ECPG_WARNING_PORTAL_EXISTS) #기존 커서 이름이 지정되었습니다. (SQLSTATE 42P03)
문서에 올바르지 않은 내용이 있으면 일치하지 않습니다. 특정 기능에 대한 경험이 있거나 추가 설명이 필요한 경우 이용해주세요이 양식문서 문제를 보고합니다.