Except 와 Except all

DB2 | 2007. 3. 16. 09:08
Posted by 시반

무심코 minus를 썼다가 SQL error가 발생한 DB2 쿼리를 보고 깜짝 놀랐다.

물론 오라클과 다르기는 하지만 많은 부분 유사하게 사용해 왔던 터였고

솔직히 union 과 union all , minus 등은 표준SQL인줄 알았던 터라

DB2에서 당연하리라 생각했던 코드에서 에러가 났으니 ...

역시 난 무식한 개발자....

 

알아보니 DB2에서는 Except와 Except All 연산자를 제공하고 있었다

 

A Except B : A에는 있으나 B에는 없는 것들을 추려내는 것

                 즉 A와 B의 차집합을 구하는 것이고

A Except All B : Except와 동일한 기능을 하지만 공통부분을 제거하지 않는다

  (흐음 솔직히 그러면 A그대로가 아닌가? 굳이 Except All을 쓰는 이유는 머지?)

 

여하튼 Except라는 연산자는 A테이블의 모든행을 포함하면서 B테이블과 중복되는 부분을 제거하기 위해서 사용한다는 것이다

 

샘플)

SELECT EMP_NO,NAME FROM EMPLOYEE WHERE SALARY >10000

EXCEPT

SELECT EMP_NO,NAME FROM EMPLOYEE WHERE JOB = 'MANAGER' AND YEAR<8

--> 급여가 10000 이상인 직원이지만 직급이 관리자가 아니면서 8호봉이상인 직원의 사번과 이름을 추출하고자 할 때

 

'DB2' 카테고리의 다른 글

[본문스크랩] DB2 SQLSTATE 메시지  (0) 2007.02.23
SQL을 이용한 DB2 XML 데이터 쿼리  (0) 2007.02.14
DB2 Viper 시작하기  (0) 2007.02.14
DB2 INDEX 설계  (0) 2007.02.02
DB2에서 *.sql 파일을 읽어들여 실행하기  (0) 2006.12.31
 

[본문스크랩] DB2 SQLSTATE 메시지

DB2 | 2007. 2. 23. 09:14
Posted by 시반

SQLSTATE 메시지

이 절에서는 SQLSTATE와 해당되는 의미를 나열합니다. SQLSTATE는 클래스 코드별로 그룹지어집니다. 부속 코드에 대해서는 해당 테이블을 참조하십시오.

 

표 2. SQLSTATE 클래스 코드
클래스
코드
 
의미
부속 코드에 대해
참조할 페이지
00 규정되지 않은 성공적인 완료 표 3
01 경고 표 4
02 데이터 없음 표 5
07 동적 SQL 오류 표 6
08 연결 예외 표 7
09 트리거 조치 예외 표 8
0A 기능(feature)이 지원되지 않음 표 9
0D 유효하지 않은 목표 유형 스펙 표 10
0F 유효하지 않은 토큰 표 11
0K 유효하지 않은 RESIGNAL문 표 12
20 CASE문에 해당하는 Case가 없음 표 13
21 카디낼리티 위반 표 14
22 데이터 예외 표 15
23 제한조건 위반 표 16
24 유효하지 않은 커서 상태 표 17
25 유효하지 않은 트랜잭션 상태 표 18
26 유효하지 않은 SQL문 ID 표 19
28 유효하지 않은 권한 부여 스펙 표 21
2D 유효하지 않은 트랜잭션 종료 표 22
2E 유효하지 않은 연결 이름 표 23
34 유효하지 않은 커서 이름 표 24
36 커서 감도 예외 표 25
38 외부 함수 예외 표 26
39 외부 함수 호출 예외 표 27
3B 유효하지 않은 SAVEPOINT 표 28
40 트랜잭션 롤백 표 29
42 구문 오류 또는 액세스 규칙 위반 표 30
44 WITH CHECK OPTION 위반 표 31
46 Java DDL 표 32
51 유효하지 않은 응용프로그램 상태 표 33
53 유효하지 않은 피연산자 또는 불일치 스펙 표 34
54 SQL 또는 제품 한계가 초과됨 표 35
55 오브젝트가 전제(Prerequisite) 상태에 있지 않음 표 36
56 기타 SQL 또는 제품 오류 표 37
57 자원이 사용 가능하지 않거나 조작원이 개입함 표 38
58 시스템 오류 표 39

클래스 코드 00 규정되지 않은 성공적인 완료

표 3. 클래스 코드 00: 규정되지 않은 성공적인 완료
SQLSTATE 값  
의미
00000 조작을 정상적으로 실행했으며 어떠한 유형의 경고 또는 예외 상황도 발생하지 않았습니다.

클래스 코드 01 경고

표 4. 클래스 코드 01: 경고
SQLSTATE 값  
의미
01002 DISCONNECT 오류가 발생했습니다.
01003 널(NULL) 값이 컬럼 함수의 인수에서 제거되었습니다.
01004 문자열 값이 짧은 길이로 다른 문자열 데이터 유형에 지정될 때 절단되었습니다.
01005 SQLDA 내의 항목 수가 충분하지 않습니다.
01007 특권이 부여되지 않았습니다.
0100C 프로시저로부터 하나 이상의 임시(ad hoc) 결과 세트가 리턴되었습니다.
0100D 닫혀진 커서가 체인 내에 있는 다음 결과 세트에 대해 다시 열렸습니다.
0100E 프로시저가 허용되는 최대수를 초과하는 결과 세트를 생성했습니다. 첫 번째 정수 결과 세트만이 호출자에게 리턴되었습니다.
01503 결과 컬럼의 수가 제공된 호스트 변수의 수보다 큽니다.
01504 UPDATE 또는 DELETE문이 WHERE절을 포함하지 않습니다.
01506 산술 연산의 결과로 나온 유효하지 않은 날짜를 정정하기 위해 DATE 또는 TIMESTAMP값이 조정되었습니다.
01509 사용자의 가상 머신에 스토리지가 충분하지 않으므로 커서에 대한 블로킹이 취소되었습니다.
01515 컬럼의 널(NULL)이 아닌 값이 호스트 변수의 범위 내에 있지 않으므로 널(NULL) 값이 호스트 변수에 지정되었습니다.
01516 적용할 수 없는 WITH GRANT OPTION이 무시되었습니다.
01517 변환할 수 없는 문자가 대체 문자로 바뀌였습니다.
01519 숫자 값이 범위를 벗어나므로 널(NULL) 값이 호스트 변수에 지정되었습니다.
01524 컬럼 함수의 결과에 산술 연산식 평가로 생성된 널(NULL) 값이 들어 있지 않습니다.
01526 분리 레벨이 에스컬레이션되었습니다.
01527 SET문이 AS에 존재하지 않는 특수 레지스터를 참조합니다.
01539 연결에는 성공했으나, SBCS 문자만 사용되어야 합니다.
01543 중복된 제한조건이 무시되었습니다.
01545 규정되지 않은 컬럼 이름이 상관 참조로 해석되었습니다.
01550 설명이 지정된 인덱스가 이미 있으므로, 인덱스가 작성되지 않았습니다.
01560 중복된 GRANT가 무시되었습니다.
01562 데이터베이스 구성 파일의 로그에 대한 새 경로(newlogpath)가 유효하지 않습니다.
01563 로그 파일에 대한 현재 경로(logpath)가 유효하지 않습니다. 로그 파일 경로가 디폴트값으로 재설정됩니다.
01564 0으로 나누어 호스트 변수에 널(NULL) 값이 지정되었습니다.
01586 참조 구조에서 상위 테이블에 대한 제한조건을 OFF로 설정하면, 하나 이상의 하위 테이블이 자동으로 점검 보류 상태가 됩니다.
01589 명령문에 불필요한 스펙이 들어 있습니다.
01592 SOURCE 함수를 참조하는 CREATE FUNCTION문에서
  • 입력 매개변수의 길이, 정밀도 또는 스케일이 소스 함수의 해당 매개변수의 길이, 정밀도 또는 스케일보다 크거나 또는
  • RETURNS나 CAST FROM 매개변수의 길이, 정밀도 또는 스케일이 소스 함수의 길이, 정밀도 또는 스케일보다 작거나 또는
  • CREATE FUNCTION문에 있는 CAST FROM 매개변수의 길이, 정밀도 또는 스케일이 RETURNS 매개변수의 길이, 정밀도 또는 스케일보다 큽니다.
런타임시 절단될 수 있습니다.(그리고 이때 오류가 발생할 수 있습니다.)
01594 SQLDA에서 ALL 정보의 항목 수가 충분하지 않습니다.(예: 구별 이름을 리턴하는 데 필요한 디스크립터가 충분하지 않습니다.)
01595 해당 뷰가 기존의 유효하지 않은 뷰를 대체했습니다.
01596 Long 문자열 데이터 유형에 근거한 구별 유형에 대해 비교 함수가 작성되지 않았습니다.
01598 이미 사용 중인 이벤트 모니터를 활성화하거나 사용하고 있지 않은 이벤트 모니터를 비활성화하려고 시도했습니다.
01599 REBIND에 대한 바인드 옵션이 무시되었습니다.
01602 최적화 레벨이 감소되었습니다.
01603 CHECK DATA 처리 중 제한조건 위반을 발견하고 이를 예외 테이블로 이동시켰습니다.
01604 SQL문이 Explain되었으나 실행되지 않았습니다.
01605 재귀 공통 테이블 표현식에 무한 루프가 들어 있을 수 있습니다.
01606 노드 또는 시스템 데이터베이스 디렉토리가 비어 있습니다.
01607 읽기 전용 트랜잭션의 노드에 대한 시간 차이가 정의된 임계값을 초과합니다.
01609 프로시저가 허용되는 최대수를 초과하는 결과 세트를 생성했습니다. 첫 번째 정수 결과 세트만이 호출자에게 리턴되었습니다.
01610 프로시저로부터 하나 이상의 임시(ad hoc) 결과 세트가 리턴되었습니다.
01611 닫혀진 커서가 체인 내에 있는 다음 결과 세트에 대해 다시 열렸습니다.
01614 로케이터 수가 결과 세트 수보다 적습니다.
01616 계산된 CPU 비용이 자원 한계를 초과합니다.
01618 노드 그룹을 재분배하려면 데이터 파티션을 변경해야 합니다.
01620 UNION ALL의 일부 기본 테이블이 동일한 테이블일 수도 있습니다.
01621 검색된 LOB 값이 변경되었을 수도 있습니다.
01622 명령문이 완료되었으나, 명령문이 완료된 후에 시스템 오류가 발생했습니다.
01623 DEGREE 값이 무시됩니다.
01625 스키마 이름은 CURRENT PATH에서 두 번 이상 나타납니다.
01626 데이터베이스에 사용 중인 버퍼 풀이 하나만 있습니다.
01627 DATALINK 값은 테이블이 조정 보류 중이거나 조정할 수 없는 상태이므로 유효하지 않을 것입니다.
01632 동시 연결의 수가 제품에 대해 정의된 한계를 초과했습니다.
01633 구체화된 쿼리 테이블을 쿼리 처리 최적화에 사용하지 못할 수도 있습니다.
01636 비증분식 데이터의 무결성이 데이터베이스 관리 프로그램에서 확인되지 않았습니다.
01637 디버깅이 작동 가능하지 않습니다.
01639 페더레이티드 오브젝트에는 호출자가 데이터 소스 오브젝트에 대한 필수 특권을 갖고 있어야 합니다.
01641 데이터 링크 유형 속성은 구조화된 유형의 사용을 제한합니다.
01642 컬럼이 가장 큰 USER 디폴트값이 들어갈 만큼 크지 않습니다.
01643 SQL 루틴의 SQLSTATE 또는 SQLCODE 변수에 지정한 값을 겹쳐쓸 수 있으며, 지정된 값으로 핸들러가 활성화되지 않습니다.
01645 SQL 프로시저의 실행 파일이 데이터베이스 카탈로그에 저장되어 있지 않습니다.
01648 VALUE COMPRESSION이 테이블에 대해 비활성화되었으므로 COMPRESS 컬럼 속성이 무시되었습니다.
01649 버퍼 풀 조작이 완료되었으나 다음에 데이터베이스를 재시작할 때까지 적용되지 않습니다.
01650 인덱스와 테이블 통계가 일치하지 않습니다.
01651 이벤트 모니터가 활성화되었지만, 일부 모니터링 정보가 손실되었을 수 있습니다.
01652 명령문 컨텍스트로 인해 분리 절이 무시됩니다.
01653 USER에게 권한을 부여하였습니다. 권한 부여 이름이 8바이트를 초과하기 때문에 그룹이 고려되지 않았습니다.
01654 버퍼 풀이 시작되지 않았습니다.
01655 이벤트 모니터가 작성되었지만, 최소한 하나의 이벤트 모니터 목표 테이블이 이미 존재합니다.
01657 다음에 데이터베이스를 시작할 때까지 버퍼 풀 조작이 적용되지 않습니다.
01665 컬럼 이름 또는 매개변수 이름이 절단되었습니다.
01667 뷰를 쿼리 처리 최적화에 사용하지 못할 수도 있습니다.
01669 지정된 별칭에 통계가 리모트와 로컬 카탈로그 간의 스키마 불일치로 인해 갱신되지 않았습니다.
01670 새로운 테이블에 대한 기본 디폴트 테이블 스페이스가 없습니다.
01671 캐시된 명령문의 환경이 현재 환경과 다릅니다. 현재 환경은 지정된 명령문을 다시 최적화하는 데 사용됩니다.
01H51 MQSeries Application Messaging Interface 메시지가 절단되었습니다.
01HXX 사용자 정의 함수(UDF) 또는 외부 프로시저 CALL에 의해 유효한 경고 SQLSTATE가 리턴되었습니다.

클래스 코드 02 데이터 없음

표 5. 클래스 코드 02: 데이터 없음
SQLSTATE 값  
의미
02000 다음 예외 중 하나가 발생했습니다.
  • SELECT INTO문 또는 INSERT문의 subselect의 결과가 빈 테이블이었습니다.
  • 검색한 UPDATE 또는 DELETE문에서 식별된 행 수가 0이었습니다.
  • FETCH문에서 참조된 커서의 위치가 결과 테이블의 마지막 행 다음입니다.
02501 커서 위치가 현재 행의 FETCH에 유효하지 않습니다.
02502 홀(hole) 삭제 또는 갱신이 발견되었습니다.

클래스 코드 07 동적 SQL 오류

표 6. 클래스 코드 07: 동적 SQL 오류
SQLSTATE 값  
의미
07001 호스트 변수의 수가 매개변수 표시문자의 수에 대해 올바르지 않습니다.
07002 호출 매개변수 목록 또는 제어 블록이 유효하지 않습니다.
07003 EXECUTE문에서 식별된 명령문이 SELECT문이거나, 준비된 상태가 아닙니다.
07004 동적 매개변수에 USING절 또는 INTO절이 필요합니다.
07005 커서의 명령문 이름이 준비된 명령문을 식별하는데, 이 명령문은 커서와 연관될 수 없습니다.
07006 입력 호스트 변수의 데이터 유형 때문에 이 변수를 사용할 수 없습니다.

클래스 코드 08 연결 예외

표 7. 클래스 코드 08: 연결 예외
SQLSTATE 값  
의미
08001 응용프로그램 리퀘스터가 연결을 설정할 수 없습니다.
08002 연결이 이미 존재합니다.
08003 연결이 존재하지 않습니다.
08004 응용프로그램 서버(AS)가 연결 설정을 거부했습니다.
08007 알 수 없는 트랜잭션 해석(resolution).
08502 사용 가능한 트랜잭션 관리 프로그램이 없어서 TWOPHASE의 SYNCPOINT로 실행 중인 응용프로그램 프로세스에서 발행한 CONNECT문이 실패했습니다.
08504 지정된 경로 이름 바꾸기 구성 파일을 처리하는 중에 오류가 발견되었습니다.

클래스 코드 09 트리거 조치 예외

표 8. 클래스 코드 09: 트리거 조치 예외
SQLSTATE 값  
의미
09000 트리거 SQL문이 실패했습니다.

클래스 코드 0A 기능(feature)이 지원되지 않음

표 9. 클래스 코드 0A: 기능(feature)이 지원되지 않음
SQLSTATE 값  
의미
0A001 프로세스가 연결 가능한 상태에 있지 않으므로, CONNECT문이 유효하지 않습니다.
0A502 이 데이터베이스 인스턴스에 대한 조치 또는 조작이 작동 가능하지 않습니다.
0A503 데이터의 불일치 가능성이 있으므로 페더레이티드 삽입, 갱신 또는 삭제 조작을 컴파일할 수 없습니다.

클래스 코드 0D 유효하지 않은 목표 유형 스펙

표 10. 클래스 코드 0D: 유효하지 않은 유형 스펙
SQLSTATE 값  
의미
0D000 목표 구조화된 데이터 유형 스펙이 적절한 소스 구조화된 데이터 유형의 부속 유형이 아닙니다.

클래스 코드 0F 유효하지 않은 토큰

표 11. 클래스 코드 0F: 유효하지 않은 토큰
SQLSTATE 값  
의미
0F001 LOB 토큰 변수가 현재 어떤 값도 나타내지 않습니다.

클래스 코드 0K 유효하지 않은 RESIGNAL문

표 12. 클래스 코드 0K: 유효하지 않은 RESIGNAL문
SQLSTATE 값  
의미
0K000 RESIGNAL문이 핸들러 내에 있지 않습니다.

클래스 코드 20 Case문에 해당되는 Case가 없음

표 13. 클래스 코드 20: Case문에 해당되는 Casre가 없음
SQLSTATE 값  
의미
20000 CASE문에 해당하는 Case가 없습니다.

클래스 코드 21 카디낼리티 위반

표 14. 클래스 코드 21: 카디낼리티 위반
SQLSTATE 값  
의미
21000 SELECT INTO의 결과가 두 행 이상의 결과 테이블이거나, 기본 술어의 서브쿼리 결과가 둘 이상의 값입니다.
21501 자체 참조 테이블로의 복수 행 삽입(INSERT)은 유효하지 않습니다.
21502 기본 키의 복수 행 갱신(UPDATE)은 유효하지 않습니다.
21504 RESTRICT나 SET NULL 삭제 규칙이 있는 자체 참조 테이블로부터의 복수 행 삭제(DELETE)는 유효하지 않습니다.
21505 행 함수는 둘 이상의 행을 리턴해서는 안됩니다.
21506 테이블의 동일한 행을 두 번 이상 갱신, 삭제 또는 삽입 조작의 목표로 사용할 수 없습니다.

클래스 코드 22 데이터 예외

표 15. 클래스 코드 22: 데이터 예외
SQLSTATE 값  
의미
22001 문자 데이터의 오른쪽 절단이 발생했습니다. 예를 들어, 갱신 또는 삽입 값이 컬럼에 비해 너무 긴 문자열이거나 날짜 시간 값이 너무 작아 호스트 변수에 지정할 수 없습니다.
22002 널(NULL) 값 또는 표시기 매개변수가 없습니다. 예를 들면, 표시기 변수가 지정되어 있지 않으므로, 호스트 변수에 널(NULL) 값을 지정할 수 없습니다.
22003 숫자 값이 범위를 벗어납니다.
22004 PARAMETER STYLE GENERAL로 정의된 프로시저 또는 널(Null)이 아닌 인수로 호출된 유형 보존 메소드에서 널(Null) 값이 리턴될 수 없습니다.
22007 유효하지 않은 날짜 시간 형식이 발견되었습니다. 즉, 유효하지 않은 문자열 표현이나 값이 지정되었습니다.
22008 날짜 시간 필드 오버플로우가 발생했습니다. 예를 들어, 날짜 또는 시간소인에 대한 산술 연산의 결과가 유효한 날짜 범위 내에 있지 않습니다.
2200G 대부분의 동적 유형이 일치하지 않습니다.
22011 부속 문자열 오류가 발생했습니다. 예를 들어, SUBSTR의 인수가 범위를 벗어납니다.
22012 0으로 나누는 것은 유효하지 않습니다.
22018 CAST, DECIMAL, FLOAT 또는 INTEGER 스칼라 함수에 대한 문자 값이 유효하지 않습니다.
22019 LIKE 술어에 유효하지 않은 Escape 문자가 있습니다.
22021 문자가 코드화된 문자 세트에 없습니다.
22024 NUL 종료 입력 호스트 변수 또는 매개변수가 NUL을 포함하지 않습니다.
22025 LIKE 술어 문자열 패턴에 유효하지 않은 Escape 문자의 어커런스가 들어 있습니다.
2202D 널(NULL) 인스턴스가 mutator 메소드에 사용되었습니다.
2202H TABLESAMPLE절의 샘플 크기가 유효하지 않습니다.
22501 가변 길이 문자열의 길이 제어 필드가 음수이거나 최대값보다 큽니다.
22504 혼합 데이터 값이 유효하지 않습니다.
22506 TOD 시계가 고장났거나 운영 체제 시간대 매개변수가 범위를 벗어났기 때문에, 날짜 시간 특수 레지스터에 대한 참조가 유효하지 않습니다.
22522 CCSID 값이 전혀 유효하지 않거나, 데이터 유형 또는 부속 유형에 유효하지 않거나, 코드화 체계에 유효하지 않습니다.
22526 키 변환 함수에서 행을 생성하지 않았거나 중복 행을 생성했습니다.
22527 다중 행 INSERT 조작에 유효하지 않은 입력 데이터가 발견되었습니다.

클래스 코드 23 제한조건 위반

표 16. 클래스 코드 23: 제한조건 위반
SQLSTATE 값  
의미
23001 상위 키의 갱신 또는 삭제는 RESTRICT 갱신 또는 삭제 규칙에 의해 금지됩니다.
23502 삽입 또는 갱신 값이 널(NULL)이지만, 컬럼이 널(NULL) 값을 포함할 수 없습니다.
23503 외부 키에 대해 삽입 또는 갱신 값이 유효하지 않습니다.
23504 상위 키의 갱신 또는 삭제는 NO ACTION 갱신 또는 삭제 규칙에 의해 금지됩니다.
23505 고유 인덱스 또는 고유 제한조건에 의해 부여된 제한조건의 위반이 발생했습니다.
23510 RLST 테이블에 의해 부과된 명령 사용시 제한조건의 위반이 발생했습니다.
23511 점검 제한조건이 삭제를 제한하므로 상위 행을 삭제할 수 없습니다.
23512 테이블에 제한조건 정의를 충족시키지 않는 행이 들어 있으므로 점검 제한조건을 추가할 수 없습니다.
23513 INSERT 또는 UPDATE의 결과 행이 점검 제한조건 정의를 준수하지 않습니다.
23514 데이터 점검 처리 중 제한조건 위반이 발견되었습니다.
23515 테이블에 지정한 키에 대해 중복된 값이 들어 있으므로, 고유 인덱스를 작성하거나 고유 제한조건을 추가할 수 없습니다.
23520 모든 외부 키의 값이 상위 테이블의 상위 키와 동일하지 않으므로, 외부 키를 정의할 수 없습니다.
23521 카탈로그 테이블의 갱신이 내부 제한조건을 위반합니다.
23522 식별 컬럼 또는 순서에 대한 값 범위가 모두 사용되었습니다.
23524 UNION ALL 뷰 내의 행 이동이 유효하지 않습니다.
23527 페더레이티드 데이터 원본에서 무결성 제한조건을 위반했습니다.

클래스 코드 24 유효하지 않은 커서 상태

표 17. 클래스 코드 24: 유효하지 않은 커서 상태
SQLSTATE 값  
의미
24501 식별된 커서는 열려 있지 않습니다.
24502 OPEN문에서 식별된 커서는 이미 열려 있습니다.
24504 UPDATE, DELETE, SET 또는 GET문에서 식별된 커서가 행에 위치하지 않습니다.
24506 PREPARE에서 식별된 명령문은 열린 커서의 명령문입니다.
24510 삭제 홀(hole) 또는 갱신 홀(hole)에 대해 UPDATE 또는 DELETE 조작이 시도되었습니다.
24512 결과 테이블이 기본 테이블과 일치하지 않습니다.
24513 커서 위치를 알 수 없으므로 FETCH NEXT, PRIOR, CURRENT 또는 RELATIVE가 허용되지 않습니다.
24514 이전 오류가 이 커서를 작동 불가능화하게 했습니다.
24516 커서가 이미 결과 세트에 지정되었습니다.
24517 외부 함수 또는 메소드에 의해 커서가 열린 상태로 있습니다.

클래스 코드 25 유효하지 않은 트랜잭션 상태

표 18. 클래스 코드 25: 유효하지 않은 트랜잭션 상태
SQLSTATE 값  
의미
25000 삽입, 갱신 또는 삭제 조작은 지정된 컨텍스트에서 유효하지 않습니다.
25001 이 명령문은 작업 단위(UOW)에서 첫 번째 명령문으로만 허용됩니다.
25501 이 명령문은 작업 단위(UOW)에서 첫 번째 명령문으로만 허용됩니다.
25502 단일 트랜잭션에 조작이 여러 번 발생할 수 없습니다.

클래스 코드 26 유효하지 않은 SQL문 ID

표 19. 클래스 코드 26: 유효하지 않은 SQL문 ID
SQLSTATE 값  
의미
26501 식별된 명령문이 존재하지 않습니다.

클래스 코드 27 트리거 데이터 변경 위반

표 20. 클래스 코드 27: 트리거 데이터 변경 위반
SQLSTATE 값   의미
27000 제한조건 또는 트리거에 의해 MERGE문의 목표 테이블을 수정하려고 했습니다.

클래스 코드 28 유효하지 않은 권한 부여 스펙

표 21. 클래스 코드 28: 유효하지 않은 권한 부여 스펙
SQLSTATE 값  
의미
28000 권한 부여 이름이 유효하지 않습니다.

클래스 코드 2D 유효하지 않은 트랜잭션 종료

표 22. 클래스 코드 2D: 유효하지 않은 트랜잭션 종료
SQLSTATE 값  
의미
2D521 SQL COMMIT 또는 ROLLBACK이 현재 운영 환경에서는 유효하지 않습니다.
2D522 ATOMIC 복합 명령문에서는 COMMIT 및 ROLLBACK이 허용되지 않습니다.
2D528 동적 COMMIT가 응용프로그램 실행 환경에 유효하지 않습니다.
2D529 동적 ROLLBACK이 응용프로그램 실행 환경에 유효하지 않습니다.

클래스 코드 2E 유효하지 않은 연결 이름

표 23. 클래스 코드 2E: 유효하지 않은 연결 이름
SQLSTATE 값  
의미
2E000 연결 이름이 유효하지 않습니다.

클래스 코드 34 유효하지 않은 커서 이름

표 24. 클래스 코드 34: 유효하지 않은 커서 이름
SQLSTATE 값  
의미
34000 커서 이름이 유효하지 않습니다.

클래스 코드 36 유효하지 않은 커서 스펙

표 25. 클래스 코드 36: 유효하지 않은 커서 스펙
SQLSTATE 값  
의미
36001 SENSITIVE 커서는 지정된 SELECT문에 대해 정의할 수 없습니다.

클래스 코드 38 외부 함수 예외

표 26. 클래스 코드 38: 외부 함수 예외
SQLSTATE 값  
의미
38XXX 외부 루틴 또는 트리거에 의해 유효한 오류 SQLSTATE가 리턴되었습니다.
38001 SQL문 실행에 외부 루틴은 허용되지 않습니다.
38002 루틴이 데이터를 수정하려 했으나, 이 루틴은 MODIFIES SQL DATA로 정의되지 않았습니다.
38003 명령문이 루틴에서 허용되지 않습니다.
38004 루틴이 데이터를 읽으려 했으나, 이 루틴은 READS SQL DATA로 정의되지 않았습니다.
38501 사용자 정의 함수(UDF), 외부 프로시저 또는 트리거를 호출(SIMPLE CALL 또는 SIMPLE CALL WITH NULLS 호출 규약 사용)하는 동안 오류가 발생했습니다.
38502 SQL문 실행에 외부 함수는 허용되지 않습니다.
38503 사용자 정의 함수(UDF)가 이상 종료되었습니다.
38504 사용자가 가능한 루핑 상태를 중지하려고 사용자 정의 함수(UDF)를 인터럽트했습니다.
38505 루틴의 FINAL CALL에서 SQL문이 허용되지 않습니다.
38506 함수가 OLE DB Provider로부터의 오류로 실패했습니다.
38552 SYSFUN 스키마의 함수(IBM 제공)가 비정상적으로 종료했습니다.

다음과 같은 이유 코드 중 하나가 메시지 텍스트에 나타날 수 있습니다.

01
숫자 값이 범위를 벗어남
02
0으로 나눔
03
산술 오버플로우 또는 언더플로우
04
유효하지 않은 날짜 형식
05
유효하지 않은 시간 형식
06
유효하지 않은 시간소인 형식
07
유효하지 않은 시간소인 지속 시간 문자 표현
08
유효하지 않은 간격 유형(1, 2, 4, 8, 16, 32, 64, 128, 256 중 하나여야 함)
09
문자열이 너무 김
10
문자열 함수의 길이나 위치가 범위를 벗어남
11
유효하지 않은 부동 소수점 숫자의 문자 표현
38553 시스템 스키마의 루틴이 오류로 종료되었습니다.
38H01 MQSeries 함수가 초기화하는 데 실패했습니다.
38H02 MQSeries Application Messaging Interface가 세션을 종료하는 데 실패했습니다.
38H03 MQSeries Application Messaging Interface가 메시지를 적절히 처리하지 못했습니다.
38H04 MQSeries Application Messaging Interface가 메시지를 보내는 데 실패했습니다.
38H05 MQSeries Application Messaging Interface가 메시지 읽기 및 받기에 실패했습니다.
38H06 MQSeries Application Messaging Interface (비)서브스크립션 요청에 실패했습니다.
38H07 MQSeries Application Messageing Inteface가 작업 단위(UOW)를 커미트하는 데 실패했습니다.
38H08 MQSeries Application Messaging Interface 규정 오류.
38H09 MQSeries XA (2단계 커미트) API 호출 오류.
38H0A MQSeries Application Messaging Interface가 작업 단위(UOW)를 롤백하는 데 실패했습니다.

클래스 코드 39 외부 함수 호출 예외

표 27. 클래스 코드 39: 외부 함수 호출 예외
SQLSTATE 값  
의미
39001 사용자 정의 함수(UDF)가 유효하지 않은 SQLSTATE를 리턴했습니다.
39004 IN 또는 INOUT 인수에는 널(NULL) 값이 허용되지 않습니다.
39501 인수와 연관된 구조 식별자(eye-catcher)가 수정되었습니다.

클래스 코드 3B 유효하지 않은 SAVEPOINT

표 28. 클래스 코드 3B: 유효하지 않은 SAVEPOINT
SQLSTATE 값  
의미
3B001 세이브포인트가 유효하지 않습니다.
3B002 최대 세이브포인트 수에 도달했습니다.
3B501 중복된 세이브포인트 이름이 발견되었습니다.
3B502 RELEASE 또는 ROLLBACK TO SAVEPOINT가 지정되었으나 세이브포인트가 존재하지 않습니다.
3B503 트리거 또는 전역 트랜잭션에서는 SAVEPOINT, RELEASE SAVEPOINT 또는 ROLLBACK TO SAVEPOINT가 허용되지 않습니다.

클래스 코드 40 트랜잭션 롤백

표 29. 클래스 코드 40: 트랜잭션 롤백
SQLSTATE 값  
의미
40001 자동 롤백되는 교착 상태나 시간종료가 발생했습니다.
40003 명령문 완료를 알 수 없습니다.
40504 시스템 오류로 인해 작업 단위가 롤백되었습니다.
40506 SQL 오류로 인해 현재 트랜잭션이 롤백되었습니다.
40507 인덱스 작성의 실패로 현재 트랜잭션이 롤백되었습니다.

클래스 코드 42 구문 오류 또는 액세스 규칙 위반

표 30. 클래스 코드 42: 구문 오류 또는 액세스 규칙 위반
SQLSTATE 값  
의미
42501 권한 부여 ID에는 식별된 오브젝트에 대해 지정한 조작을 실행할 수 있는 특권이 없습니다.
42502 권한 부여 ID에는 지정된 대로 조작을 수행할 수 있는 특권이 없습니다.
42504 지정한 특권을 지정된 권한 부여 이름에서 취소할 수 없습니다.
42506 소유자 권한 부여에 실패했습니다.
42508 지정한 데이터베이스 특권을 PUBLIC으로 부여할 수 없습니다.
42509 STATICRULES 옵션으로 인해 SQL 문에는 권한이 부여되지 않았습니다.
42511 DATALINK 값을 검색할 수 없습니다.
42601 문자, 토큰 또는 절이 유효하지 않거나 누락되었습니다.
42602 이름에서 유효하지 않은 문자가 발견되었습니다.
42603 종료되지 않은 문자열 상수가 발견되었습니다.
42604 유효하지 않은 숫자나 문자열 상수가 발견되었습니다.
42605 스칼라 함수에 대해 지정된 인수의 수가 유효하지 않습니다.
42606 유효하지 않은 16진수 상수가 발견되었습니다.
42607 컬럼 함수의 피연산자가 유효하지 않습니다.
42608 VALUES에서의 NULL 또는 DEFAULT 사용이 유효하지 않습니다.
42609 연산자나 술어의 모든 피연산자가 매개변수 표시문자입니다.
42610 매개변수 표시문자가 허용되지 않습니다.
42611 컬럼 또는 인수 정의가 유효하지 않습니다.
42612 명령문 문자열이, 제시되는 컨텍스트에서 허용되지 않는 SQL문입니다.
42613 절이 상호 배제적(exclusive)입니다.
42614 중복된 키워드는 유효하지 않습니다.
42615 유효하지 않은 다른 방법이 발견되었습니다.
42616 유효하지 않은 옵션이 지정되었습니다.
42617 명령문 문자열이 공백이거나 비어 있습니다.
42618 호스트 변수가 허용되지 않습니다.
42620 읽기 전용 SCROLL이 UPDATE절에 대해 지정되었습니다.
42621 점검 제한조건이 유효하지 않습니다.
42622 이름이나 레이블이 너무 깁니다.
42623 DEFAULT절을 지정할 수 없습니다.
42625 CASE 표현식이 유효하지 않습니다.
42627 RETURNS절은 EXPRESSION AS절을 사용하는 술어 스펙 앞에 지정되어야 합니다.
42628 TO SQL 또는 FROM SQL 트랜잭션 함수가 변환 정의에 두 번 이상 정의되었습니다.
42629 SQL 루틴에는 매개변수 이름이 지정되어야 합니다.
42630 SQLSTATE 또는 SQLCODE 변수 선언이 중첩된 복합 명령문 내에 있어서는 안됩니다.
42631 SQL 함수 또는 메소드에 있는 RETURN문은 리턴 값을 포함해야 합니다.
42634 XML 이름이 유효하지 않습니다.
42635 XML 이름 스페이스 접두부가 유효하지 않습니다.
42701 삽입, 갱신 조작 또는 SET 전이 변수 명령문에서 중복된 컬럼 이름이 발견되었습니다.
42702 중복된 이름으로 인해 컬럼 참조가 명확하지 않습니다.
42703 정의되지 않은 컬럼, 속성 또는 매개변수 이름이 발견되었습니다.
42704 정의되지 않은 오브젝트 이름이나 제한조건 이름이 발견되었습니다.
42705 정의되지 않은 서버 이름이 발견되었습니다.
42707 ORDER BY내의 컬럼 이름이 결과 테이블의 컬럼을 식별하지 않습니다.
42709 PRIMARY, UNIQUE 또는 FOREIGN KEY절에서 중복된 컬럼 이름이 발견되었습니다.
42710 중복된 오브젝트 이름 또는 제한조건 이름이 발견되었습니다.
42711 중복된 컬럼 이름이나 속성 이름이 오브젝트 정의 또는 ALTER문에서 발견되었습니다.
42712 FROM절에서 중복된 테이블 지정자가 발견되었습니다.
42713 오브젝트 목록에 중복되는 오브젝트가 발견되었습니다.
42720 리모트 데이터베이스에 대한 노드 이름이 노드 디렉토리에 없습니다.
42723 동일한 시그니처를 갖는 함수가 스키마에 이미 있습니다.
42724 사용자 정의 함수(UDF) 또는 프로시저에 사용되는 외부 프로그램에 액세스할 수 없습니다.
42725 함수 또는 메소드가 직접 참조되었지만(시그니처 또는 특정 인스턴스 이름에 의해서가 아님), 해당 함수의 특정 인스턴스가 둘 이상 있습니다.
42726 이름 지정된 파생된 테이블(derived table)에 대해 중복된 이름이 발견되었습니다.
42727 새로운 테이블에 기본 디폴트 테이블 스페이스가 없습니다.
42728 노드 그룹 정의에서 중복된 노드가 발견되었습니다.
42729 노드가 정의되어 있지 않습니다.
42730 컨테이너 이름이 이미 다른 테이블 스페이스에서 사용되고 있습니다.
42731 컨테이너 이름이 이미 이 테이블 스페이스에서 사용되고 있습니다.
42732 SET CURRENT PATH문에서 중복된 스키마 이름이 발견되었습니다.
42734 중복된 매개변수 이름, SQL 변수 이름, 커서 이름, 조건 이름 또는 레이블이 발견되었습니다.
42735 테이블 스페이스를 위한 노드 그룹이 버퍼 풀에 대해 정의되어 있지 않습니다.
42736 LEAVE문에 지정된 레이블이 없거나 유효하지 않습니다.
42737 핸들러에 지정된 조건이 정의되어 있지 않습니다.
42738 중복된 컬럼 이름 또는 이름이 지정되지 않은 컬럼이 FOR문의 DECLARE CURSOR문에 지정되었습니다.
42739 중복된 변환이 발견되었습니다.
42740 지정된 유형에 대한 변환이 없습니다. 변환이 삭제되지 않았습니다.
42741 데이터 유형에 대한 변환 그룹이 정의되어 있지 않습니다.
42742 유형이 지정된 테이블 또는 유형이 지정된 뷰 계층 구조에 같은 유형의 서브테이블이나 서브뷰가 이미 있습니다.
42743 검색 메소드가 인덱스 확장에 없습니다.
42744 변환 그룹에 TO SQL 또는 FROM SQL 변환 함수가 정의되어 있지 않습니다.
42745 루틴이 기존의 메소드를 사용하여 중첩 관계를 정의합니다.
42746 메소드 이름은 같은 유형 계층 구조 내의 구조화된 유형 이름과 같을 수 없습니다.
42748 스토리지 경로가 데이터베이스에 대해 이미 존재하거나 두 번 이상 지정되었습니다.
42802 삽입 값 또는 갱신 값의 수가 컬럼의 수와 동일하지 않습니다.
42803 SELECT 또는 HAVING절의 컬럼 참조는 컬럼이 그룹화 컬럼이 아니므로, 유효하지 않습니다. 또는 GROUP BY절의 컬럼 참조가 유효하지 않습니다.
42804 CASE 표현식의 결과 표현식이 호환 가능하지 않습니다.
42805 ORDER BY절의 정수는 결과 테이블의 컬럼을 식별하지 않습니다.
42806 데이터 유형이 호환 가능하지 않으므로, 호스트 변수에 값을 지정할 수 없습니다.
42807 이 오브젝트에 대해서는 INSERT, UPDATE 또는 DELETE가 허용되지 않습니다.
42808 삽입 또는 갱신 조작에서 식별된 컬럼은 갱신 불가능합니다.
42809 식별된 오브젝트는 명령문이 적용되는 오브젝트의 유형이 아닙니다.
42810 기본 테이블이 FOREIGN KEY절에서 식별되지 않습니다.
42811 지정한 컬럼 수가 SELECT절의 컬럼 수와 동일하지 않습니다.
42813 WITH CHECK OPTION을 지정한 뷰에 사용할 수 없습니다.
42815 데이터 유형, 길이, 스케일, 값 또는 CCSID가 유효하지 않습니다.
42816 표현식의 날짜 시간 값 또는 지속기간이 유효하지 않습니다.
42818 연산자 또는 함수의 피연산자가 호환되지 않습니다.
42819 산술 연산의 피연산자 또는 숫자를 요구하는 함수의 피연산자가 숫자가 아닙니다.
42820 숫자 상수가 너무 길거나, 그 값이 해당 데이터 유형의 범위 내에 있지 않습니다.
42821 갱신 또는 삽입 값이 컬럼과 호환되지 않습니다.
42823 하나의 컬럼만 허용되는 서브쿼리로부터 여러 컬럼이 리턴되었습니다.
42824 LIKE의 피연산자가 문자열이 아니거나 첫 번째 피연산자가 컬럼이 아닙니다.
42825 UNION, INTERSECT, EXCEPT 또는 VALUES의 행에 호환되는 컬럼이 없습니다.
42826 UNION, INTERSECT, EXCEPT 또는 VALUES의 행에서 컬럼 수가 동일하지 않습니다.
42827 UPDATE 또는 DELETE에서 식별된 테이블이 커서에 의해 지정된 동일한 테이블이 아닙니다.
42828 UPDATE 또는 DELETE문의 커서에 의해 지정된 테이블을 수정할 수 없거나, 커서가 읽기 전용입니다.
42829 커서에 의해 지정된 결과 테이블을 수정할 수 없으므로 FOR UPDATE OF는 유효하지 않습니다.
42830 외부 키가 상위 키의 설명을 따르지 않습니다.
42831 기본 키 또는 고유 키의 컬럼에 널(NULL) 값이 허용되지 않습니다.
42832 조작이 시스템 오브젝트에 대해 허용되지 않습니다.
42834 외부 키의 컬럼에 널(NULL) 값을 지정할 수 없으므로 SET NULL을 지정할 수 없습니다.
42835 이름 지정된 파생된 테이블(derived table) 간에 순환 참조를 지정할 수 없습니다.
42836 반복적인 이름 지정된 파생된 테이블(derived table)의 스펙이 유효하지 않습니다.
42837 컬럼의 속성이 현재 컬럼 속성과 호환되지 않으므로, 컬럼을 변경할 수 없습니다.
42838 테이블 스페이스의 유효하지 않은 사용이 발견되었습니다.
42839 인덱스 및 긴 컬럼을 해당 테이블과 별도의 테이블 스페이스에 둘 수 없습니다.
42840 AS CAST 옵션의 유효하지 않은 사용이 발견되었습니다.
42841 매개변수 표시문자는 사용자 정의 유형 또는 참조 유형이 될 수 없습니다.
42842 지정한 옵션이 컬럼 설명과 일치하지 않으므로, 컬럼 정의가 유효하지 않습니다.
42845 VARIANT 또는 EXTERNAL ACTION 함수의 유효하지 않은 사용이 발견되었습니다.
42846 소스 유형에서 목표 유형으로의 캐스트가 지원되지 않습니다.
42852 GRANT 또는 REVOKE에 지정된 특권이 유효하지 않거나 일관성이 없습니다(예: 뷰에 대한 GRANT ALTER).
42853 두 가지 방법의 옵션이 지정되었거나 같은 옵션이 두 번 이상 지정되었습니다.
42854 선택 목록의 결과 컬럼 데이터 유형이 유형이 지정된 뷰나 구체화된 쿼리 테이블 정의에 정의된 유형과 호환되지 않습니다.
42855 이 호스트 변수에 대한 LOB의 지정이 허용되지 않습니다. 이 커서의 이 LOB 값에 대한 모든 페치의 목표 호스트 변수는 로케이터이거나 LOB 변수여야 합니다.
42858 조작을 지정된 오브젝트에 적용할 수 없습니다.
42863 REXX에서 정의되지 않은 호스트 변수가 발견되었습니다.
42866 CREATE FUNCTION문 내 CAST FROM절의 RETURNS절에 있는 데이터 유형이 함수 내용에 있는 전래 함수나 RESTURN문에 의해 리턴된 데이터 유형에 적합하지 않습니다.
42867 충돌하는 옵션이 지정되었습니다.
42872 FETCH문 절이 커서 정의와 호환되지 않습니다.
42875 CREATE SCHEMA 내에서 작성할 오브젝트의 규정자가 스키마 이름과 동일해야 합니다.
42877 컬럼 이름을 규정할 수 없습니다.
42878 유효하지 않은 함수 또는 프로시저 이름이 EXTERNAL 키워드에 사용되었습니다.
42879 CREATE FUNCTION문에 있는 하나 이상의 입력 매개변수의 데이터 유형이 소스 함수의 해당 데이터 유형에 적합하지 않습니다.
42880 CAST TO와 CAST FROM 데이터 유형이 호환되지 않거나, 항상 고정 문자열이 절단되게 합니다.
42881 행 기본 함수의 사용이 잘못되었습니다.
42882 특정 인스턴스 이름 규정자가 함수 이름 규정자와 동일하지 않습니다.
42883 시그니처가 일치하는 함수 또는 메소드가 없습니다.
42884 지정된 이름과 호환되는 인수를 갖는 루틴이 없습니다.
42885 CREATE FUNCTION문에 지정된 입력 매개변수 수가 SOURCE절에 이름 지정된 함수에서 제공하는 수와 일치하지 않습니다.
42886 IN, OUT 또는 INOUT 매개변수 속성이 일치하지 않습니다.
42887 함수가 발생한 컨텍스트에서 유효하지 않습니다.
42888 테이블에 기본 키가 없습니다.
42889 테이블에 기본 키가 이미 있습니다.
42890 컬럼 목록이 참조 절에 지정되었으나, 식별된 상위 테이블에 지정된 컬럼 이름을 갖는 고유 제한조건이 없습니다.
42891 중복된 UNIQUE 제한조건이 이미 있습니다.
42893 다른 오브젝트가 종속되어 있기 때문에, 오브젝트 또는 제한조건을 삭제할 수 없습니다.
42894 DEFAULT 값이 유효하지 않습니다.
42895 정적 SQL의 경우, 입력 호스트 변수의 데이터 유형이 프로시저 또는 사용자 정의 함수(UDF)의 매개변수와 호환 불가능하므로, 해당 입력 호스트 변수를 사용할 수 없습니다.
428A0 사용자 정의 함수(UDF)의 기본이 되는 전래 함수(sourced function)에 오류가 발생했습니다.
428A1 호스트 파일 변수가 참조하는 파일에 액세스할 수 없습니다.
428A2 테이블에 파티션 키가 없으므로 테이블을 다중 노드로 구성된 노드 그룹에 지정할 수 없습니다.
428A3 이벤트 모니터에 유효하지 않은 경로가 지정되었습니다.
428A4 이벤트 모니터 옵션에 유효하지 않은 값이 지정되었습니다.
428A5 SET INTEGRITY문에 이름 지정된 예외 테이블이 적당한 구조로 되어 있지 않거나, 생성된 컬럼, 제한조건 또는 트리거와 함께 정의되었습니다.
428A6 SET INTEGRITY문에 이름 지정된 예외 테이블은 점검될 테이블 중 어느 것과도 같아서는 안됩니다.
428A7 점검 중인 테이블의 수와 SET INTEGRITY문에 지정된 예외 테이블의 수가 일치하지 않습니다.
428A8 상위 테이블이 점검 보류(check-pending) 상태에 있는 동안에는 하위 테이블에 SET INTEGRITY문을 사용하여 점검 보류 상태를 재설정할 수 없습니다.
428A9 노드 범위가 유효하지 않습니다.
428AA 컬럼 이름이 이벤트 모니터 테이블에 유효한 컬럼이 아닙니다.
428B0 ROLLUP, CUBE 또는 GROUPING SETS 내에 잘못된 중첩(nesting)이 있습니다.
428B1 특정 노드에 대해 지정되지 않은 테이블 스페이스 컨테이너 스펙의 수가 올바르지 않습니다.
428B2 컨테이너에 대한 경로 이름이 유효하지 않습니다.
428B3 유효하지 않은 SQLSTATE가 지정되었습니다.
428B7 SQL문에 지정된 번호가 유효한 범위를 벗어납니다.
428BO 페더레이티드 데이터 소스에 대한 플랜이 작성 가능하지 않습니다.
428C0 노드 그룹의 유일한 노드이므로 노드를 삭제할 수 없습니다.
428C1 하나의 ROWID 컬럼만이 테이블에 대해 지정될 수 있습니다.
428C2 함수 내용의 검사는 제공된 절이 CREATE FUNCTION문에서 지정되어야 함을 나타냅니다.
428C4 술어 연산자의 양쪽에 있는 요소의 수가 동일하지 않습니다.
428C5 데이터 소스로부터 데이터 유형에 대한 데이터 유형 맵핑을 찾을 수 없습니다.
428C9 ROWID 컬럼은 INSERT 또는 UPDATE의 목표 컬럼으로서 지정될 수 없습니다.
428CA 추가 모드에 있는 테이블에는 클러스터된 인덱스가 있을 수 없습니다.
428CB 테이블 스페이스의 페이지 크기는 연관된 버퍼 풀의 페이지 크기와 일치해야 합니다.
428D1 DATALINK 값이 참조하는 파일에 액세스할 수 없습니다.
428D4 FOR문에 지정된 커서는 OPEN, CLOSE 또는 FETCH문에서 참조될 수 없습니다.
428D5 끝 레이블이 시작 레이블과 일치하지 않습니다.
428D6 UNDO는 NOT ATOMIC문에는 허용되지 않습니다.
428D7 조건 값이 허용되지 않습니다.
428D8 SQLSTATE 또는 SQLCODE 변수의 선언 또는 사용이 유효하지 않습니다.
428DB 오브젝트가 슈퍼 유형, 슈퍼 테이블 또는 슈퍼 뷰로 유효하지 않습니다.
428DC 함수 또는 메소드가 이 유형에 대한 변환으로 유효하지 않습니다.
428DD 필수 변환이 정의되지 않았습니다.
428DE PAGESIZE 값은 지원되지 않습니다.
428DF CREATE CAST에서 지정된 데이터 유형이 유효하지 않습니다.
428DG CREATE CAST에서 지정된 함수가 유효하지 않습니다.
428DH 유형 지정된 테이블에 대해 조작이 유효하지 않습니다.
428DJ 상속된 컬럼 또는 속성은 변경하거나 삭제할 수 없습니다.
428DK 참조 컬럼의 범위(scope)가 이미 정의되었습니다.
428DL 외부 또는 전래 함수의 매개변수의 범위(scope)가 정의되었습니다.
428DM 범위 테이블이나 뷰가 참조 유형에 유효하지 않습니다.
428DN SCOPE가 외부 함수의 RETURNS절에 지정되지 않았거나 전래 함수의 RETURNS절에 지정되었습니다.
428DP 유형이 구조화된 유형이 아닙니다.
428DQ 서브테이블이나 서브뷰는 슈퍼 테이블이나 슈퍼 뷰와 다른 스키마 이름을 가질 수 없습니다.
428DR 조작은 서브테이블에 적용될 수 없습니다.
428DS 지정된 컬럼의 인덱스가 서브테이블에서 정의될 수 없습니다.
428DT 표현식의 피연산자가 유효한, 범위 지정된 참조 유형이 아닙니다.
428DU 유형이 필수 유형 계층 구조에 포함되지 않습니다.
428DV 비참조 연산자의 왼쪽 피연산자가 유효하지 않습니다.
428DW 오브젝트 ID 컬럼은 비참조 연산자를 사용하여 참조될 수 없습니다.
428DX 유형이 지정된 테이블이나 유형이 지정된 뷰 계층 구조의 루트 테이블이나 루트 뷰를 정의하는 데 오브젝트 ID 컬럼이 필요합니다.
428DY 목표 오브젝트 유형에 대한 통계를 갱신할 수 없습니다.
428DZ 오브젝트 ID 컬럼을 갱신할 수 없습니다.
428E0 인덱스 정의가 인덱스 확장의 정의와 일치하지 않습니다.
428E1 범위 생성 테이블 함수의 결과가 인덱스 확장에 대한 키 변환 테이블 함수와 일치하지 않습니다.
428E2 키 목표 매개변수의 숫자나 유형이 인덱스 확장에 대한 키 변환 함수의 숫자나 유형과 일치하지 않습니다.
428E3 인덱스 확장에서 함수에 대한 인수가 유효하지 않습니다.
428E4 함수는 CREATE INDEX EXTENSION문에서 지원되지 않습니다.
428E5 SELECTIVITY절은 사용자 정의 술어를 사용해서만 지정될 수 있습니다.
428E6 사용자 정의 술어에 있는 메소드의 검색 인수가 인덱스 확장의 해당 검색 메소드의 인수와 일치하지 않습니다.
428E7 사용자 정의 술어에서 비교 연산자 다음에 오는 피연산자 유형이 RETURNS 데이터 유형과 일치하지 않습니다.
428E8 검색 목표 또는 검색 인수 매개변수가 작성되는 함수의 매개변수 이름과 일치하지 않습니다.
428E9 인수 매개변수 이름은 같은 작성 규칙에서 검색 목표와 검색 인수로 모두 나타날 수 없습니다.
428EA 유형이 지정된 뷰에서 fullselect가 유효하지 않습니다.
428EB 서브뷰의 컬럼은 슈퍼 뷰의 해당 컬럼이 갱신 가능할 때만 읽을 수 없습니다.
428EC 구체화된 쿼리 테이블에 대해 지정된 fullselect가 유효하지 않습니다.
428ED 데이터 링크 또는 참조 유형 속성의 구조화된 유형을 구성할 수 없습니다.
428EE 옵션이 이 데이터 소스에 유효하지 않습니다.
428EF 옵션 값이 이 데이터 소스에 유효하지 않습니다.
428EG 이 데이터 소스에 대한 필수 옵션이 누락되었습니다.
428EH 이미 정의되어 있는 옵션을 추가할 수 없습니다.
428EJ 추가되지 않은 옵션을 설정 또는 삭제할 수 없습니다.
428EK 선언된 전역 임시 테이블 이름에 대한 규정자는 SESSION이어야 합니다.
428EL 변환 함수는 함수 또는 메소드와 함께 사용할 수 없습니다.
428EM TRANSFORM GROUP절이 필요합니다.
428EN 사용되지 않은 변환 그룹이 지정되었습니다.
428EP 구조화된 유형은 직접적이든 간접적이든 자신에게 종속될 수 없습니다.
428EQ 루틴의 리턴 유형이 주제 유형과 동일하지 않습니다.
428ER 메소드 본문을 제거하기 전에 메소드 스펙을 제거할 수 없습니다.
428ES 메소드 본문이 메소드 스펙의 언어 유형에 해당하지 않습니다.
428EU TYPE 또는 VERSION이 서버 정의에 지정되어 있지 않습니다.
428EV 데이터 소스 유형에는 pass-through 기능이 지원되지 않습니다.
428EW 테이블을 요약 테이블로 또는 구체화된 쿼리 테이블을 테이블로 변환할 수 없습니다.
428EX 루틴이 내장 함수 또는 메소드이기 때문에 변환 함수로 사용될 수 없습니다.
428EY 사용자 정의 술어에 있는 검색 목표의 데이터 유형이 지정된 인덱스 확장의 소스 키에 대한 데이터 유형과 일치하지 않습니다.
428EZ OLAP 함수의 창 스펙이 유효하지 않습니다.
428F0 ROW 함수는 컬럼을 두 개 이상을 포함해야 합니다.
428F1 SQL TABLE 함수는 테이블 결과를 리턴해야 합니다.
428F2 SQL 프로시저에서 RETURN문 값의 데이터 유형은 INTEGER여야 합니다.
428F3 SCROLL과 WITH RETURN은 함께 사용할 수 없습니다.
428F4 FETCH문에 지정된 SENSITIVITY는 이 커서에 사용할 수 없습니다.
428F6 커서가 화면 이동 커서이지만, 결과 테이블에 테이블 함수의 출력이 포함됩니다.
428F7 SQL 루틴에만 적용하는 조작이 외부 루틴에서 시도되었습니다.
428F9 이 컨텍스트에서는 시퀀스 표현식을 지정할 수 없습니다.
428FA 10진수의 스케일은 0이어야 합니다.
428FB sequence-name은 식별 컬럼용으로 시스템이 생성한 시퀀스여서는 안됩니다.
428FC ENCRYPTION PASSWORD의 길이가 유효하지 않습니다.
428FD 암호 해독에 사용된 암호가 데이터를 암호화할 때 사용된 암호와 일치하지 않습니다.
428FE 이 데이터는 ENCRYPT 함수의 결과가 아닙니다.
428FF 버퍼 풀 스펙이 유효하지 않습니다.
428FG 스테이징 테이블을 정의하는 데 사용된 테이블이 유효하지 않습니다.
428FH SET INTEGRITY 옵션이 유효하지 않습니다.
428FI ORDER OF가 지정되었으나, 테이블 지정자에 ORDER BY절이 없습니다.
428FJ 뷰 또는 구체화된 쿼리 테이블의 외부 fullselect에서는 ORDER BY가 허용되지 않습니다.
428FL SQL 데이터 변경 명령문이 지정된 컨텍스트에서 허용되지 않습니다.
428FM SELECT 내의 INSERT문에 대칭 뷰가 아닌 뷰가 지정되었습니다.
428FP 주제 뷰에서 각 조작에 대해 하나의 INSTEAD OF 트리거가 허용됩니다.
428FQ INSTEAD OF 트리거는 WITH CHECK OPTION을 사용하여 정의된 뷰, WITH CHECK OPTION이 정의된 다른 뷰에 정의된 뷰 또는 WITH ROW MOVEMENT절을 사용하여 정의된 뷰에 중첩된 뷰를 지정해서는 안됩니다.
428FU FROM SQL 변환 함수 또는 메소드로부터 리턴된 내장 유형이 TO SQL 변환 함수 또는 메소드의 해당하는 내장 유형과 일치하지 않습니다.
428FV 메소드를 중첩 메소드로 정의할 수 없습니다.
428FZ 일부 조작에 대해서만 정의된 INSTEAD OF 트리거가 있는 뷰는 MERGE문에서 목표로 사용할 수 없습니다.
428G3 fullselect에서 SQL 데이터 변경 명령문의 목표 뷰에 INSTEAD OF 트리거가 정의되어 있는 경우 최종 테이블은 유효하지 않습니다.
428G4 INPUT SEQUENCE 순서가 잘못 사용되었습니다.
428G5 UPDATE문의 지정 절은 INCLUDE 컬럼이 아닌 컬럼을 최소한 하나 이상 지정해야 합니다.
428G6 fullselect의 FROM절에서 데이터 변경 명령문의 목표로부터 선택할 수 없는 컬럼이 지정되었습니다.
428G8 뷰를 쿼리 최적화에 사용할 수 없습니다.
428GA 페더레이티드 옵션은 추가, 삭제 또는 변경될 수 없습니다.
42901 컬럼 함수에 컬럼 이름이 포함되어 있지 않습니다.
42903 WHERE절이나 SET절에 컬럼 함수와 같은 유효하지 않은 참조가 들어 있습니다.
42904 컴파일 오류로 인해 SQL 프로시저를 작성할 수 없습니다.
42907 문자열이 너무 깁니다.
42908 명령문에 필요한 컬럼 목록이 포함되어 있지 않습니다.
42910 명령문이 복합 명령문에서 허용되지 않습니다.
42911 10진수 나눗셈 조작의 결과로 스케일이 음수가 되므로, 10진수 나눗셈 조작은 유효하지 않습니다.
42912 컬럼이 커서의 SELECT문의 UPDATE절에서 식별되지 않으므로, 이 컬럼을 갱신할 수 없습니다.
42914 서브쿼리에서 참조되는 테이블이 조작에 의해 영향을 받을 수 있으므로, DELETE가 유효하지 않습니다.
42915 유효하지 않은 참조 제한조건이 발견되었습니다.
42916 별명을 작성하면 별명이 반복적인 체인을 이루므로 별명을 작성할 수 없습니다.
42917 오브젝트를 명시적으로 삭제 또는 변환할 수 없습니다.
42918 사용자 정의 데이터 유형(UDT)을 시스템 정의 데이터 유형(예: INTEGER) 이름으로 작성할 수 없습니다.
42919 중첩된 복합 명령문은 허용되지 않습니다.
42921 테이블 스페이스에 컨테이너를 추가할 수 없습니다.
42925 반복적인 이름 지정된 파생된 테이블(derived table)은 SELECT DISTINCT를 지정할 수 없으며, UNION ALL을 지정해야 합니다.
42928 테이블에 대해 WITH EMPTY TABLE을 지정할 수 없습니다.
42932 프로그램 준비 가정(assumption)이 올바르지 않습니다.
42939 지정된 ID는 시스템에서 사용하기 위해 예약되어 있으므로, 이름을 사용할 수 없습니다.
42961 지정된 서버 이름이 현재 서버와 일치하지 않습니다.
42962 긴 컬럼, LOB 컬럼 또는 구조화된 유형은 인덱스, 키 또는 제한조건에서 사용될 수 없습니다.
42968 현재 소프트웨어 라이센스가 없기 때문에 연결에 실패했습니다.
42969 패키지가 작성되지 않았습니다.
42972 조인 조건 또는 MERGE문의 ON절에서 표현식은 둘 이상의 피연산자 테이블의 컬럼을 참조합니다.
42985 명령문이 루틴에서 허용되지 않습니다.
42987 명령문이 프로시저 또는 트리거에서 허용되지 않습니다.
42989 표현식을 기본으로 한 GENERATED 컬럼은 BEFORE 트리거에서는 사용될 수 없습니다.
42991 BOOLEAN 데이터 유형은 현재 내부적으로만 지원됩니다.
42993 컬럼이 정의될 때, 너무 길어서 로그할 수 없습니다.
42994 원시 디바이스(raw device) 컨테이너는 지원되지 않습니다.
42995 요청된 함수가 전역 임시 테이블에 적용되지 않습니다.
42997 기능이 이 버전의 DB2 응용프로그램 리퀘스터, DB2 응용프로그램 서버 또는 이 둘의 조합에서 지원하지 않습니다.
429A0 외부 키는 처음에 로그지 않으므로 정의된 상위 테이블을 참조할 수 없습니다.
429A1 노드 그룹이 테이블 스페이스에 유효하지 않습니다.
429A9 DataJoiner가 SQL문을 처리할 수 없습니다.
429B2 구조화된 유형 또는 컬럼에 지정된 인라인 길이 값이 너무 작습니다.
429B3 오브젝트가 서브테이블에서 정의되지 않을 수도 있습니다.
429B4 데이터 필터 함수는 LANGUAGE SQL 함수가 될 수 없습니다.
429B5 인덱스 확장에서 인스턴스 매개변수의 데이터 유형이 유효하지 않습니다.
429B8 PARAMETER STYLE JAVA에 정의된 루틴은 매개변수 또는 리턴 유형으로서 구조화된 유형을 가질 수 없습니다.
429B9 속성을 지정할 때 DEFAULT 또는 NULL을 사용할 수 없습니다.
429BA FEDERATED 키워드는 페더레이티드 데이터베이스 오브젝트에 대한 참조와 함께 사용되어야 합니다.
429BB 매개변수 또는 변수에 대해 지정된 데이터 유형이 SQL 루틴에서는 지원되지 않습니다.
429BC ALTER TABLESPACE문에 여러 개의 컨테이너 조치가 있습니다.
429BE 기본 키 또는 고유 키가 차원 절에서 컬럼의 서브세트입니다.
429BG 함수는 범위 클러스터 테이블에서 지원되지 않습니다.
429BJ 뷰에서 WITH ROW MOVEMENT가 잘못 사용되었습니다.
429BK 행 이동에 하위 뷰가 포함되므로 뷰 갱신 시도가 유효하지 않습니다.
429BL SQL 데이터를 수정하는 함수가 올바르지 않은 컨텍스트에서 호출되었습니다.
429BO 페더레이티드 데이터 소스에 대한 플랜이 작성 가능하지 않습니다.
429BP 별칭 계산 결과 컬럼이 유효하지 않습니다.

클래스 코드 44 WITH CHECK OPTION 위반

표 31. 클래스 코드 44: WITH CHECK OPTION 위반
SQLSTATE 값  
의미
44000 결과 행이 뷰 정의를 충족시키지 않으므로, 삽입이나 갱신 조작이 허용되지 않습니다.

클래스 코드 46 Java DDL

표 32. 클래스 코드 46: Java DDL
SQLSTATE 값  
의미
46001 Java DDL - 유효하지 않은 URL.
46002 Java DDL - 유효하지 않은 jar 이름.
46003 Java DDL - 유효하지 않은 클래스 삭제.
46007 Java DDL - 유효하지 않은 시그니처.
46008 Java DDL - 유효하지 않은 메소드 스펙.
46103 Java 루틴에 ClassNotFound 예외가 발생했습니다.
46501 Java DDL - 선택적 구성요소가 구현되지 않았습니다.

클래스 코드 51 유효하지 않은 응용프로그램 상태

표 33. 클래스 코드 51: 유효하지 않은 응용프로그램 상태
SQLSTATE 값  
의미
51002 SQL문 실행 요청에 해당되는 패키지가 없습니다.
51003 일관성 토큰이 일치하지 않습니다.
51004 SQLDA의 주소가 유효하지 않습니다.
51005 이전 시스템 오류로 인해 이 기능이 작동 불가능하게 되었습니다.
51008 프리컴파일된 프로그램의 릴리스 번호가 유효하지 않습니다.
51015 바인드 시 오류가 발견된 섹션을 실행하려고 했습니다.
51017 사용자가 로그온되지 않았습니다.
51021 응용프로그램 프로세스에서 롤백 작업을 처리할 때까지 SQL문을 실행할 수 없습니다.
51022 CONNECT문에 이름 지정된 서버로의 연결(현재 또는 비활동)이 이미 존재하면, 권한 부여 이름을 지정하는 CONNECT가 유효하지 않습니다.
51023 데이터베이스가 데이터베이스 관리 프로그램의 다른 인스턴스에서 이미 사용 중입니다.
51024 뷰가 작동 불능으로 표시되어, 이를 사용할 수 없습니다.
51025 XA 트랜잭션 처리 환경의 응용프로그램은 SYNCPOINT TWOPHASE로 바인드되지 않습니다.
51026 이벤트 모니터의 목표 경로를 이미 다른 이벤트 모니터에서 사용 중이므로, 이 이벤트 모니터를 작동시킬 수 없습니다.
51027 테이블이 사용자 유지보수 구체화된 쿼리 테이블이거나, 점검 보류 상태가 아니므로 SET INTEGRITY문의 IMMEDIATE CHECKED 옵션이 유효하지 않습니다.
51028 패키지가 작동 불능으로 표시되어 이를 사용할 수 없습니다.
51030 ALLOCATE CURSOR 또는 ASSOCIATE LOCATORS문에서 참조되는 프로시저가 응용프로그램 프로세스에서 호출되지 않았습니다.
51034 MODIFIES SQL DATA로 정의된 루틴이 이 루틴이 호출된 컨텍스트에서 유효하지 않습니다.
51035 이 세션에서 시퀀스에 대해 값이 생성되지 않았으므로 PREVVAL 표현식을 사용할 수 없습니다.
51038 루틴에서 더 이상 SQL문을 발행하지 못할 수 있습니다.
51039 ENCRYPTION PASSWORD 값이 설정되지 않았습니다.
51040 유효하지 않은 컴파일 환경.

클래스 코드 53 유효하지 않은 피연산자 또는 불일치 스펙

표 34. 클래스 코드 53: 유효하지 않은 피연산자 또는 불일치 스펙
SQLSTATE 값  
의미
53040 지정된 버퍼 풀이 지정된 데이터베이스 파티션에 존재하지 않습니다.
53090 하나의 코드화 체계(ASCII, EBCDIC 또는 유니코드)의 데이터만 같은 SQL문에서 참조될 수 있습니다.
53091 지정된 코드화 체계가 포함하는 오브젝트에 현재 사용 중인 코드화 체계와 동일하지 않습니다.

클래스 코드 54 SQL 또는 제품 한계가 초과됨

표 35. 클래스 코드 54: SQL 또는 제품 한계가 초과됨
SQLSTATE 값  
의미
54001 명령문이 너무 길거나 너무 복잡합니다.
54002 문자열 상수가 너무 깁니다.
54004 명령문에 테이블 이름이 너무 많거나 SELECT 또는 INSERT 목록에 항목이 너무 많습니다.
54006 병합의 결과가 너무 깁니다.
54008 키가 너무 길거나 키에 너무 많은 컬럼이 있거나 키 컬럼이 너무 깁니다.
54010 테이블의 레코드 길이가 너무 깁니다.
54011 테이블이나 뷰에 대해 컬럼이 너무 많이 지정되었습니다.
54023 함수 또는 프로시저에 대한 매개변수나 인수의 수에 대한 한계가 초과되었습니다.
54028 최대 동시 LOB 핸들 수에 도달했습니다.
54029 최대 열린 디렉토리 스캔 수에 도달했습니다.
54030 최대수의 이벤트 모니터가 이미 사용 중입니다.
54031 최대 파일 수가 이벤트 모니터에 이미 지정되었습니다.
54032 최대 테이블 크기에 도달했습니다.
54033 최대 파티션 맵의 수에 도달했습니다.
54034 테이블 스페이스에 대한 모든 컨테이너 이름의 길이 합계가 너무 깁니다.
54035 내부 오브젝트 한계를 초과했습니다.
54036 컨테이너 또는 스토리지 경로의 경로 이름이 너무 깁니다.
54037 테이블 스페이스에 대한 컨테이너 맵(map)이 너무 복잡합니다.
54038 중첩된 루틴 또는 트리거의 최대 용량을 초과했습니다.
54045 유형 계층 구조의 최대 레벨을 초과했습니다.
54046 인덱스 확장에서 허용된 최대 매개변수가 초과되었습니다.
54047 테이블 스페이스의 최대 크기에 도달했습니다.
54048 페이지 크기가 충분한 임시 테이블 스페이스가 없습니다.
54049 구조화된 유형의 인스턴스 길이가 시스템 한계를 초과합니다.
54050 구조화된 유형에서 최대 허용 속성이 초과되었습니다.
54052 버퍼 풀의 블록 페이지 수가 버퍼 풀의 크기에 비해 너무 큽니다.
54053 BLOCKSIZE에 지정된 값이 유효한 범위내에 있지 않습니다.

클래스 코드 55 오브젝트가 전제(prerequisite) 상태에 있지 않음

표 36. 클래스 코드 55: 오브젝트가 전제(prerequisite) 상태에 있지 않음
SQLSTATE 값  
의미
55001 데이터베이스를 이주해야 합니다.
55002 설명 테이블이 적절하게 정의되어 있지 않습니다.
55006 오브젝트는 현재 같은 응용프로그램 프로세스에서 사용 중이므로 삭제할 수 없습니다.
55007 오브젝트는 현재 같은 응용프로그램 프로세스에서 사용 중이므로 변경할 수 없습니다.
55009 시스템이 읽기 전용 파일 또는 쓰기 보호된 디스켓에 쓰려고 했습니다.
55012 클러스터링 인덱스가 이미 테이블에 있습니다.
55019 테이블이 조작에 유효하지 않은 상태입니다.
55022 파일 서버가 데이터베이스에 등록되지 않았습니다.
55023 루틴을 호출할 때 오류가 발생했습니다.
55024 테이블 관련 데이터가 다른 테이블 스페이스에도 있기 때문에 이 테이블 스페이스를 삭제할 수 없습니다.
55025 데이터베이스를 재시작해야 합니다.
55026 임시 테이블 스페이스는 삭제할 수 없습니다.
55031 오류 맵핑 파일의 형식이 올바르지 않습니다.
55032 이 응용프로그램이 시작된 이후 데이터베이스 관리 프로그램이 중지되었기 때문에 CONNECT문은 유효하지 않습니다.
55033 이벤트 모니터가 작성 또는 수정된 같은 작업 단위(UOW)에서 이벤트 모니터를 활성화할 수 없습니다.
55034 이벤트 모니터가 조작에 유효하지 않은 상태입니다.
55035 테이블이 보호되어 있으므로 삭제할 수 없습니다.
55036 노드가 파티션 맵에서 제거되지 않았기 때문에 삭제할 수 없습니다.
55037 테이블이 다중 노드로 구성된 노드 그룹에 있기 때문에 파티션 키를 삭제할 수 없습니다.
55038 노드 그룹은 재조정(rebalance)되는 중이므로 사용할 수 없습니다.
55039 테이블 스페이스가 적절한 상태에 있지 않기 때문에 액세스 또는 상태 변화가 허용되지 않습니다.
55041 재조정이 수행되는 동안에는 컨테이너를 테이블 스페이스에 추가할 수 없습니다.
55043 구조화된 유형에 근거하는 유형이 지정된 테이블 또는 유형이 지정된 뷰가 있는 경우 이러한 유형의 속성은 변경할 수 없습니다.
55045 필요한 구성요소가 서버에서 사용 가능하지 않으므로 루틴에 대한 SQL 아카이브(SAR) 파일을 작성할 수 없습니다.
55046 지정된 SQL 아카이브가 목표 환경과 일치하지 않습니다.
55047 외부 함수 또는 메소드가 페더레이티드 오브젝트에 액세스하려고 했습니다.
55048 암호화된 데이터는 암호화할 수 없습니다.
55049 이벤트 모니터 테이블이 제대로 정의되지 않았습니다.
55051 ALTER BUFFERPOOL문이 현재 진행 중입니다.
55054 메소드를 중첩 메소드로 정의할 수 없습니다.
55056 데이터베이스를 페더레이션에 사용할 수 없으므로 별칭 통계를 갱신할 수 없습니다.
55060 데이터베이스에 대해 자동 스토리지가 정의되지 않았습니다.
55061 자동 스토리지 테이블 스페이스의 경로 재지정 리스토어가 허용되지 않습니다.
55062 자동 스토리지에 데이터베이스를 사용할 수 없기 때문에 스토리지 경로가 제공될 수 없습니다.

클래스 코드 56 기타 SQL 또는 제품 오류

표 37. 클래스 코드 56: 기타 SQL 또는 제품 오류
SQLSTATE 값  
의미
56031 이 시스템에서는 혼합 및 DBCS 데이터가 지원되지 않기 때문에 절 또는 스칼라 함수는 유효하지 않습니다.
56033 Long 문자열 컬럼의 삽입 또는 갱신 값은 호스트 변수 또는 널(NULL)이어야 합니다.
56038 이 환경에서는 요청된 기능이 지원되지 않습니다.
56072 후속 SQL문을 실행하는 데 영향을 미치지 못하는 하위 레벨 서버에서 지원하지 않는 함수로 인해 실행하지 못했습니다.
56084 LOB 데이터는 DRDA에서 지원되지 않습니다.
56091 복합 SQL문의 실행 결과로 여러 가지 오류가 발생했습니다.
56092 인증 이름이 사용자 ID 또는 그룹 ID이기 때문에 인증 유형을 판별할 수 없습니다.
56095 바인드 옵션이 유효하지 않습니다.
56097 LONG VARCHAR와 LONG VARGRAPHIC 필드는 DEVICE에서 빌드된 TABLESPACE에서 허용되지 않습니다.
56098 내재 리바인드 또는 준비 중에 오류가 발생했습니다.
56099 REAL 데이터 유형은 목표 데이터베이스에서 지원하지 않습니다.
560A0 LOB 값에 대한 조치가 실패했습니다.
560AA 이 시스템에서는 UCS-2가 지원되지 않기 때문에 절 또는 스칼라 함수는 유효하지 않습니다.
560AC 지정된 유형 또는 데이터 소스 버전에 대해서는 랩퍼 정의를 사용할 수 없습니다.
560AF 게이트웨이 집중기를 사용할 때 PREPARE문이 지원되지 않습니다.
560B0 테이블 스페이스 또는 테이블 스페이스 컨테이너 크기 재지정에 대해 새 크기 값이 유효하지 않습니다.
560B1 스토어드 프로시저에 유효하지 않은 커서 스펙이 있습니다.
560B7 복수 행 INSERT의 경우, 시퀀스 표현식의 사용법은 각 행에 대해 동일해야 합니다.
560BB 동적으로 준비되는 CALL문의 INOUT 매개변수에서는 USING절과 INTO절에 같은 호스트 변수를 사용해야 합니다.
560BC 파일에 액세스하는 중에 오류가 발생했습니다.
560BD 페더레이티드 서버가 데이터 소스에서 예기치 않은 오류 코드를 수신했습니다.
560BF 암호화 기능이 사용 불가능합니다.
560C0 유니코드 코드화 체계로 작성된 테이블은 SQL 함수 또는 SQL 메소드에 사용할 수 없습니다.
560C1 유니코드 코드화 체계로 작성된 테이블은 유형이 지정된 테이블이 되거나, 그래픽 유형 또는 사용자 정의 유형을 포함할 수 없습니다.
560C2 삭제된 테이블에 대한 실행기록 파일 항목을 쓰는 데 실패했습니다.
560C3 이후 트리거는 INSERT문에 삽입 중인 행을 수정할 수 없습니다.
560C6 참조 제한조건이 fullselect 내의 SQL 데이터 변경 명령문에서 수정한 행을 수정할 수 없습니다.
560C8 일부 별칭 통계를 갱신할 수 없습니다.
560C9 지정된 명령문을 설명할 수 없습니다.
560CA SQL문이 현재 데이터베이스 파티션에서만 실행될 수 있는 루틴을 참조합니다.

클래스 코드 57 자원이 사용 가능하지 않거나 조작원이 개입함

표 38. 클래스 코드 57: 자원이 사용 가능하지 않거나 조작원이 개입함
SQLSTATE 값  
의미
57001 테이블에 1차 인덱스가 없기 때문에 이 테이블을 사용할 수 없습니다.
57003 지정된 버퍼 풀이 활성화되지 않았습니다.
57007 DROP 또는 ALTER가 보류 중이므로 오브젝트를 사용할 수 없습니다.
57009 가상 스토리지 또는 데이터베이스 자원이 임시로 사용 불가능하게 되었습니다.
57011 가상 스토리지 또는 데이터베이스 자원을 사용할 수 없습니다.
57012 데이터베이스가 아닌 다른 자원을 사용할 수 없습니다. 이는 후속 명령문의 정상적인 실행에 영향을 주지 않습니다.
57013 데이터베이스가 아닌 다른 자원을 사용할 수 없습니다. 이는 후속 명령문의 정상적인 실행에 영향을 주지 않습니다.
57014 처리가 요청된 대로 취소되었습니다.
57016 테이블이 활성화되지 않으므로 액세스할 수 없습니다.
57017 문자 변환이 정의되지 않았습니다.
57019 자원 문제점으로 인해 명령문이 실패했습니다.
57020 데이터베이스가 들어 있는 드라이브가 잠겨 있습니다.
57021 디스켓 드라이브 문이 열려 있습니다.
57022 명령문의 권한 부여 ID가 적절한 DB 스페이스를 소유하지 않으므로 테이블을 작성할 수 없습니다.
57030 응용프로그램 서버(AS)로의 연결이 정의된 설치 한계를 초과했습니다.
57032 최대수의 동시 데이터베이스가 시작되었습니다.
57033 자동 롤백 없이 교착 상태 또는 시간종료가 발생했습니다.
57036 트랜잭션 로그가 현재 데이터베이스에 속하지 않습니다.
57046 데이터베이스 또는 인스턴스가 Quiesce 상태이기 때문에 새로운 트랜잭션을 시작할 수 없습니다.
57047 디렉토리에 액세스할 수 없기 때문에 내부 데이터베이스 파일을 작성할 수 없습니다.
57048 테이블 스페이스에 대한 컨테이너에 액세스하는 동안 오류가 발생했습니다.
57049 운영 체제 프로세스 한계에 도달했습니다.
57050 파일 서버가 현재 사용 가능하지 않습니다.
57051 계산된 CPU 비용이 자원 한계를 초과합니다.
57052 노드에 모든 임시 테이블 스페이스에 대한 컨테이너가 없으므로 이 노드를 사용할 수 없습니다.
57053 조작이 충돌되므로 테이블에서 조작을 수행할 수 없습니다.
57055 페이지 크기가 충분한 임시 테이블 스페이스를 사용할 수 없습니다.
57056 데이터베이스가 NO PACKAGE LOCK 모드에 있으므로 패키지를 사용할 수 없습니다.
57057 SQL문 DRDA 체인의 이전 상태로 인해 SQL문을 실행할 수 없습니다.
57059 테이블 스페이스에 지정된 조치에 사용할 수 있는 스페이스가 충분하지 않습니다.

클래스 코드 58 시스템 오류

표 39. 클래스 코드 58: 시스템 오류
SQLSTATE 값  
의미
58004 시스템 오류(후속 SQL문을 정상적으로 실행할 수는 있음)가 발생했습니다.
58005 시스템 오류(후속 SQL문을 정상적으로 실행하지 못하게 함)가 발생했습니다.
58008 후속 DDM 명령 또는 SQL문의 정상적인 실행에는 영향을 주지 않는 분산 프로토콜 오류로 인해 실행에 실패했습니다.
58009 대화가 할당해제되게 만드는 분산 프로토콜 오류로 인해 실행에 실패했습니다.
58010 후속 DDM 명령 또는 SQL 문의 정상적인 실행에 영향을 주는 분산 프로토콜 오류로 인해 실행에 실패했습니다.
58011 바인드 프로세스가 진행되는 동안 DDM 명령이 유효하지 않습니다.
58012 지정된 패키지명과 일치하는 토큰을 사용한 바인드 프로세스가 실행 중이 아닙니다.
58014 DDM 명령이 지원되지 않습니다.
58015 DDM 오브젝트가 지원되지 않습니다.
58016 DDM 매개변수가 지원되지 않습니다.
58017 DDM 매개변수 값이 지원되지 않습니다.
58018 DDM 응답 메시지가 지원되지 않습니다.
58023 시스템 오류로 인해 현재 프로그램이 취소되었습니다.
58030 입출력 오류가 발생했습니다.
58031 시스템 오류로 인해 연결에 실패했습니다.
58032 분리 모드 사용자 정의 함수(UDF)에 대한 프로세스를 사용할 수 없습니다.
58034 DMS 테이블 스페이스에서 오브젝트에 대한 페이지를 찾는 중에 오류가 발견되었습니다.
58035 DMS 테이블 스페이스에서 오브젝트에 대한 빈 페이지를 찾는 중에 오류가 발견되었습니다.
58036 지정된 내부 테이블 스페이스 ID가 없습니다.
ZZZZZ 플레이스 홀더 sqlstate는 개발용으로만 사용하십시오. 코드 이동 전 변경해야 합니다.

'DB2' 카테고리의 다른 글

Except 와 Except all  (1) 2007.03.16
SQL을 이용한 DB2 XML 데이터 쿼리  (0) 2007.02.14
DB2 Viper 시작하기  (0) 2007.02.14
DB2 INDEX 설계  (0) 2007.02.02
DB2에서 *.sql 파일을 읽어들여 실행하기  (0) 2006.12.31
 

SQL을 이용한 DB2 XML 데이터 쿼리

DB2 | 2007. 2. 14. 10:52
Posted by 시반

 

SQL을 이용한 DB2 XML 데이터 쿼리

 

난이도 : 초급

Cynthia M. Saracco, Senior Software Engineer, IBM

2006 년 12 월 26 일

DB2® 9(코드명 ‘Viper’)는 XML 데이터의 저장, 관리, 쿼리에 대한 새로운 지원 사항이 추가되었습니다. SQL과 SQL/XML을 사용하여 XML 칼럼에 저장된 데이터를 쿼리하는 방법을 배워봅시다. 후속 기술자료에서는 XQuery를 사용하여 XML 데이터를 쿼리하는 방법을 설명합니다.

DB2의 하이브리드(hybrid) 아키텍처는 이전 릴리스와는 많이 달라졌지만, 새로운 XML 기능을 활용하는 것은 그렇게 어려운 일은 아니다. SQL에 대해 잘 알고 있다면, DB2에 저장된 XML 데이터로 지금 즉시 작업할 수 있다.

DB2 9(코드명 ‘Viper’)의 XML 기능에는 새로운 스토리지 관리, 인덱싱, 쿼리 언어 지원이 포함된다. 이 글에서 SQL 과 SQL with XML extensions (SQL/XML)를 사용하여 DB2 XML 칼럼의 데이터를 쿼리하는 방법을 설명한다. 후속 기술자료에서는 XQuery에 대해 자세히 다룰 예정이다.

DB2가 Bilingual 쿼리(SQL과 XQuery의 식들을 결합한 쿼리)도 지원한다는 사실에 놀랄 것이다. 어떤 언어(또는 언어들의 조합)를 사용하든지 간에, 애플리케이션의 필요와 기술에 맞춰 선택해야 한다. 두 개의 쿼리 언어의 엘리먼트들을 하나의 쿼리로 결합하는 것은 생각만큼 어렵지 않다. 전통적인 SQL과 XML 데이터를 검색 및 통합하는 강력한 기능을 경험할 수 있을 것이다.

샘플 데이터베이스

이 글에서는 "DB2 Viper 시작하기 (한글)" (developerWorks, 2006년 7월)에서 만들었던 샘플 테이블에 액세스 할 것이다. 샘플 “아이템”과 “클라이언트” 테이블 샘플은 다음과 같이 정의된다.


Listing 1. 테이블 정의

 create table items ( id int primary key not null, brandname varchar(30), itemname varchar(30), sku int, srp decimal(7,2), comments xml ) create table clients( id int primary key not null, name varchar(50), status varchar(10), contactinfo xml ) 

"items.comments" 칼럼에 포함된 XML 데이터는 그림 1에 나타나 있다. "clients.contactinfo" 칼럼에 포함된 XML 데이터는 그림 2를 참조하라. 그 뒤에 나오는 쿼리 예제들은 이 XML 문서들에 있는 특정 엘리먼트들을 참조할 것이다.


그림 1. "items" 테이블의 "comments" 칼럼에 저장된 샘플 XML 문서



그림 2. "clients" 테이블의 "contactinfo" 칼럼에 저장된 XML 문서 샘플




쿼리 환경

이 글의 모든 쿼리들은 대화형으로 실행된다. DB2 명령행 프로세서(CLP)나 DB2 Control Center의 DB2 Command Editor를 통해서 이를 수행할 수 있다. 본문의 스크린 이미지와 명령어는 나중에 설명하겠다. (DB2 Viper에는 Eclipse 기반 Developer Workbench가 포함된다. 이 글에서는 애플리케이션 개발 문제 또는 Developer Workbench에 대해서는 다루지 않겠다.)

DB2 Command Editor를 사용하려면, Control Center를 시작하고 Tools > Command Editor를 선택한다. 그림 3과 비슷한 창이 나타날 것이다. 위쪽 창에 쿼리 내용을 입력하고, 왼쪽 상단 코너에 있는 녹색 화살표를 클릭하여 실행하고, 아래쪽 창 또는 개별 "Query results" 탭에서 아웃풋을 본다.


그림 3. DB2 Control Center에서 시작한 DB2 Command Editor





순수한 SQL 쿼리

SQL에 대해 잘 모르더라도, XML 데이터를 쿼리 할 수 있다. 다음 쿼리로는, "contactinfo" 칼럼에 저장된 XML 정보를 포함하여, “clients” 테이블의 전체 콘텐트를 선택한다.


Listing 2. SELECT 문

 select * from clients 

물론, 관계형 투영(projection)과 제약(restriction) 연산을 결합한, 보다 선택적인 SQL 쿼리들을 작성할 수 있다. 다음 쿼리는 “Gold”로 되어있는 모든 고객들의 아이디, 이름, 연락처 정보를 검색한다. "contactinfo"에는 XML 데이터가 있지만, 다른 두 개의 칼럼에는 없다는 것에 주의하라.


Listing 3. 투영과 제약을 이용한 SELECT 문

 select id, name, contactinfo from clients where status = 'Gold' 

아래 "goldview"에서 보듯, 이 같은 쿼리를 기반으로 뷰를 만들 수 있다.


Listing 4. XML 칼럼을 포함하고 있는 뷰 만들기

 create view goldview as select id, name, contactinfo from clients where status = 'Gold' 

SQL만 가지고는 할 수 없는 많은 일들이 있다. 플레인 SQL 문으로 전체 XML 문서를 가져올 수 있지만, XML 기반 쿼리 술어(predicate)를 지정할 수 없고, 부분적인 XML 문서를 가져오거나 XML 문서에서 특정 엘리먼트 값을 가져올 수 없다. 다시 말해서, 플레인 SQL을 사용해서는 XML 문서 조각들의 투영, 제한, 조인(join), 조합(aggregate), 순서 정하기(order)를 할 수 없다. 예를 들어, Gold 고객들의 이메일 주소나 우편번호 "95116”에 살고 있는 클라이언트의 이름조차도 가져올 수 없다. 이러한 유형의 쿼리를 실행하려면, SQL with XML extensions (SQL/XML), XQuery, 또는 이 두 가지를 결합한 것을 사용해야 한다.

다음 섹션에서는 SQL/XML의 기본적인 여러 기능들을 설명하겠다. XQuery 작성 방법과 XQuery와 SQL을 결합하는 방법을 설명한다.




SQL/XML 쿼리

이름에서 암시하듯, SQL/XML은 SQL과 XML을 결합한 것이다. SQL 표준 작업의 일환이며, 이제는 SQL 문에 XQuery와 XPath 식을 삽입하는 스팩도 포함되어 있다. XPath는 XML 문서들을 검색하여 엘리먼트나 애트리뷰트를 찾는 언어이다.

XQuery(XPath) 식은 대/소문자를 가린다. 예를 들어, XML 엘리먼트 “zip”을 참조하는 XQuery는 "ZIP" 또는 "Zip" 이라는 이름의 XML 엘리먼트에는 적용되지 않을 것이다. 대/소문자 구분이 된다는 사실은 SQL 프로그래머가 기억하기 어렵기 때문에, SQL 쿼리 신택스에서는 "zip", "ZIP", "Zip"을 사용하여 같은 칼럼 이름을 참조하도록 하고 있다.

DB2 Viper는 15개 이상의 SQL/XML 함수들을 갖고 있다. 이것으로, XML 문서 내의 특정 데이터를 검색할 수 있고, 관계형 데이터를 XML로 변환하고, XML 데이터를 관계형 데이터로 변환하고, 기타 유용한 태스크들을 수행할 수 있다. 이 글에서는 SQL의 모든 부분을 설명하지는 않을 것이다. 일반적인 쿼리 문제들을 짚어보고, 핵심 SQL/XML 함수들이 그러한 문제들을 어떻게 해결하는가를 볼 것이다.

XML 엘리먼트 값에 따라 결과 “제한하기”

SQL 프로그래머들은 특정 조건에 기반하여 DBMS에서 리턴된 행을 제한하는 쿼리를 작성하곤 한다. 예를 들어, Listing 3의 SQL 쿼리는 “clients” 테이블에서 가져온 행을 제한하여 "Gold" 상태에 있는 고객들만 포함하도록 제한시켰다. 이 경우, 고객의 상태는 SQL VARCHAR 칼럼에 캡쳐된다. 하지만, XML 칼럼에 있는 데이터에 적용할 조건에 기반하여 검색을 제한하고 싶다면 어떻게 하겠는가? SQL/XML의 XMLExists 함수가 이를 해결할 수 있다.

XMLExists는 XML 문서 내에 있는 엘리먼트를 검색하고, 특정 조건에 맞추어 테스트를 한다. XMLExistsWHERE문의 일부로서 지정되면, 이것은 리턴된 값을 특정 XML 엘리먼트 값을 갖고 있는 XML 문서를 포함한 행들로만 제한한다. (지정된 값은 “true”가 된다.)

앞서 발생했던 샘플 쿼리 문제에 대해 살펴보자. 특정 Zip Code에 살고 있는 모든 클라이언트의 이름을 배치해야 한다고 해보자. 기억하겠지만, “clients” 테이블은 XML 칼럼에 고객들의 주소(Zip Code 포함)를 저장한다. (그림 2) XMLExists를 사용하여, 목표 Zip Code에 대한 XML 칼럼을 검색하고, 리턴된 결과 세트를 이에 따라 제한할 수 있다. 다음 SQL/XML 쿼리는 Zip Code 95116에 살고 있는 클라이언트의 이름을 리턴한다.


Listing 5. XML 엘리먼트 값에 기반한 결과 제한

 select name from clients where xmlexists('$c/Client/Address[zip="95116"]' passing clients.contactinfo as "c") 

첫 번째 라인은 “clients” 테이블의 "name” 칼럼에 있는 정보만 검색한다는 것을 지정하는 SQL 문이다. WHERE 문은 XMLExists 함수를 호출하면서, DB2가 “zip” 엘리먼트를 검색하고 95116 값을 체크하도록 XPath 식을 지정하고 있다. "$c/Client/Address" 문은 DB2가 “zip” 엘리먼트를 두는 곳인 XML 문서 계층에 있는 경로를 가리킨다. "$c" 노드에서 액세스 할 수 있는 데이터를 사용하여, DB2는 "Client" 엘리먼트와 "Address" 하위 엘리먼트를 검색하여 Zip Code(“zip” 값)을 찾는다. 마지막 라인은 "$c" 의 값을 해석한 것이다. “clients” 테이블의 "contactinfo" 칼럼이라는 의미이다. 따라서, DB2는 "contactinfo" 칼럼에 저장된 XML 데이터를 보고, 루트 "Client" 엘리먼트에서 "Address"로, 그리고 "zip”으로 검색하고, 그 고객이 목표 Zip Code에 살고 있는지를 결정한다. 만약 그렇다면, XMLExists 함수는 "true”로 연산되고, DB2는 그 행과 관련된 클라이언트의 이름을 리턴한다.

일반적으로 실수하는 것 중에는 XMLExists 쿼리 술어에 대한 수식도 포함된다. (Listing 6)


Listing 6. XML 엘리먼트 값에 기반하여 값을 제한하는 틀린 신택스

 select name from clients where xmlexists('$c/Client/Address/zip="95116" ' passing clients.contactinfo as "c") 

쿼리는 성공적으로 실행되겠지만, 결과를 Zip Code 95116에 살고 있는 클라이언트로 제한하지 않는다. (표준에서 이렇게 정의하고 있다. DB2는 표준을 준수할 뿐이다.) 값을 Zip Code 95116에 살고 있는 클라이언트로 제한하려면, Listing 5에서 보았던 신택스를 사용해야 한다.

애플리케이션에서 XML 데이터를 제한하는 쿼리를 포함시키는 방법도 궁금할 것이다. 이 글에서는 애플리케이션 개발에 대해서는 자세히 설명하지 않을 것이다. 아웃풋을 주어진 Zip Code에 살고 있는 고객에 대한 정보로 제한하는 SQL/XML 문 내에 매개변수 마커를 사용하는 자바 예제가 포함되어 있다.

XML 엘리먼트 값의 “투영(Projecting)”

약간 다른 상황에 대해 생각해 보자. XML 값을 리턴된 결과 세트에 투영(project)한다고 해보자. 다시 말해서, 우리 XML 문서에서 한 개 이상의 엘리먼트 값을 가져와야 한다고 해보자. 여러 가지 방법들이 있다. 먼저, XMLQuery 함수를 사용하여 한 엘리먼트에 대한 값을 가져오고, XMLTable 함수를 사용하여 여러 엘리먼트에 대한 값을 가져오고, 이들을 SQL 결과 세트의 칼럼에 매핑시킨다.

이전에 발생했던 문제를 해결해 보자. Gold 고객들의 이메일 주소를 기록한 리포트를 만드는 방법에 대해 알아보자. Listing 7의 다음 쿼리는 XMLQuery 함수를 호출하여 이 태스크를 수행한다.


Listing 7. 해당 고객의 이메일 정보 가져오기

 select xmlquery('$c/Client/email' passing contactinfo as "c") from clients where status = 'Gold' 

첫 번째 라인은 루트 "Client" 엘리먼트에서 "email" 하위 엘리먼트에 대한 값을 리턴 한다고 지정한다. 두 번째와 세 번째 라인에서는 DB2가 그 정보를 찾을 수 있는 곳을 가리킨다. "clients" 테이블의 "contactinfo" 칼럼이다. 네 번째 라인은 Gold 고객의 이메일 주소에만 관심이 있다는 것을 나타내고 있다. 이 쿼리는 XML 엘리먼트 세트와 값을 리턴한다. 예를 들어, 500 명의 Gold 고객들이 있으면, 각각 한 개의 이메일 주소가 있고, 아웃풋은 500개의 행을 가진 한 개 칼럼의 결과 세트가 될 것이다. (Listing 8)


Listing 8. 이전 쿼리에 대한 샘플 아웃풋

 1 -------------------------------------------- <email>user5976@anyprovider.com</email> . . . <email>someID@yahoo.com</email> 

Gold 고객들이 각각 여러 개의 이메일 주소를 갖고 있을 경우, 주 이메일 주소만 리턴하도록 DB2에 명령할 수도 있다. (고객의 "contactinfo" 문서에서 찾은 첫 번째 이메일 주소) 이렇게 하려면, 쿼리의 첫 번째 라인에서 XPath 식을 변경한다.


Listing 9. 해당 고객의 첫 번째 이메일 주소 가져오기

 select xmlquery('$c/Client/email[1]' passing contactinfo as "c") from clients where status = 'Gold' 

마지막으로, 일부 Gold 고객들의 이메일 주소가 없다면, 결과 세트에서 null을 배제하도록 쿼리를 작성해야 한다. 소실된 이메일 정보가 있는지 테스트하기 위해 WHERE 문에 또 다른 술어를 추가하여, 이전 쿼리를 수정한다. 이미 이렇게 할 수 있는 SQL/XML 함수는 익숙할 것이다. 바로 XMLExists이다. Listing 10은 이전 쿼리를 다시 써서, (XML로 저장된) 연락처 정보에 이메일 주소가 없는 Gold 고객들의 행을 거르는 방법이다.


Listing 10. 최소 한 개의 이메일 주소를 갖고 있는 해당 고객의 첫 번째 이메일 주소 가져오기

 select xmlquery('$c/Client/email[1]' passing contactinfo as "c") from clients where status = 'Gold' and xmlexists('$c/Client/email' passing contactinfo as "c") 

약간 다른 상황을 생각해 보자. 여러 XML 엘리먼트 값을 가져와야 하는 경우를 생각해 보자. XMLTable은 XML 칼럼에 저장된 데이터에서 테이블 형태의 아웃풋을 만들고, 프로그래머들이 XML 데이터의 관계를 볼 수 있도록 한다. XMLExistsXMLQuery와 마찬가지로, XMLTable 함수는 DB2가 XML 문서 계층을 검색하여 관심 있는 데이터를 배치하도록 한다. 하지만, XMLTable에는 대상 XML 데이터를 SQL 데이터 유형의 결과 세트 칼럼으로 매핑하는 문도 포함된다.

다음 쿼리(Listing 11)를 생각해 보자. "items" 테이블에 저장된 관계형 데이터와 XML 데이터에서 칼럼을 투영한다. (그림 1의 "items" 테이블 참조) comment ID, customer ID, 메시지가 "comments" 칼럼에 있는 XML 문서에 저장된다. 아이템 이름은 SQL VARCHAR 칼럼에 저장된다.


Listing 11. 여러 XML 엘리먼트를 가져와서 각각 SQL 데이터 유형으로 변환하기

 select t.Comment#, i.itemname, t.CustomerID, Message from items i, xmltable('$c/Comments/Comment' passing i.comments as "c" columns Comment# integer path 'CommentID', CustomerID integer path 'CustomerID', Message varchar(100) path 'Message') as t 

첫 번째 라인은 결과 세트에 포함될 칼럼들을 지정하고 있다. 다음의 쿼리 라인이 가리키는 것처럼, 인용 부호가 있고 "t" 변수가 앞에 붙은 칼럼은 XML 엘리먼트 값에 기반하고 있다. 두 번째 라인은 XMLTable 함수를 호출하여 목표 데이터 ("i.comments")를 포함하고 있는 DB2 XML 칼럼을 지정하고, 해당 엘리먼트가 배치 (루트 "Comments" 엘리먼트의 "Comment" 하위 엘리먼트 내)되는 칼럼의 XML 문서 안의 경로를 지정한다. 세 번째 라인에서 다섯 번째 라인까지 이어지는 "columns" 문은 첫 번째 라인에서 지정된 SQL 결과 세트에 있는 아웃풋 칼럼으로 매핑 될 XML 엘리먼트를 구분한다. 매핑의 일부는 XML 엘리먼트 값이 변환될 데이터 유형들을 지정한다. 이 예제에서, 모든 XML 데이터는 SQL 데이터 유형들로 변환된다.

그림 4는 이 쿼리를 실행한 결과이다. 아웃풋은 단순한 SQL 결과 세트이다. 칼럼 이름들이 대문자로 표시되는데, 이는 SQL에서는 흔히 있는 일이다.


그림 4. XMLTable 함수를 사용한 쿼리의 결과


XMLTable을 사용하여 XML 칼럼도 포함한 결과 세트를 만들 수 있다. 예를 들어, 다음 문은 이전 것과 비슷한 결과 세트를 만든다. 단, "Message" 데이터가 SQL VARCHAR 칼럼이 아닌 XML 칼럼에 포함되는 것만 다르다.


Listing 12. 여러 XML 엘리먼트를 가져와서, 이들을 SQL 또는 XML 데이터 유형으로 변환하기

 select t.Comment#, i.itemname, t.CustomerID, Message from items i, xmltable('$c/Comments/Comment' passing i.comments as "c" columns Comment# integer path 'CommentID', CustomerID integer path 'CustomerID', Message XML by ref path 'Message') as t 

XML 데이터의 관계 뷰 만들기

SQL/XML 함수들은 뷰를 정의하는데도 사용된다. SQL 애플리케이션 프로그래머들에게 XML 데이터의 관계 모델을 보여줄 때 특히 유용하다.

XML 칼럼에 있는 데이터들의 관계 뷰를 만드는 것은 XML 엘리먼트 값을 투영하는 것 보다 복잡하지 않다. XMLTable 함수를 호출하는 SQL/XML SELECT 문을 작성하고, 이것을 뷰 정의의 기초로 사용한다. Listing 13에 나와있는 예제는 "items" 테이블의 XML 및 비 XML 칼럼에 있는 정보에 기반한 뷰를 만든다. (Listing 11의 쿼리와 비슷하다.)


Listing 13. XMLTable의 결과에 기반하여 뷰 만들기

 create view commentview(itemID, itemname, commentID, message, mustrespond) as select i.id, i.itemname, t.CommentID, t.Message, t.ResponseRequested from items i, xmltable('$c/Comments/Comment' passing i.comments as "c" columns CommentID integer path 'CommentID', Message varchar(100) path 'Message', ResponseRequested varchar(100) path 'ResponseRequested') as t; 

XML 칼럼 데이터에 대한 관계 뷰를 만드는 것은 쉽지만, 사용에 대해서는 신중하게 생각해야 한다. 이 같은 뷰에 대해 쿼리가 실행될 때 DB2는 XML 칼럼 인덱스를 사용하지 않는다. 따라서, ResponseRequested 엘리먼트를 인덱싱 하고, "mustrespond" 칼럼의 결과를 특정 값으로 제한하는 SQL 쿼리를 실행한다면, DB2는 모든 XML 문서를 읽고 알맞은 "ResponseRequested" 값을 찾을 것이다. 데이터 양이 많다면 런타임 성능이 느려진다. 하지만, 쿼리에 전통적인 SQL 유형(이 예제에서는 "i.id" 또는 "i.itemname")의 칼럼을 포함한 매우 제한적인 술어가 포함된다면, 결과 셋이 적어지기 때문에 성능이 많이 악화되는 것을 막을 수 있다. DB2는 관계형 인덱스를 사용하여 해당 행들을 작은 수로 필터링 하고, 최종 결과 세트를 리턴하기 전에, 추가 XML 쿼리 술어를 중간 결과에 적용한다.

XML과 관계형 데이터 조인(join)

XML 데이터를 비 XML 데이터(예를 들어, 전통적인 SQL 유형에 기반한 관계형 데이터)와 합치는(join) 것도 궁금할 것이다. DB2에서는 SQL/XML 문으로 이를 수행한다. 데이터베이스 스키마와 위크로드에 따라, 조인(join)을 수행하는 여러가지 방법들이 있지만, 여기에서는 한 가지 예제만 설명하겠다. 사실상, 여러분은 이 작업의 수행을 통해 SQL/XML에 대해 이미 알고 있음을 인지하게 될 것이다.

"items" 테이블에 있는 XML 칼럼에 "CustomerID" 엘리먼트가 포함된다는 것을 기억하는가? 이것이 "clients" 테이블의 정수 기반 "id" 칼럼에 대한 조인 키(join key)로서 작동할 수 있다. 한 개 이상의 제품들에 대해 코멘트를 달았던 고객의 이름과 상태에 대한 리포트가 필요하면, 한 테이블에서 나온 XML 엘리먼트 값을 다른 테이블에서 나온 SQL 정수 값과 합쳐야 한다. 한 가지 방법은 XMLExists 함수를 사용하는 것이다. (Listing 14)


Listing 14. XML과 비 XML 데이터 합치기

 select clients.name, clients.status from items, clients where xmlexists('$c/Comments/Comment[CustomerID=$p]' passing items.comments as "c", clients.id as "p") 

첫 번째 라인은 쿼리 결과 세트와 쿼리에서 참조되는 소스 테이블에 포함될 SQL 칼럼을 지정한다. 두 번째 라인에는 join 문이 포함된다. XMLExists는 한 개의 목표 소스에 있는 "CustomerID" 값이 또 다른 목표 소스에서 가져온 값과 같은지를 결정한다. 세 번째 라인은 이러한 소스들을 지정한다. 첫 번째는 “items” 테이블에 있는 "comments" XML 칼럼이고, 두 번째는 "clients" 테이블의 정수 "id" 칼럼이다. 따라서, 고객이 아이템에 대해 코멘트를 달았고 이 고객에 대한 정보가 "clients" 테이블에서 사용할 수 있다면, XMLExists 식은 "true" 가 되고 클라이언트의 이름과 상태 정보가 그 리포트에 포함될 것이다.

SQL/XML에서 "FLWOR" 식 사용하기

일부 함수들만 설명했지만, SQL/XML은 XML 데이터를 쿼리하고, 그 데이터를 관계형 데이터로 통합하는 강력한 기능들을 갖고 있다. 몇 가지 예제를 통해 이를 수행하는 방법을 배웠지만, 이 부분에서는 더 자세히 설명하도록 하겠다.

XMLExistsXMLQuery 함수를 사용하여 XQuery를 SQL로 결합할 수 있다. 이전 예제에서는 간단한 XPath 식으로 이러한 함수들을 사용하여 해당 XML 문서 부분을 검색하는 방법을 설명했다. 이제는, XQuery를 SQL 쿼리에 포함시키는 예제를 생각해 보자.

XQuery에는 "for," "let," "where," "order by", "return" 문들의 일부 또는 전체가 포함된다. 이들이 모여서 FLWOR (flower로 발음함) 식을 만든다. SQL 프로그래머들은 XQuery를 SELECT 리스트로 결합하여 XML 문서 조각들을 결과 세트로 추출(또는 투영)하는 것이 간단하다는 것을 깨닫게 될 것이다. 이것이 XMLQuery 함수가 사용되는 유일한 방법은 아니지만, 이 글에서는 이 부분에 대해서만 설명하겠다. (다음 글에서 XQuery에 대해 자세히 설명하겠다.)

"Gold" 고객들의 이름과 기본 이메일 주소를 가져와야 한다. 이 작업은 XML 엘리먼트 값을 투영하는 방법과 비슷하다. (Listing 9) 여기에서는 인풋으로 XQuery("for"와 "return" 문과 함께)를 XMLQuery 함수로 전달한다.


Listing 15. XQuery의 "for"와 "return" 문을 사용하여 XML 데이터 가져오기

 select name, xmlquery('for $e in $c/Client/email[1] return $e' passing contactinfo as "c") from clients where status = 'Gold' 

첫 번째 라인은 XMLQuery 함수에서 온 고객 이름과 아웃풋이 결과 세트에 포함되어야 할 것을 지정하고 있다. 두 번째 라인은 "Client" 엘리먼트의 하위 엘리먼트인 "email"이 리턴 되어야 한다고 지정하고 있다. 세 번째 라인은 XML 데이터의 소스인 "contactinfo" 칼럼을 가리키고 있다. 네 번째 라인은 이 칼럼이 "clients” 테이블에 있다는 것을 알려준다. 마지막으로, 다섯 번째 라인은 “Gold” 고객들만 해당한다는 것을 나타내고 있다.

이 예제는 매우 간단하기 때문에, 여러분도 같은 쿼리를 작성할 수 있다. 대신, 더 간소하게 같은 쿼리를 작성할 수 있다.


Listing 16. 이전 쿼리를 더 간단하게 작성하기

 select name, xmlquery('$c/Client/email[1]' passing contactinfo as "c") from clients where status = 'Gold' 

XQuery의 return 문으로 XML 아웃풋을 변형할 수 있다. 예를 들어, 이메일 엘리먼트 값을 추출하여 이들을 HTML로 표현할 수 있다. 다음 쿼리는 각 Gold 고객들의 첫 번째 이메일 주소가 HTML로 리턴된 결과 세트를 만들어 낼 것이다.


Listing 17. XML을 HTML로 변형하기

 select xmlquery('for $e in $c/Client/email[1]/text() return <p>{$e}</p>' passing contactinfo as "c") from clients where status = 'Gold' 

첫 번째 라인은 해당 고객의 첫 번째 이메일 주소의 텍스트 표현에 관심이 있다는 것을 나타내고 있다. 두 번째 라인은, 이 정보가 리턴 되기 전에 HTML 태그로 되어 있어야 한다고 지정하고 있다. 특히, 중괄호( { } )는 리터럴 스트링으로서 취급하기 보다는 식("$e")을 계산하도록 명령하고 있다. 중괄호를 생략한다면, DB2는 모든 해당 고객 레코드에 대해 "<p>$e</p>"를 포함하고 있는 결과 세트를 리턴할 것이다.

XML을 관계형 데이터로서 공개(publish)하기

지금까지는 DB2 XML 칼럼에 저장된 데이터를 쿼리, 추출, 변형하는 방법을 설명했다. 이러한 기능들은 SQL/XML을 사용하면 모두 가능하다.

SQL/XML은 다른 기능들도 제공한다. 이 중에서 관계형 데이터를 XML로 변환 및 공개(publish)하는 기능이 있다. 여기에서 다룰 함수들은 XMLElement, XMLAgg, XMLForest이다.

XMLElement는 SQL 칼럼에 저장된 데이터를 XML 조각들로 변환한다. (XML 애트리뷰트가 있거나 또는 없는) XML 엘리먼트를 기본 SQL 데이터에서 구현할 수 있다. 다음 예제는 XMLElement 함수를 사용하여 아이템 엘리먼트를 만드는 예제이다. 각각 "items" 테이블에서 가져온 아이디, 브랜드 이름, stock keeping unit ("sku") 하위 엘리먼트 값이 있다.


Listing 18. XMLElement를 사용하여 관계형 데이터를 XML로 전개하기

 select xmlelement (name "item", xmlelement (name "id", id), xmlelement (name "brand", brandname), xmlelement (name "sku", sku) ) from items where srp < 100 

이 쿼리를 실행하면 다음과 같은 결과가 나온다.


Listing 19. 이전 쿼리의 결과

 <item> <id>4272</id> <brand>Classy</brand> <sku>981140</sku> </item> . . . <item> <id>1193</id> <brand>Natural</brand> <sku>557813</sku> </item> 

XMLElement를 다른 SQL/XML 퍼블리싱 함수들과 결합하여 XML 값들을 구현 및 그룹핑 하고, 원하는 대로 계층에 포함시킬 수 있다. Listing 20의 예제는 XMLElement를 사용하여 customerList 엘리먼트를 만든다. 이것의 콘텐트는 "status" 칼럼에 있는 값들로 그룹핑 된다. 각 "customerList" 레코드에서, XMLAgg 함수는 일련의 고객 엘리먼트를 리턴하는데, 각각 "name"과 "status" 칼럼에 기반하여 하위 엘리먼트를 포함하고 있다. 그리고, 고객 엘리먼트 값은 고객 이름 순서대로 되어있다.


Listing 20. 데이터 모으기 및 그룹핑

 select xmlelement(name "customerList", xmlagg (xmlelement (name "customer", xmlforest (name as "fullName", status as "status") ) order by name ) ) from clients group by status 

"clients" 테이블에 세 개의 "status" 값들이 있다고 생각해 보자. 각각 "Gold”, "Silver”, "Standard” 이다. 이전 쿼리를 실행하면 DB2는 세 개의 customerList 엘리먼트를 리턴할 것이다. 이때, 각각 이름과 상태 정보를 포함하고 있는 고객의 하위 엘리먼트들이 있을 것이다. 따라서 결과는 다음과 같다.


Listing 21. 이전 쿼리의 결과

 <customerList> <customer> <fullName>Chris Bontempo</fullname> <status>Gold</status> </customer> <customer> <fullName>Ella Kimpton</fullName> <status>Gold</status> </customer> . . . </customerList> <customerList> <customer> <fullName>Lisa Hansen</fullName> <status>Silver</status> </customer> . . . </customerList> <customerList> <customer> <fullName>Rita Gomez</fullName> <status>Standard</status> </customer> . . . </customerList> 




Update 및 Delete 연산

이 글의 목적은 SQL을 사용하여 XML 칼럼에 저장된 데이터를 검색 및 가져오는 방법을 설명하는 것이지만, XML 칼럼에 있는 데이터를 업데이트 및 삭제하는 방법도 알아 둘 필요가 있다.

DB2에서는 SQL과 SQL/XML 문을 사용하여 XML 데이터를 업데이트 및 삭제할 수 있다. 실제로, XQuery 표준의 초안은 이 문제를 다루지 않기 때문에, DB2 사용자들은 이러한 태스크를 수행할 때 SQL에 의지해야만 한다.

XML 데이터 업데이트

DB2는 SQL UPDATE 문 또는 시스템에서 제공하는 저장 프로시저(DB2XMLFUNCTIONS.XMLUPDATE)를 사용하여 XML 칼럼을 업데이트 한다. 두 경우 모두, XML 칼럼 업데이트는 엘리먼트 레벨이 아닌 문서 레벨에서 수행한다. 하지만 저장 프로시저를 사용하여 업데이트 하는 프로그래머들은 전체 XML 문서를 DB2에 제공할 필요가 없다. 업데이트 될 XML 엘리먼트를 지정하고, DB2는 변경되지 않은 문서 데이터를 보존하고, 지정된 엘리먼트만 업데이트 하면 된다. UPDATE 문을 실행하는 프로그래머는 전체 문서를 지정해야 한다. (변경하고자 하는 엘리먼트만 지정하는 것이 아니다.)

예를 들어, 특정 고객의 연락처 정보에서 이메일 주소를 변경하기 위해 UPDATE 문을 실행해야 한다면, 새로운 이메일 엘리먼트 값뿐만 아니라, XML 칼럼에 포함된 전체 연락처 정보를 제공해야 한다. 그림 2를 보면, "Address" 정보, "phone" 정보, "fax" 정보, "email" 정보가 포함되어 있다.

다음 문을 보자.


Listing 22. UPDATE 문 샘플

 update clients set contactinfo=( xmlparse(document '<email>newemail@someplace.com</email>' ) ) where id = 3227 

DB2 Viper 시작하기 (한글)” 에서 XML 데이터를 삽입하는 방법을 떠올려 보면, 유사하다는 것을 알 수 있다. 다른 SQL UPDATE 문과 마찬가지로, 이 예제는 업데이트 될 테이블과 칼럼을 먼저 지정하고 있다. 목표 칼럼에 XML 데이터가 포함되기 때문에, 새로운 목표 값으로 완성된 XML 문서를 주어야 한다. 대부분의 실행 환경은 호스트 변수 또는 매개변수 마커를 애플리케이션에 사용하여 XML 데이터를 업데이트 하는 반면, 나는 여기에서 이를 번갈아 가며 수행하는 방법을 설명했다. 두 번째 라인은 XMLParse 함수를 사용하여 인풋 스트링을 XML로 변환한다. 마지막 라인은 업데이트를 테이블의 특정 행으로 제한하는 표준 SQL 문이다.

앞의 UPDATE 문을 실행하면, 3227 고객의 "contactinfo" 칼럼에 이메일 정보만 포함된다. (Listing 23)


Listing 23. UPDATE 문 실행 결과

 <email>newemail@someplace.com</email> 

고객의 주소, 전화 번호, 팩스 번호는 소실된다. (그림 2) 게다가, 고객의 이메일 주소를 추출하기 위해 작성했던 이전 쿼리 일부가 이것을 찾아내지 못한다. 이전 쿼리에는 특정 문서 계층을 통해 검색했던 XPath 또는 XQuery 식이 포함되었기 때문이다. Client는 루트 엘리먼트였고 이메일은 하위 엘리먼트였다. 이 문서를 업데이트 한 후에는, 이메일은 이제 이 고객의 XML 레코드의 루트 엘리먼트가 된다. 따라서, 그 계층의 위치에서는 값을 찾을 수 없는 것이다.

고객의 이메일 주소를 업데이트 하고, 기존의 다른 연락처 정보는 유지하고 싶다면 쿼리를 다시 작성해야 한다. (Listing 24)


Listing 24. UPDATE 문 수정

 update clients set contactinfo= (xmlparse(document '‘<Client> <Address> <street>5401 Julio Ave.</street> <city>San Jose</city> <state>CA</state> <zip>95116</zip> </Address> <phone> <work>4084633000</work> <home>4081111111</home> <cell>4082222222</cell> </phone> <fax>4087776666</fax> <email>newemail@someplace.com</email> </Client>' ) ) where id = 3227 

전체 XML 문서를 주지 않고 뷰를 통해 업데이트 하는 방법이 궁금할 것이다. 예를 들어, Listing 13에서 정의된 commentview는 XMLTable 함수를 사용하여 XML 칼럼의 특정 엘리먼트를 추출하고, 이들을 뷰에 있는 SQL 칼럼으로 변형한다. SQL 칼럼들 중 한 개의 값을 업데이트 하고, 그 결과를 원래 XML 문서의 정확한 하위 엘리먼트에 작성하는 것이 가능한가? 그렇지 않다. DB2는 SQL 유형에 기반한 뷰 칼럼과 함수(이 경우, XMLTable 함수)의 결과에서 가져온 뷰 칼럼을 구분한다. 후자의 업데이트 방식은 지원되지 않는다.

XML 데이터 삭제하기

XML 칼럼을 포함한 행을 삭제하는 것은 간단하다. SQL DELETE 문을 사용하여 WHERE 문에서 삭제하고 싶은 행을 지정(또는 제한)할 수 있다. 이 문에는 XML 칼럼 값이나 SQL/XML 함수들을 지정하는 술어가 포함되어 XML 칼럼 내에 포함된 XML 엘리먼트 값을 구분하고 있다.

다음은 고객 ID 3227에 대한 모든 고객 정보를 삭제하는 방법이다.


Listing 25. 특정 클라이언트의 데이터 삭제하기

 delete from clients where id = 3227 

Zip Code 95116에 살고 있는 고객들에 대한 행만 리턴하도록 SQL SELECT 문을 제한하는 방법을 기억하는가? 그렇다면, 그러한 고객들을 트래킹 하는 행을 삭제하는데도 적용할 수 있다. 다음은 XMLExists를 사용하는 방법이다.


Listing 26. 특정 Zip Code 내에 있는 클라이언트용 데이터 삭제하기

 

 delete from clients where xmlexists('$c/Client/Address[zip="95116"]' passing clients.contactinfo as "c"); 


인덱싱(Indexing)

마지막으로, 특별한 XML 인덱스를 만들어서 XML 칼럼에 저장된 데이터로의 액세스 속도를 높이는 방법도 있다. 이 글은 Indexing에 대한 개요이고, 샘플 데이터도 작기 때문에 이 부분은 설명하지 않겠다. 하지만, 실행 환경에서, 알맞은 인덱스를 정의하는 것은 최적의 성능을 얻는데 있어 중요한 요소이다. 참고자료 섹션에서 새로운 DB2 인덱싱 기술을 참조하기 바란다.




요약

SQL/XML의 핵심 부분들과, 이를 사용하여 XML 칼럼에 있는 데이터를 쿼리하는 방법을 설명했다. 여기에서 설명한 것 이상으로 SQL과 SQL/XML 함수들을 사용하여 할 수 있는 일들이 많이 있다. 본문에 포함된 자바 예제들을 통해 SQL/XML의 매개변수 마커를 사용하여 XML 칼럼에 있는 데이터를 쿼리하는 방법을 설명했다. 향후 기술자료에서는 애플리케이션 개발에 대해 자세히 설명하도록 하겠다. 물론, DB2 Viper에서 지원되는 새로운 쿼리 언어인 XQuery에 대해서도 설명할 것이다.

감사의 말

도움을 주신 George Lapis, Matthias Nicola, Sriram Padmanabhan, Gary Robinson, Hardeep Singh, Bert Van der Linden에게 감사의 말을 전하고 싶다.

기사의 원문보기



 

참고자료

교육


제품 및 기술 얻기


토론



 

필자소개

 

C. M. Saracco는 IBM Silicon Valley Laboratory의 DB2 XML 분야에서 일하고 있다. 데이터베이스 관리, XML, 웹 애플리케이션 개발을 수행하고 있다.

 

 

출처 : 한국 developerWorks  

'DB2' 카테고리의 다른 글

Except 와 Except all  (1) 2007.03.16
[본문스크랩] DB2 SQLSTATE 메시지  (0) 2007.02.23
DB2 Viper 시작하기  (0) 2007.02.14
DB2 INDEX 설계  (0) 2007.02.02
DB2에서 *.sql 파일을 읽어들여 실행하기  (0) 2006.12.31
 

DB2 Viper 시작하기

DB2 | 2007. 2. 14. 10:37
Posted by 시반

DB2 Viper 시작하기 (한글)

 

난이도 : 초급

Cynthia M. Saracco, Senior Software Engineer, IBM

2006 년 7 월 28 일

베타 버전으로 릴리스 된 DB2® Viper는 XML 데이터의 저장, 관리, 검색에 대한 새로운 기능을 제공합니다. 이 글에서는 XML 데이터를 관리하기 위한 데이터베이스 객체를 만들고 DB2 데이터베이스에 XML 데이터를 구축하는 방법을 설명합니다.

독자는 IBM에서 테이블형(SQL-기반), 계층형(XML-기반) 데이터 구조를 지원하는 최초의 DBMS인 새로운 DB2 Viper 릴리즈에 대해서 들었는지도 모른다. DB2의 새로운 “native” XML 지원이 궁금하고 이에 대해 알고 싶다면 이 글은 많은 도움이 될 것이다.

DB2의 native XML 기능에 빨리 다가서기 위해서 다음과 같은 공통적인 작업이 필요하다.

  1. 테스트 데이터베이스, 샘플 테이블 및 뷰를 포함한 XML 데이터 관리를 위한 데이터베이스 객체 생성
  2. INSERTIMPORT statements 문장을 이용해 XML 데이터로 데이터베이스 구축하기
  3. XML 데이터 검증하기. DB2로 XML 스키마 개발 및 등록, 데이터를 들여올 경우 XMLVALIDATE 옵션 이용하기

후속 기술문서에서는 SQL을 이용한 XML 데이터 조회, 갱신, 삭제, XQuery를 이용한 조회, DB2 XML 데이터를 처리하는 Java application 및 Web components를 다룬다.

데이터베이스 객체 생성하기

우선 단일 DB2 유니코드 데이터베이스를 생성해 보자. DB2 Viper에서는 유니코드 데이터베이스만이 XML 문서 및 정수, 날짜/시간, 가변 길이 문자열 등과 같은 전형적인 SQL 데이터 형태를 저장할 수 있다. 추후에는 위 데이터베이스에 XML 및 다른 형태의 데이터를 모두 관리하는 객체를 생성할 것이다.

테스트 데이터베이스 생성하기

새로운 DB2 유니코드 "test" 데이터베이스를 생성하려면 DB2 명령 윈도우를 열고 Listing 1에 나오는 유니코드 코드셋 지원영역을 지정하는 Statement를 실행한다.


Listing 1. XML데이터를 저장하기 위한 데이터베이스 생성하기

				
create database test using codeset UTF-8 territory us 

일단, 유니코드 데이터베이스를 생성하면 XML 데이터를 native 계층형 포맷으로 저장하기 위한 더 이상의 추가적인 명령이나 action은 불필요하다.

샘플 테이블 생성하기

XML 데이터를 저장하려면 한 개 이상의 XML 열을 포함한 테이블을 생성한다. 이런 테이블은 문서들에 대한 논리적 container 역할을 한다. DB2는 실제로 XML 및 표면화되어 있지 않지만 내부적으로, 비-XML 데이터에 관해 각기 다른 데이터 저장방식을 사용한다. 특히 단일 쿼리에서 다른 형태의 데이터들을 통합해야 할 경우에는 더욱 그렇다. 하지만, 형태가 다르다 할지라도 지원되는 모든 형태의 데이터를 관리하기 위한 논리적 객체로 테이블을 사용함으로써 운영 및 application 개발 문제를 단순화 시킬 수 있다.

사용자는 XML 형식의 열만을 가진 테이블, 일반적인 SQL 형태의 열만을 가진 테이블, 두 형태를 모두 포함하는 테이블을 정의할 수 있다. 이 글에서는 마지막 경우를 모델화한다. Listing 2에서의 예는 “test” 데이터베이스에 연결하고 두 개의 테이블을 생성한다. 첫 번째 테이블은 “items” 테이블로 판매항목 및 고객이 판매항목에 대해 내린 평가에 관한 정보를, 두번째 테이블은 “clients” 테이블로 연락 데이터를 포함한 고객에 대한 정보를 저장한다. 여기서 “comments” 및 “contactinfo”열은 새로운 DB2 XML 데이터 형태이고, 다른 열은 기존의 SQL 데이터 타입이다.


Listing 2. XML 데이터에 관한 테이블 생성

				
connect to test;

create table items (
  id          int primary key not null, 
  brandname   varchar(30), 
  itemname    varchar(30), 
  sku         int, 
  srp         decimal(7,2), 
  comments    xml
);

create table clients(
  id          int primary key not null, 
  name        varchar(50), 
  status      varchar(10), 
  contactinfo xml
);

위 테이블 정의를 자세히 보면 두 테이블 다 “comments” 또는 “contactinfo”열에 저장된 XML 문서의 내부구조가 명시되지(specified) 않았다는 사실을 알게 된다. 이는 DB2의 중요한 특징이다. 사용자들은 데이터를 저장하기 위해 XML 데이터구조(또는 더 정확하게 말하면 XML 스키마)를 미리 정의할 필요가 없다. 사실, DB2는 어떠한 well-formed XML 문서를 한 열에 저장할 수 있고 이는 다른 XML schema를 따르는 문서나 등록된 XML schema와 관련이 없는 문서도 동일한 열에 저장할 수 있다는 것을 의미한다.이 글에서는 DB2에서 데이터를 저장하는 방법을 설명할 때 이와 같은 특징에 대해 더 자세히 논하기로 한다.

뷰 생성하기

기존의 SQL 데이터 형태만 포함하는 테이블에 대해 뷰를 생성하는 것처럼 XML 데이터를 포함하는 테이블에 대해 View를 생성할 수 있다. Listing 3에서는 status가 "Gold" 인 client에 대한 View를 생성한다.


Listing 3. XML 데이터를 포함한 뷰 생성하기

				
create view goldview as 
select id, name, contactinfo 
from clients where status='Gold'; 

인덱스에 관한 사항

최종적으로, XML 열에 대해 인덱스를 생성해 데이터 검색을 빠르게 할 수 있다는 점은 알아둘 필요 있다. 이 글은 초보자들을 위한 글이고 샘플 데이터 규모도 작아, 그와 같은 주제를 여기선 다루지 않기로 한다. 하지만 실제 운영 상황에서 최적의 성능을 위해 적절한 인덱스를 정의하는 것은 매우 중요하다. DB2의 새로운 인덱싱 기술에 관해 자세히 알아보기 위해서는 이 글 끝에 참고자료 섹션을 참조하라.




XML 데이터 저장하기

이제 생성된 테이블을 이용해 데이터를 구축할 수 있다. 직접 SQL INSERT 문을 실행하거나 DB2 IMPORT 기능을 이용할 수 있다. IMPORT 기능은 결국 내부적으로 INSERT 문을 수행한다.

INSERT 문장 사용하기

사용자는 INSERT 문으로 직접 원시 XML 데이터를 DB2에 넣을 수 있다. 애플리케이션을 작성하거나 변수에 저장된 XML 데이터를 이용해 입력하는 경우에는 아마 가장 쉬운 방법일 수도 있다. 그러나 우선 DB2 Viper로 시작했고 애플리케이션을 작성하려 하지 않을 경우에는 INSERT문을 대화식으로 실행할 수 있다. (기호에 따라 CLP(Command Line Processor)를 이용할 수도 있지만 필자로선 DB2 명령 에디터를 사용하는 게 편하다.)

DB2 명령 에디터를 사용하려면 DB2 제어센터를 클릭한다. 상단에 있는 "Tools" 풀다운 메뉴에서 Command Editor를 선택하면 그림 1과 같이 별도의 창이 나타난다.


그림 1. DB2 명령 에디터


상단 창에 다음과 같은 문장을 입력한다.


Listing 4. 대화식으로 XML 데이터 삽입하기

				
connect to test;

insert into clients values (77, 'John Smith', 'Gold', 
   '<addr>111 Main St., Dallas, TX, 00112</addr>') 

왼쪽에 있는 녹색 화살표를 클릭해 명령을 실행한다.

이 경우, 입력 문장은 상당히 단순하다. 문서가 크거나 복잡할 경우, XML 데이터를 그림에 나오는 INSERT 문장에 입력하는 작업은 실지로 불가능하다. 대부분의 경우 호스트 변수, 파라미터 마커를 이용해 데이터를 삽입하기 위한 애플리케이션을 작성한다. 이 글과 같이 자바 코딩 예제가 간단히 소개된다. 하지만 초보자를 위한 글이라 애플리케이션 개발에 관한 주제에 대해 심도있게 논의하지는 않겠다. 대신 IMPORT 도구를 이용해 데이터로 DB2 XML 열을 구축하는 방식에 대해 논의하겠다.

DB2 IMPORT 이용하기

XML 데이터를 파일로 가지고 있는 경우, DB2 IMPORT 도구로 XML 데이터로 DB2 테이블을 생성하는 간단한 방법을 제공한다. 이 경우, 애플리케이션을 작성할 필요가 없고 단지 테이블에 올려놓고 싶은 데이터를 포함한 구별된(delimited) ASCII 파일을 생성하면 된다. 파일에 XML 데이터를 저장한 경우에는 파라미터로 적절한 파일 이름을 지정한다.

사용자에 따라 선택한 텍스트 에디터를 사용해 구별된 ASCII 파일을 생성한다. (통상적으로 그런 파일들의 유형은 .del 이다.) 파일에서의 각 라인은 테이블에 들어온 데이터 행을 나타낸다. 라인에 XML 데이터 지정자(XDS:XML Data Specifier)를 포함한 경우, IMPORT 명령은 참조 XML 파일에 포함된 데이터를 읽어들여 그 데이터를 DB2로 들여보낸다. 예를 들어, 그림 2에서의 첫번째 라인은 ID, 이름, 고객상태 등을 포함한 Ella Kimpton에 관한 정보가 포함되어 있다. 이 여자의 연락정보는 Client3227.xml 파일에 포함되어 있다.


그림 2. DB2 IMPORT 입력용으로 쓰이는 샘플 구별 ASCII파일


그림 3에는 Client3227.xml 파일의 컨텐츠가 나와 있다. 보다시피, 이 파일에는 Ella Kimpton의 주소, 전화번호, 팩스 번호 및 e-메일에 관한 정보가 포함되어 있다.


그림 3. 샘플 클라이언트 XML 파일


XML 파일이 모든 행(row)에 대해 준비되지 않아도 입력파일에서 XDS 정보를 생략하면 import는 잘 수행된다.예를 들어, 그림 4에 나온 items.del 파일은 항목 3641(멋진 드레스 슈트)에 관한 XML 파일 명칭이 빠져 있다. 그 결과, 이 행의 XML 열은 어떤 데이터도 포함되지 않는다.


그림 4. 한 행에 XML 데이터 지정자가 없는 샘플 구별 ASCII 파일


XML 파일 및 구별된 ASCII 파일이 있는 경우 DB2 IMPORT 도구를 사용할 준비가 다 된 셈이다. Listing 4에 나온 다음 문장으로 C:/XMLFILES 디렉토리에 있는 clients.del 파일에 지정된 컨텐츠를 "clients" 테이블로 import한다.


Listing 4. 데이터를 "clients" 테이블로 import하기

				

그림 2에 나온 client.del 파일은 6개의 XML 파일에 대한 레퍼런스를 포함해 6개의 행에 대한 데이터를 포함하고 있다.IMPORT 명령을 성공적으로 실행하면 그림 5와 비슷한 결과가 나온다.


그림 5. DB2 IMPORT의 샘플 출력


Exegenix와 같은 ISV(Independent Software Vendor)는 워드, PDF, 기타 문서 형식의 데이터를 XML형태로 바꿔 그 데이터를 DB2로 import 하기 위한 도구를 제공한다. (Exegenix에 대한 자세한 정보는 참고자료를 참고하라.)




XML 데이터 validation하기

방금 논의된 INSERTIMPORT 명령에 관한 예를 통해 테이블에 well-formed XML 데이터를 기록하게 된다. 여기에서는 XML 데이터를 validation하지 않는다. 이는 XML 데이터가 특정 XML 스키마에 따라 어떠한 구조에 적합한지 확인하지 않는다는 의미이다. 하지만 이런 validation은 DB2를 통해 가능하다. validation하는 방법을 알아보자.

Step 1: XML 스키마 생성하기

XML 데이터를 validation하기 위해 허용하는 element와 이에 대한 데이터 타입, 순서를 정의하는 XML 스키마가 필요하다.XML 스키마는 W3C 산업표준이고 XML 언어로 쓰여진다. XML 스키마의 기능을 설명하는 것은 이 글의 범주에서 벗어나므로, 웹 상에 있는 다양한 교재를 참조하라.(참고자료)

XML 스키마를 생성하는 많은 방법이 있는데, 텍스트 에디터를 이용하여 수동으로 생성할 수 있고 GUI Tool을 이용할 수도 있으며 자동으로 생성할 수도 있다. MDXSYS Limited와 같은 ISV는 그와 같은 XML 도구를 제공하고, IBM에서는 자사의 자바-통합 개발환경을 통한 XML 스키마 생성 지원기능을 제공한다.

예를 들어, IBM WebSphere® Studio로 그림 3에 있는 Client3227.xml 파일을 Web 프로젝트로 import한다. 마우스를 이용해 오른쪽 마우스를 클릭한 다음, 생성 -> XML Schema를 선택한다. 이렇게 하면 그림 6과 같이 특정 입력파일에 대한 유효한 XML 스키마를 생성하게 된다. 그 파일을 변경한 다음 (필요한 경우), DB2에 등록하면 된다.


그림 6. WebSphere Studio를 이용해 XML 파일로부터 XML 스키마 생성하기


이제 유연한 XML 스키마를 만들어 고객들마다 다른 연락정보 형태를 가질 수 있다고 가정해 보자. 예를 들어 여러 전화번호 또는 e-메일 주소를 제공하는 고객들과 그렇지 않은 고객들이 있다고 하자.

WebSphere Studio에서 생성한 스키마로부터 나온 그림 7과 같은 XML 스키마는 이와 같은 유연성을 보여준다. 이 스키마에는 주어진 element에 대해 허용된 최대, 최소 발생수("minOccurs" 및 "maxOccurs")에 대한 부가적인 정보를 포함하고 있다. 이 경우, 고객은 여러분이 수집하고 싶은 연락정보를 제공할 필요가 없다. 하지만 고객이 e-메일 정보를 제공할 경우, 이 스키마로 5개의 e-메일 주소(즉 5개의 "이메일" element 값)를 포함 할 수 있도록 한다.


그림 7. 클라이언트 고객정보에 관한 샘플 XML 스키마


이미 알고 있겠지만, XML 스키마는 형식정보를 포함하고 있다. 그림 7에 나온 스키마는 단순히 모든 기본 element를 문자열로 정의한 반면 운용되는 대부분의 XML 스키마는 정수, 소수점, 날짜 등 기타 데이터 형태를 이용한다. INSERT 또는 IMPORT 명령실행의 일환으로 주어진 스키마에 대한 XML 문서를 validation할 경우, DB2는 자동적으로 XML 문서에 대한 형식 주석을 덧붙인다.

Step 2. XML 스키마 등록하기

일단 적절한 XML 스키마를 생성하면 DB2로 스키마를 등록할 필요가 있는데 IBM에서는 이를 위한 여려 방법을 제공한다. DB2 제어센터에서 그래픽 마법사를 선택해 등록 절차를 안내받을 수 있고, System에서 제공하는 Stored Procedure를 호출할 수도 있으며 DB2 명령을 바로 수행할 수도 있다. 일단 DB2 명령을 바로 수행하는 방법을 사용해본다. 이 방법을 사용하면 DB2가 보이지 않게 작업하는 것을 보다 쉽게 이해할 수 있다.

스키마가 상당히 큰 경우, 스키마를 등록하기 전, 애플리케이션 힙 사이즈를 증가시키면 된다. 예를 들어, 다음과 같은 statement를 수행해 보자.


Listing 4. 애플리케이션 힙 사이즈 증가시키기

				
 connect to test;
 update db cfg using applheapsz 10000; 

그 다음 단계로, XML 스키마를 등록한다. 등록된 XML 스키마가 다른 XML 스키마를 참조하지 않는 경우 단일 명령으로 스키마를 등록하고 등록과정을 완료한다. 그렇지 않은 경우에는 각각의 명령을 수행해 1차 XML 스키마를 등록하고 다른 필요한 스키마를 등록한 다음 등록 과정을 완료한다. 스키마 문서가 상당히 큰 경우에는 문서 내용을 여러 개의 파일로 분할해 유지보수성, 가독성 및 재이용률을 향상시키는 게 일반적이다. 이는 복잡한 애플리케이션 또는 component를 여러 개의 모듈로 나누는 것과 유사하다. 이 주제에 관한 자세한 사항은 W3C "XML 스키마 입문서"(참고자료)를 참조하라.

이 글은 단순하고 독립적인 XML 스키마를 사용한다. 다음과 같은 명령을 이용해 DB2로 이 스키마를 등록한다.


Listing 5. XML 스키마 등록하기

				
register xmlschema 'http://mysample.org' from 'C:/XMLFiles/ 
ClientInfo.xsd' as user1.mysample complete;

이 예에서 ClientInfo.xsd는 XML 스키마 파일의 명칭이며 C:/XMLFiles 디렉토리에 위치해 있다. 이 XML 스키마는 SQL 스키마 "user1" 및 XML 스키마 "mysample"하에 DB2의 내부 저장소에 등록된다. http://mysample.org 파라미터는 이 예에서 placeholder에 불과하며 XML 인스턴스 문서에서 참조하는 URI를 명시한다. 많은 XML 문서들은 URI를 이용해 지정되는 namespace를 이용한다. 마지막으로, "complete" 절은 DB2로 하여금 XML 등록과정을 완료하도록 명령을 내리며, 등록된 스키마는 XML 데이터 검증을 위해 활용된다.

스키마 등록 과정에서 해당 스키마를 적용할 테이블 열을 지정하지 않았다는 사실을 알아둘 필요가 있다. 즉, 스키마는 SQL 열 constraints와 대등하지 않다. 주어진 스키마는 여러 다른 테이블에 있는 다양한 XML 열에 대한 데이터를 validation할 수 있다. 하지만, validation은 자동적이지 않다. DB2는 어떠한 well-formed XML 문서라도 XML 열에 저장할 수 있도록 한다. 문서를 저장하기 전에 등록 스키마에 대해 데이터를 검증하고 싶은 경우 DB2에 검증하라는 명령을 내려야 한다.

Step 3. Validation을 통해 XML 데이터 import하기

XML 스키마를 생성하고 DB2에 완전 등록시킨 상태에서, 스키마를 데이블에 삽입하거나 importing할 때 DB2로 XML 데이터를 검증할 수 있다. 스키마 validation을 염두에 두고, 초기 IMPORTIMPORT 시나리오를 다시 보도록 하자.

이미 "clients" 테이블을 구축한 경우, 테이블 컨텐츠를 삭제하거나, 테이블을 drop하고 재생성하는 것이 편리할지도 모른다. 이전에 했던 것처럼 테이블에 같은 데이터를 추가하기로 계획한 경우에만 이런 작업이 필요하다. "clients" 테이블에서 client ID 컬럼이 primary key로 잡혀 있다면 중복되는 데이터로 인해 import는 실패할 것이라는 것을 기억하자.

"clients" 테이블에 XML 데이터를 import하는 과정에 validation하기 위해서는 DB2 IMPORTXMLVALIDATE 절을 이용한다. Listing 6의 다음과 같은 문장은 XML 파일을 "clients" 테이블에 등록하기 전 clients.del 파일에 지정된 XML 파일을 validation하기 위한 기본 XDS (XML 데이터 지정자)로 이전에 등록된 XML 스키마를 사용하도록 DB2에 명령을 내린다.


Listing 6. validation하면서 XML 데이터 import하기

				
import from clients.del of del xml from C:/XMLFILES xmlvalidate using 
xds default user1.mysample insert into user1.clients; 

XML 문서가 지정 스키마와 일치하지 않는다고 DB2에서 결정되는 경우, 그 문서와 관련된 전 행은 거부된다. 그림 8은 IMPORT 명령 실행에서 나온 샘플 출력을 나타낸 것으로 출력 가운데 6개의 열 중 하나는 XML 문서가 지정 스키마와 일치하지 않기 때문에 거부된다.


그림 8. 한 열이 재송요구된 상태에서의 DB2 IMPORT 명령실행에서 나온 샘플 출력


XMLVALIDATEINSERT 문과 함께 사용되어 XML 데이터를 입력하기 전에 validation을 수행할 수 있다는 점을 알아둘 필요가 있다.문법은 이미 보았던 IMPORT 예와 비슷한데 XMLVALIDATE 절에서 등록된(처리완료된) XML 스키마를 지정하면 된다. (이에 대한 더 자세한 정보는 "A simple Java example" 을 참조한다.).




요약

DB2 Viper는 새로운 XML 데이터 타입과 XML 데이터를 효율적으로 자동 저장/처리하는 엔진 레벨 컴포넌트를 포함하여 XML을 지원하는 중요한 기능을 제공한다. 독자가 이 기능들을 빨리 이해하도록 하기 위해, 이 글에서는 테스트 데이터베이스 및 샘플 데이터베이스를 생성해 XML 문서를 저장하는 방법에 대해 설명했다. 본 글에서는 또한 XML 데이터로 데이터베이스를 구축하는 방법에 대해 검토해 보았다. 마지막으로, 사용자-제공 XML 스키마에 대해 XML 데이터를 validation하는 DB2의 기능을 요약하고 validation 과정을 시작하는 예를 제공했다.

DB2의 새로운 "native" XML 기능을 이용해 XML 데이터를 저장하는 방법을 배웠으므로, 여러분은 그 데이터를 조회할 준비가 되었다. 다음 글에서는 데이터 조회방법에 대해 알게 된다. 여기서는 DB2의 새로운 XQuery 기능 및 DB2의 SQL에 관한 XML 확장 등에 관해 소개한다.

감사의 글

이 글에 의견을 남겨주신 Rav Ahuja, Matthias Nicola 및 Gary Robinson 에게 감사의 말을 전한다.

기사의 원문보기





참고자료

교육


제품 및 기술 얻기


토론

출처

  • IBM DeveloperWorks

'DB2' 카테고리의 다른 글

[본문스크랩] DB2 SQLSTATE 메시지  (0) 2007.02.23
SQL을 이용한 DB2 XML 데이터 쿼리  (0) 2007.02.14
DB2 INDEX 설계  (0) 2007.02.02
DB2에서 *.sql 파일을 읽어들여 실행하기  (0) 2006.12.31
Column Size 변경  (0) 2006.12.19
 

DB2 INDEX 설계

DB2 | 2007. 2. 2. 18:12
Posted by 시반
DB2 index 설계 기법 


1. DB2의 Access Path 방법과 Index의 성질을 이해한 후에 적절한 Index를 선택하는 순서를 이해한다.
2. 유효한 Index 와 그렇지 않은 Index를 판단할 수 있다.
3. Index의 물리설계를 이해한다.

▣ Index 목적과 성질

◈ Index의 목적
1. 행의 Unique 성을 보증한다.
2. 추출하기의(예, 조회) Access Performance를 향상한다.

◈ Index의 성질
1. Unique 한가
. Unique Index
. Non Unique Index(Duplicate/Nonunique Index)

2. Cluster화 하는가
. Cluster화 Index(Clustering Index)
. 비 Cluster화 Index(Nonclustering Index)

3. Cluster성의 정도는 어느 정도인가
. Clustered Index(Clustered Index)
. 비 Clustrered Index(Nonclustered Index)

4. 복수의 열로부터 되는가
. 단일열 index
. 복합열 Index(Compound Index)

※ 참고

◐ Clustering Index

CREATE INDEX IXI ON TI (...) CLUSTER
☞ 행의 삽입시에 그 Index Key에 기초하여 삽입되어지고 1 Table 당 1 개

예 : create index ix1 on ta(c1)
create index ix2 on ta(c2) cluster

☞ LOAD, REORG(LOAD)의 때에 행의 Load순은 File의 순번대로
☞ Clustering, 동시에 Clustered로 할 때는 Load전에 미리 File을 그 Key 순으로 Sort해 놓는다.
☞ CLUSTER 지정 Index가 없을 때에는, 최초로 만들어진 Index를 Cluster화 Index로 간주한다.
☞ REORG(UNLOAD)가 Cluster화 Index를 사용하여 Unload하는 것은
- 1 Table / TableSpace인 때
- Segmented TableSpace인 때

◐ Clustered Index

☞ 행이 그 index 순번으로 물리적으로 거의 나열해 있는 경우
☞ Data page 내에는 Key순으로 꼭 나열해 있을 필요는 없고, 가까운 key를 갖고 있는 다른 행과 같은 page에 뭉쳐 있으면 좋다.
☞ 다음의 Key를 갖는 행이 같은 page에 있든가, 이웃한 Page에 있는 비율이 95% 를 넘을 때, 그 Index는 Clustered Index로 간주되어진다.
☞ 1 개의 Table에 복수의 Cluster Index가 존재할 수 있다.

◐ Index의 성질은 DB2 Catalog에 기록되어져 있다.

SYSIBM.SYSINDEXES

NAME Index
COLCOUNT 1 단일열 Index
n 복합열 Index
UNIQUEQULE U Unique Index 
D Non Unique Index
CLUSTERED Y Clusered Index
N Non Clustered Index
CLUSTERING Y Cluster화 Index
N 비 Cluster화 Index
CLUSTERRATIO n Cluster 율

위의 정보들은 Version에 따라서 다를 수가 있으며, 특히 중요한 의미를 갖는 것은 다음의 세가지이다.

◐ Unique Index인가, Non Unique Index 인가
◐ Clustered Index 인가, Non Clustered Index인가, Cluster 율
◐ 다일열 Index 인가, 복합열 Index 인가

▣ Index의 설계 순서

◈ 개요

1. Index의 필요성의 검토
2. 기본적인 Index후보의 선택
Program 설계와 SQL설계를 한 뒤에 행한다.
3. 추가 Index 후보의 검토
4. Clustered Index의 검토
5. Index 후보의 취사 선택과 결정
6. 중요한 조회에 대한 추가의 Index를 검토
(1) Index만의 Access
(2) 복합열 Index
7. Index의 물리설계
8. Index의 유효성과 검증

EXPLAIN

※ 3번 ~ 8번 을 반복 수행한다.

◈ 세부내용

1. Index의 필요성과 검토

(1) Unique성이 필요한 Table에는 꼭 Index를 만든다.
(2) 삽입/삭제/Index열의 갱신이 있는 작은 Table이나 빈 Table에는 index를 붙이지 않는다.
☞ Lock 에 의한 경합
☞ Index의 갱신 부하
(3) Join을 필요로 하는 컬럼에는 반드시 Index를 만든다.
(4) Foreign Key에는 반드시 Index를 만든다.
☞ Lock 에 의한 경합

2. 기본적인 Index의 선택

(1) Primary Key
☞ Unique 인 동시에 NOT NULL
(2) Foreign Key
☞ 경합열이 된다
(3) Primary Key외에 Unique성이 필요한 열
(4) 조회 성능을 높이기 위해 필요한 열

3. 추가 Index후보의 검사
(1) 상기 이외로 빈번하게 조회(갱신, 삭제를 포함한다)의 술어로 사용되어지는 열을 조사한다.
(가) 예를들면, Transaction 종류의 20% 혹은 10 ~ 20 개의 조회, 갱신 삭제에 사용되어지는 술어를 나타낸다.
(나) 상기의 Index의 선두행에 전혀 ㅍ함되지 않은 열이 단독으로 사용되어지고 있는 경우도 Index 의 후보로 한다.
(다) 상기의 Index가 등호술어에 전부 Match 하는가, 일부에 Match 하는가, 일부에 Match 하는가 어떤가를 검토한다.
※ c1 = and c2 = 
☞ Index(c1,c2)가 있으면 완전하게 Match하고 있으므로 이 조회에 대해서는 추가 Index가 필요 없다.
☞ Index(c1), Index(c2) 밖에 없을 때에는 복합열 Index(c1,c2)를 추가의 Index 후보로 한다.
(라) Index 칼럼의 순서는 COLCARD가 큰 쪽을 앞으로 한다.

(2) 빈번하게 ORDER BY, GROUP BY 의 대상이 되는 열
(3) 상기의 2 이외로 Join에 사용되는 열이 있으면 Index의 후보로 한다.

4. Cluster화 Index(Clustering)의 검토
(1) 어느 Index에 Cluster 속성을 주는가를 결정한다.
(가) 가장 사용 빈도가 높고, 동시에 범위로 검색할 수 있는 것이 많은 Index (Unique할 필요는 없다)
(나) 그 Key 순으로 조회할 수 있는 것이 많은 Index
(다) 입력 Data의 발생순서에 가장 가까운 Index
(라) Foreign Key로 Join되어지는 일이 많은 경우에는 Foreign Key의 Index

(2) 선택한 Index가 Clustered Index로도 된다고 가정한다.
☞ Primary Key를 꼭 Clustering Index로 할 필요는 없다.

5. Index 후보의 취사 선택과 결정
(1) Index의 수는 5 개 이하를 표준으로 한다.
(가) 검색만의 Table 에는 몇 개의 Index를 붙여도 좋다.
☞ Load시의 Index 작성 또는 Create Indext시에 많은 시간 소요
☞ Index를 위해 DASD 용량을 염두에 둘 것

(나) 갱신이라도 Index의 열을 갱신하지 않는 경우는 검색과 같다.
(다) Index의 열을 갱신/삽입/삭제를 하는 경우는, Index의 수를 적게 한다.
☞ 타당한 Index의 수는 Processor 능력과 응답시간 요구의 정도에 의존한다.
☞ ANDB2의 Cost Model로 부하를 추정하는 것이 바람직하다.

(2) COLCARD 가 작은 열의 Index는 피한다.
(가) 중복이 대단히 많은 경우, INSRT/DELETE의 부하가 크다.
(나) 다음의 부등식을 만족시키지 않는 Non Clustered Index는 제외
(3) 일반적으로 40Byte 이상의 Key의 Index는 피한다.
(4) 일반적으로 VARCHAR, VARGRAPHIC과 같은 가변길이 열의 Index는 피한다.

6. 중요한 조회에 대개 개별적으로 추가의 Index를 검토한다.
(1) Index만의 Access로 끝나는 Index를 검토한다.
(2) 단일열/복합열 Index의 추가로 Performance의 향상이 보여 지는가 어떤가를 검토한다.

☞ 모든 Index의 열이 등호 조건으로 사용되어지는 것이 유효하다
(3) 복합 Index의 유효성을 평가한다.

☞ FIRSTKEYCARD가 작은 Index는 피한다.
☞ 복합열 Index가 다른 Index Key를 포함하는 경우에는 짧은 Key의 Index를 우선한다.
※ Index(c1,c2) 와 Index(c1)중에서 Index(c1)을 우선한다.

7. Index의 물리설계를 행한다.
CREATE INDEX 의 Parameter를 결정한다.

(1) 열의 순번
(2) 오름순인가 내림순인가
(3) PCTFREE

☞ Random한 삽입이 있는 경우에 지정한다.

(4) SUBPAGES

☞ 삽입이 있다. -----------> 기본적으로 1 지정
☞ 행의 갱신만 있다. -----------> 1 이상 지정

(5) 값이 단조 증가하는 열을 선두에 갖는 Index는 DASD 용량에 주의힐 필요

예 : 날짜, 채번에 의해 발생한 수주번호와 출하번호
이유 : 
① 오래된 Key를 삭제해도, 그 Key 범위가 아니면 Index Page는 재 사용되어지지 않는다.
② 최후의 Index Page 가 꽉차게 되는 때에 Split 이 생기고 Index Page의 반밖에 유효하게 사용되어지지 않는다

8. Index의 유효성을 검증한다.

(1) Data 가 존재하고 DB2가 가동하고 있는 때
☞ EXPLAIN
(2) Data 가 존재하지 않지만 DB2가 가동하고 있는 때
☞ EXPLAIN
(3) DB2가 가동하고 있지 않은 때
☞ ANDB2 APS

▣ FULLKEY CARD(COLCARD)가 작은 경우의 고려사항

◈ FULLKEYCARD가 작은 Non Cluster Index는 일단 사용하지 않는다

예 : Index(성별 [남,녀])
Index(대분류Code [1,2,3])

1. Optimezer가 Access Path 로써 선택하지 않는 것 뿐만 아니라 다른 Access Path가 Performance가 좋기 때문이다.

◈ 할 수 없는 경우의 대응책
Optimezer에게 Non Cluster 이지만 COLCARD 와 FULLKEY CARD가 크다고 인식 시킨다.

◐ 순서

1. 여러 Key 값을 갖는 Dummy 행을 INSERT 시킨다.
2. RUNSTATS Utility 를 실행 시킨다.
3. Dummy 행을 모두 DELETE 한다.
4. BIND 한다.

◐ 고려사항

1. 희망하는 Access Path 가 얻어진 뒤에는 RUNSTATS 와 BIND를 하지 않는다.
2. RUNSTATS Utility 실행의 필요가 생겨난 경우는(재편성해야 옳은가 어떤가를 알기 위해), 이 Index를 RUNSTATS의 대상으로부터 떼내고 상기의 Step을 반복한다.

▣ 정리

◈ 언제 CREATE INDEX 하는가

1. LOAD 전
2. 빈번하게 Access하는 열이 나중에 발견되었을 때
3. 결합열(Join)이 새롭게 발견되었을 때
4. ORDER BY, GROUP BY의 Performance를 개선하고 싶을 때

◈ 언제 DROP INDEX 하는가

1. EXPLAIN에 그 Index가 사용되어지지 않는 것이 판명되었을 때
2. SYSPLANDEP로부터 어떤 Plan도 그 Index를 사용하고 있지 않음을 알았을 때

◈ 언제 RUNSTATS를 실행하는가

1. LOAD 후
2. Reorganization 후
3. 삽입, 삭제, 가변길이의 갱신이 많이 발생한 때
4. CREATE INDEX 후
5. DROP TABLE 한 때

※ 주의사항

☞ Tablespace 와 Index 양쪽을 동시에 조사할 것
☞ RUNSTATS를 실행하여도 BIND하지 않으면 Access Path는 바뀌지 않는다.
☞ Access Path를 바꾸고 싶지 않을 때 처리하지 않는 것도 생각되어 진다.

'DB2' 카테고리의 다른 글

SQL을 이용한 DB2 XML 데이터 쿼리  (0) 2007.02.14
DB2 Viper 시작하기  (0) 2007.02.14
DB2에서 *.sql 파일을 읽어들여 실행하기  (0) 2006.12.31
Column Size 변경  (0) 2006.12.19
db2와 oracle에서 프로시저 호출하기  (0) 2006.06.05
 

DB2에서 *.sql 파일을 읽어들여 실행하기

DB2 | 2006. 12. 31. 11:10
Posted by 시반

 

 DB2 -tvf 파일명

오라클에서처럼 파일을 읽어 들여 sql을 실행하는 것이 없나 했는데

역시 있었네여.. 사용하는 방법은 확실히 오라클과는 다르군여

 

1. DB2 Connect to 데이타베이스명 user 사용자명 using 비밀번호

 

2. test.sql을 만들어 insert/update/select 등 sql 구문을 작성합니다

    단 이때 DB2 콘솔창에서는 하나의 sql을 마칠때 ;를 쓰면 에러가 발생하지만

    파일로 만들경우에는 ;가 없으면 에러가 생기더군여

    ex) insert into emp(employee_num,emp_name) values ('1','TEST');

    또 하나 AutoCommit을 지정하지 않으셨다면 마지막에 Commit; 을 추가하세요

 

3. DB2 -tvf test.sql 을 하시면 쭈~욱 test.sql에서 실행한 스크립트가 실행되는것을 확인하실수 있습니다. 

'DB2' 카테고리의 다른 글

DB2 Viper 시작하기  (0) 2007.02.14
DB2 INDEX 설계  (0) 2007.02.02
Column Size 변경  (0) 2006.12.19
db2와 oracle에서 프로시저 호출하기  (0) 2006.06.05
DB2 에서의 OUTER JOIN  (0) 2006.06.01
 

Column Size 변경

DB2 | 2006. 12. 19. 11:20
Posted by 시반

 

ALTER TABLE tablename ALTER COLUMN [column-alteration] [column-alteration]
column-name SET DATA TYPE VARCHAR(integer)
CHARACTER VARYING
CHAR VARYING

예) 사원테이블의 사번컬럼사이즈를 30으로 변경

ALTER TABLE emp ALTER COLUMN employee_num SET DATA TYPE varchar(30);

1. Fixpak3(3/98)에 도입됨

2. 기존의 VARCHAR 컬럼의 길이를 증가함

3. Ineger 값은 4000까지 사용함

4. 컬럼의 변경은 모든 컬럼의 총 Byte수가 Page Size의 최대 record size를 초과해서는 안됨 (SQLSTATE 54010)

5. 만약 컬럼이 unique constaraint 또는 Index에 사용되는 경우 새로운 Size는 Unique Constraint 또는 Index 의 컬럼들의 길이의 합계가 1024 Byte를 초과해서는 안됨(SQLSTATE 54008)

* 참고로 DB2 UDB for OS/390은 254Byte, DB2 for OS/400은 2000Byte,infomix 7.2는 120Byte, Oracle 7.3은 255Byte,SQL Server 7은 900Byte,Sybase 10은 256Byte를 초과해서는 안됨

 *^^* 매번 느끼는 거지만 오라클과는 많이 다르다는 사실을 느끼네여 단순히 컬럼사이즈 변경하는 부분도 이리 틀리다니..-_- ㅋ

[출처] : 웰빙 님의 블로그

 

 

'DB2' 카테고리의 다른 글

DB2 INDEX 설계  (0) 2007.02.02
DB2에서 *.sql 파일을 읽어들여 실행하기  (0) 2006.12.31
db2와 oracle에서 프로시저 호출하기  (0) 2006.06.05
DB2 에서의 OUTER JOIN  (0) 2006.06.01
DB2에서의 부분범위 처리  (0) 2006.06.01
 

db2와 oracle에서 프로시저 호출하기

DB2 | 2006. 6. 5. 19:47
Posted by 시반
======== oracle =========
try
{
   int age = 39;
   String poetName = "dylan thomas";
   CallableStatement proc =  connection.prepareCall("{ call set_death_age(?, ?) }");
   proc.setString(1, poetName);
   proc.setInt(2, age);
   cs.execute();
}
catch (SQLException e)
{
   // ....
}

 

======== DB2 =========

try
{
   int age = 39;
   String poetName = "dylan thomas";
   CallableStatement proc =  

     connection.prepareCall(" call set_death_age(cast(? as INT), cast(? as VARCHAR(20)) ");
   proc.setString(1, poetName);
   proc.setInt(2, age);
   cs.execute();
}
catch (SQLException e)
{
   // ....
}

 

오라클에서 잘 돌아가던 프로시저 호출 구문이 DB2에서 에러를 토해낼때

1. 파라미터 타입을 일치시켜라(예: cast(? as INT))

2. { } 부분을 삭제하라(그 이유는 아직도 잘.. 빼니 돌아갑니다.. (__ )a )

 

'DB2' 카테고리의 다른 글

DB2에서 *.sql 파일을 읽어들여 실행하기  (0) 2006.12.31
Column Size 변경  (0) 2006.12.19
DB2 에서의 OUTER JOIN  (0) 2006.06.01
DB2에서의 부분범위 처리  (0) 2006.06.01
SQL0418N 오류  (0) 2006.05.09
 

DB2 에서의 OUTER JOIN

DB2 | 2006. 6. 1. 19:58
Posted by 시반

POINT : oracle에서 지원하는 (+)를 통한 outer join 대신 db2에서는 ANSI SQL형태의 OUTER JOIN형식만 지원한다.

EX) A.A1컬럼과 B.B1컬럼을 outer join 하는 경우

 ORACLE >

SELECT  A.A1,A.A2  FROM A,B WHERE  A.A1 = B.B1(+) ;

 DB2   >

SELECT A.A1,A.A2 FROM A LEFT OUTER JOINON A.A1 = B.B1;

EX) A.A1컬럼과 B.B1컬럼을 outer join 하면서 B.B2와 C.C1을 JOIN 하는 경우

ORACLE >

SELECT A.A1,C.1 FROM A,B,C WHERE A.A1 = B.B1(+) AND B.B2 = C.C1 ;

DB2        >

SELECT A.A1,C.C1 FROM A LEFT OUTER JOINON A.A1 = B.B1 INNER JOIN C ON B.B2 = C.C1;



 

'DB2' 카테고리의 다른 글

Column Size 변경  (0) 2006.12.19
db2와 oracle에서 프로시저 호출하기  (0) 2006.06.05
DB2에서의 부분범위 처리  (0) 2006.06.01
SQL0418N 오류  (0) 2006.05.09
SQLCODE: -301 오류  (0) 2006.05.08
 

DB2에서의 부분범위 처리

DB2 | 2006. 6. 1. 11:18
Posted by 시반

1. fetch사용 :(처음부터 몇 개까지만 가져올 경우)

 select * from zoam01 fetch first 5 rows only


2. rownumber()의 사용 (전체범위 중 일부만을 가져오고자 할때)

select   empno, lastname, yyt    from 
    (select 
         empno, lastname, firstname,
         rownumber() over (order by empno) as yyt
       from 
    employee)as t
   where yyt between 20 and 30


* order by 구문이 있는 경우 over()안에 넣어야  order by 처리가 된 전체범위 중 일부만을 가져옵니다

   전 over()만 했더니 전체 범위일때랑 부분범위처리일때랑 가져온 값이 틀려서 *^^*

 

'DB2' 카테고리의 다른 글

db2와 oracle에서 프로시저 호출하기  (0) 2006.06.05
DB2 에서의 OUTER JOIN  (0) 2006.06.01
SQL0418N 오류  (0) 2006.05.09
SQLCODE: -301 오류  (0) 2006.05.08
SQL30081N 오류  (0) 2006.05.02
 
블로그 이미지

시반

시반(詩伴)이란 함께 시를 짓는 벗이란 뜻을 가지고 있습니다. 함께 나눌수 있는 그런 공간이길 바라며...

카테고리

분류 전체보기 (233)
개발 이야기 (73)
WEB2.0 (57)
DB2 (24)
MySQL (6)
오라클 (26)
기타 (44)
취미 (0)
잡담 (2)