PowerPoint 프레젠테이션

Download Report

Transcript PowerPoint 프레젠테이션

IBM Software Group
Information Management DB2 FTSS
Contents
UNIT01
Overview
서버 제품군
클라이언트 제품군
지원되는 프로토콜
DB2 아키텍처
프로세스 모델
메모리 모델
인스턴스와 데이터베이스
데이터베이스와 테이블스페이스
유용한 URL
UNIT02
명령행 처리기
db2 명령행 처리기
Windows용 DB2 명령창
UNIX용 터미널 세션
DB2 세션 옵션
입력 파일을 이용한 처리 방법
온라인 도움말
UNIT03
원격 서버 등록
원격 클라이언트 지원을 위한 서버 설정
원격 노드 등록
원격 데이터베이스 등록
데이터베이스 목록 확인
데이터베이스 접속과 해제
응용프로그램 목록 확인
DB2 for UNIX
개발자기본교육
007
UNIT04
031
스키마
테이블
CREATE TABLE 문
데이터 유형
NULL 값과 DEFAULT 값
테이블스페이스 지정
고유키
기본키
참조 무결성
외부키
점검 제한 조건
IDENTITY 컬럼
인덱스
CREATE INDEX문
017
UNIT05
024
DDL
DML
시스템 레지스터리
카탈로그 테이블과 뷰
NULL값 처리
CASE 문
OUTER JOIN
Dummy 테이블
Common 테이블
Temporary 테이블
Transition 테이블
MQT
046
Contents
DB2 for UNIX
개발자기본교육
Identity 컬럼
Sequence
집합 연산
FOR READ ONLY
FOR UPDATE
문자열 스킬라 함수
숫자 스칼라 함수
날짜 스칼라 함수
형변환 스칼라 함수
컬럼 함수
스냅샷 테이블 함수
ROW_NUMBER 함수
RANK 함수
GROUP BY 확장 옵션
Recursive SQL
Correlated 서브 쿼리
UNIT06
DCL
사용자 인증
권한의 종류
권한별 기능
인스턴스 권한 제어 방법
데이터베이스 권한 제어 방법
특권의 종류
특권 제어 방법
UNIT07
LOCK
084
동시성과 무결성
분리 수준
분리 수준 지정 방법
잠금의 대상
테이블 잠금 유형
테이블 잠금 지정 방법
행 잠금 유형
잠금 변환 현상
잠금 상승 현상
잠금 대기 현상
교착 상태
UNIT08
076
SQL 고려 사항
인덱스의 필요성
인덱스 선정 기준
인덱스의 구조
인덱스 관리
복합 인덱스
클러스터 인덱스
인덱스 생성 옵션
Matching Column 수
Predicate
효율적인 SQL
컬럼 함수
096
Contents
DB2 for UNIX
개발자기본교육
데이터 유형 변환
부정형 PREDICATE
BETWEEN
NOT BETWEEN
술어 변환
OR 와 IN
LIKE
연산식을 포함한 술어
스칼라 함수, UDF
인덱스 컬럼 변형
여러 컬럼 값 동시 비교
중복된 테이블 SCAN
FETCH FIRST N ROWS ONLY
OPTIMIZE FOR K ROWS
FOR READ ONLY
FOR UPDATE OF
DISTINCT, GROUP BY, ORDER BY
SUBQUERY 와 JOIN
SELECT *
COUNT(*)
UNION ALL
WITH HOLD 커서
UNIT09
익스플레인
SQL 컴파일러
통계 자료 갱신
익스플레인 도구
액세스 플랜의 기본 형식
데이터 액세스 유형과 기법
단일 테이블 액세스 유형
Table Scan
Matching Index Scan
Non-matching Index Scan
One Fetch Access
Index Only Access
다중 Index Access
IN List Index Access
Sequential Prefetch
List Prefetch
Index ORing
Index ANDing
다중 테이블 액세스 유형
Cartesian Product
Nested Loop 조인
Merge Scan 조인
Hash 조인
UNIT10
142
Oracle 비교
데이터 유형
함수
데이터 유형 변환
NULL 값
시스템 레지스터리
187
Contents
DB2 for UNIX
개발자기본교육
DUMMY TABLE
ROWNUM
RAWID
날짜 연산
집합 연산
DECODE 문
값을 반환하는 UID 문
OUTER JOIN
SEQUENCE
SYNONYM
저장 프로시저
사용자 정의 함수
트리거
TEMPORARY TABLE
SUMMARY TABLE
계층적 쿼리
SQLCA 확인
UNIT11
프로그램 유형
ESQL
CLI
API
JDBC
저장 프로시저
사용자 정의 함수
주석문
exception 처리
dynamic SQL
WITH UR
기타 고려 사항
UNIT12
210
SQLPL
231
SP 기본 구조
SP 예제 코드
주석문
SP 이름과 매개 변수 선언
SPECIFIC 옵션
RESULT SETS 옵션
LANGUAGE 옵션
COMPOUND SQL 블록
NOT ATOMIC 옵션
ATOMIC 옵션
COMMIT, ROLLBACK, SAVEPOINT 문
변수 선언, 초기화, 값 할당
SQLCODE, SQLSTATE, 반환용 변수 선언
CURSOR 선언
오류 CONDITION 선언
오류 HANDLER 처리 로직 정의
LOGIC FLOW CONTROL 문
DYNAMIC SQL 문
GET DIAGNOSTICS 문
SIGNAL 문
실행 권한 제어
Contents
UNIT13
ESQL
DB2 for UNIX
개발자기본교육
253
기본 구조
헤더 파일
SQL 구분자
호스트 변수
널 지시자 (Null Indicator)
db2dclgn 유틸리티
주요 SQL문
커서 처리
Positioned UPDATE / DELETE
복합 SQL (Compound SQL)
SQLCA
WHENEVER 문
정적 SQL
동적 SQL
매개 변수 표시 문자 (Parameter Marker)
생성 과정
프리컴파일
PREP 명령어
바인드 / BIND 명령어
컴파일과 링크 / xlc 명령어
팩키지
리바인딩
TOPIC
01
01
UNIT01
Overview
UDB개발자기본교육
서버 제품군
클라이언트 제품군
지원되는 프로토콜
DB2 아키텍처
프로세스 모델
메모리 모델
인스턴스와 데이터베이스
데이터베이스와 테이블스페이스
유용한 URL
U D B 개 발 자 기 본 교 육 • UNIT 01 • Overview
7
TOPIC
0101 서버 제품군
01
1
다양한 플랫폼별로 지원되는 모든 DB2 제품들을 DB2 Family 라고
합니다.

2
단일 프로세서를 가진 데스크탑부터 다중 프로세서를
가진 SMP, SMP 클러스터, MPP에 이르기까지 다양한
환경을 지원합니다.

MPP의 Shared Nothing 구조는 확장성이 좋으므로 ESE
with DPF에 유리합니다.

Personal Edition은 클라이언트를 지원하지 않습니다.

DB2 Family 간에는 DRDA라는IBM의 전용 데이터
프로토콜이 사용됩니다. 클라이언트의 액세스 요청은
DRDA 프로토콜을 이용하여 서버에 전달되고, 서버는
DRDA 프로토콜을 이용하여 결과를 반환합니다.
Intel과 UNIX 기반의 DB2 제품군을 DB2 UDB라고 합니다. DB2 UDB 데
이터베이스 엔진 기능을 제공하는 서버 제품군에는 PE, WSE, ESE, ESE
with DPF 등이 있습니다.
제품
설명
PE
Personal Edition 의 약자입니다. Linux 와 Windows 플
랫폼에서 지원되는 Stand Alone용 데이터베이스 엔진
입니다.
WSE
Workgroup Server Edition의 약자입니다. 4 개 이하의
CPU로 구성된 플랫폼을 지원하며, 소규모의 데이터베
이스 서버용으로 사용됩니다. Linux, Windows, AIX,
HP-UX, Solaris 등에서 지원됩니다.
ESE
Enterprise Server Edition 의 약자입니다. SMP, SMP 클
러스터, MPP 를 지원하며, 대규모의 데이터베이스 서버
용으로 사용됩니다. Linux, Windows, AIX, HP-UX,
Solaris 등에서 지원됩니다.
ESE with
DPF
3
Enterprise Server Edition with Database Partitioning
Feature 의 약자입니다. ESE에 다중 데이터베이스 파티
셔닝 기능을 추가한 제품으로 병렬 데이터베이스 환경
을 구성할 수 있습니다.
AS/400과 S/390 에서 지원되는 DB2 제품군은 호스트 DB2라고 합니다.
제품
설명
DB2 iSeries
OS/400 에서 지원됩니다.
DB2 zSeries
OS/390 에서 지원됩니다.
U D B 개 발 자 기 본 교 육 • UNIT 01 • Overview
8
TOPIC
0102 클라이언트 제품군
01
1
원격 또는 지역 클라이언트의 요청은 서버의 엔진에 포함된 통신
리스너 프로세스에 의해 처리됩니다.

DRDA 프로토콜을 이용한 통신에서 데이터를 요청하는
프로그램을 DRDA Application Requester 라고 합니다.

DRDA 프로토콜을 이용한 통신에서 데이터를 제공하는
서버를 DRDA Application Server 라고 합니다.

DB2 서버 제품은 클라이언트 모듈을 포함하고 있습니다.

DB2 Connect Enterprise Edition은 DB2
gateway라고도 합니다. .
2
Runtime, Administration, Development Client 제품을 이용하여
DB2 UDB 서버에 액세스할 수 있습니다.
제품
3
설명
Runtime
Client
ODBC, JDBC 등을 포함한 실행 환경을 제공하
는 최소한의 클라이언트 모듈입니다.
Administration
Client
Run-Time Client 의 기능을 포함하며, 다양한
GUI 도구들을 이용한 관리 작업을 가능하게 하
는 클라이언트 모듈입니다.
Development
Client
Administration Client의 기능을 포함하며,
ESQL 등의 개발이 가능하도록 하는 프리컴파일
러, 헤더 파일, 라이브러리 등을 제공하는 클라이
언트 모듈입니다
DB2 Connect를 이용하면 OS/390, AS/400 등의 호스트 머신에 있는
데이터베이스를 액세스할 수 있습니다.
제품
제품
DB2 Connect
Personal
Edition
Linux 와 Windows 플랫폼에서 지원되는 단일
사용자용 호스트 데이터베이스 액세스 제품입
니다.
DB2 Connect
Enterprise
Edition
Windows, AIX, HP-UX, Solaris, Linux,
Linux/390 플랫폼에서 지원되는 다중 사용자용
호스트 데이터베이스 액세스 제품입니다.
U D B 개 발 자 기 본 교 육 • UNIT 01 • Overview
9
TOPIC
0103 지원되는 프로토콜
01
1
DB2 서버와 클라이언트는 TCP/IP, NetBIOS, Named Pipe, MPTN
등의 통신 프로토콜을 사용합니다.

TCP/IP 프로토콜은 설정이 간편하여가장 많이
사용됩니다.

TCP/IP 프로토콜을 사용할 때는 각 머신간의 물리적인
통신 설정이 완료된 상태에서 각 머신의 IP주소와 통신
포트 번호만 DB2에 설정하면 됩니다.

2
UNIX와 Windows 데이터베이스 서버 머신에 설치된 WSE, ESE, ESE
with DPF 등의 서버 제품과 클라이언트 머신에 설치된 Runtime,
Administration, Development Clinet 등의 클라이언트 제품간의 물
리적인 통신은 TCP/IP, NetBIOS, Named Pipe 프로토콜을 사용합니
다.
3
호스트 데이터베이스 서버 머신에 설치된 DB2 for OS/390, DB2 for
OS/400 등의 서버 제품과 클라이언트 머신에 설치된 DB2 Connect
Personal Edition, DB2 Connect Enterprise Edition 등의 클라이언트
OS/390과 AIX간의 프로토콜과 AIX와 Windows간의
프로토콜은 다른 종류로 설정할 수 있습니다.
제품간의 물리적인 통신은 TCP/IP, APPC, MPTN 프로토콜을 사용합니
다.
4
Windows 클라이언트에서 AIX에 설치된 DB2 Connect를 게이트웨이
로 호스트 머신의 데이터베이스를 액세스할 수 있습니다. 일차적으로
호스트 머신과 AIX간의 프로토콜을 설정하여 AIX에서 호스트 DB에 대
한 접속을 확인하고, AIX에 설치된 DB2 Connect 서버와 Windows 클
라이언트 간의 프로토콜을 설정합니다.
U D B 개 발 자 기 본 교 육 • UNIT 01 • Overview 10
TOPIC
0104 아키텍처
01
1
단일 데이터베이스 파티션으로 구성된 인스턴스의 아키텍처는 다
음과 같습니다.
4
응용프로그램이 데이터베이스에 접속을 요청하면, db2ipccm 또는
db2tcpcm 리스너 프로세스가 db2agent 라는 프로세스를 생성합니
다. SMP 머신에서 파티션내 병렬 기능을 이용하거나, DPF를 구성하면,
여러 개의 Subagent를 이용하여 쿼리를 병렬로 처리할 수 있습니다.
TCP/IP
Coordinator
Agent
5
에게 필요한 SQL문의 실행을 요청하고, 그 답을 응용프로그램에게 전
달하는 중계자 역할을 하게 됩니다.
Parallel
Subagent
6
Log Buffer
db2agent 프로세스는 응용프로그램을 대신하여 데이터베이스 엔진
db2agent가 필요한 데이터를 DB2 엔진에게 요청하면, 버퍼풀에서 필
요한 데이터를 검색합니다. Prefetch가 가능한 경우에는 db2pfchr에
의해 필요한 데이터를 디스크로부터 비동가적인 모드의 big-block I/O
Bufferpool
를 실행하여 버퍼풀로 읽어옵니다. 데이터가 여러 디스크에 걸쳐 스트
Loggr
Prefetcher
Page
Cleaner
라이핑이 되어있다면, 여러 개의 프리페처를 지정하여 여러 디스크를
동시에 액세스할 수 있도록 합니다.
7
읽어온 데이터가 버퍼에서 변경되면, 변경에 관련된 사전 이미지와 사
후 이미지가 로그 버퍼에 기록되어 특정 시점에 db2loggw 프로세스를
이용하여 로그 파일로 기록됩니다. 변경된 실제 데이터는 즉시 반영되
지 않고, db2pclnr 프로세스에 의해 비동기적으로 디스크에 반영됩니
2
DB2 엔진은 고유한 기능을 담당하는 여러 개의 EDU(Engine
다. 변경된 데이터가 디스크에 반영될 때에는 반드시 로그 파일에 먼저
Dispatchable Unit)로 구성되어 있으며, 각 EDU는 UNIX에서는 프
기록됩니다. 이러한 방식을 Write Ahead Logging 이라고 합니다.
로세스로 구현됩니다.
3
8
요청을 종료한 응용프로그램이 접속을 해제하면, db2agent 프로세스
는 제거됩니다. 에이전트 프로세스의 생성과 제거로 인한 오버헤드를
데이터베이스 서버 머신에서 접속을 요청하면 지역 응용프로그램
줄이기 위해 에이전트 프로세스를 위한 POOL 을 운영했다면, 에이전
이라고 하고, 원격 클라이언트에서 접속을 요청하면 원격 응용프로
트풀로 반환되어 다른 응용프로그램을 위한 db2agent 프로세스로 사
그램이라고 합니다.
용됩니다.
U D B 개 발 자 기 본 교 육 • UNIT 01 • Overview 11
TOPIC
0105 프로세스 모델
01
1
단일 데이터베이스 파티션으로 구성된 인스턴스에서는 다음과
같은 프로세스가 생성됩니다.
4
DB2 프로세스는 인스턴스, 데이터베이스, 응용프로그램의 수준으로 분
리됩니다.
수준
설명
인스턴스
인스턴스 수준의 프로세스는 db2start 명령을 실행하
여 인스턴스를 기동할 때 생성되고, db2stop 명령어
로 인스턴스를 중지할 때 제거됩니다. db2sysc,
db2resync, db2fmtlg, db2wdog, db2cart,
db2gds, db2ipccm, db2tcpcm 등의 프로세스가
있습니다.
데이터베
이스
데이터베이스 수준의 프로세스는 activate db 명령
어에 의해 데이터베이스가 활성화될 때 생성되고,
deactivate db 명령어에 의해 데이터베이스가 비활
성화되면 제거됩니다. db2pfchr, db2pclnr,
db2loggr, db2loggw, db2logts, db2dlock 등의 프
로세스가 있습니다.
응용프로
그램
5
2
데이터베이스 엔진과 관련된 프로세스들은 외부의 응용프로그
3
과 분리되도록 설계되어 있습니다.
데이터베이스를 액세스하는 응용프로그램은 반드시 데이터베이
스에 접속하므로, connection과 응용프로그램은 동일한 의미로
connect 는 데이터베이스를 간접적으로 활성화시킵니다. 이러한 방식
으로 활성화된 데이터베이스는 최종의 connect reset 요청시에 비활
램 프로세스들과 다른 address space를 사용하도록 구성되어
있으므로, 데이터베이스 제어 블록 및 중요한 데이터베이스 파일
응용프로그램 수준의 프로세스는 지역 또는 원격 응용
프로그램이 데이터베이스에 접속을 요청하는 경우에
생성됩니다. db2agent를 비롯하여 db2agntp,
db2agnta, db2agentg 등의 프로세스가 있습니다.
데이터베이스가 활성화되어 있지 않은 상태에서 요청된 최초의
6
성화됩니다.
DB2 Connect 제품으로 호스트에 접속하거나, 특정한 인스턴스를 게
이트웨이로하여 다른 인스턴스의 데이터베이스에 접속을 요청하면,
db2agent 프로세스를 대신하여 db2agentg 프로세스가 생성됩니다.
사용됩니다.
U D B 개 발 자 기 본 교 육 • UNIT 01 • Overview 12
TOPIC
0106 메모리 모델
01
1
DB2 메모리는 다음과 같이 4가지로 구성됩니다.
4
특정한 인스턴스에서 존재할 수 있는 에이전트 프로세스의 최대 개수
5
각 메모리별 특성은 다음과 같습니다.
는 인스턴스 구성 변수인 MAXAGENTS를 이용하여 조절합니다.
메모리
2
3
인스턴스
공유 메모
리
db2start 명령을 실행하여 인스턴스를 기동할 때 할
당되고, db2stop 명령어로 인스턴스를 중지할 때 해
제됩니다. Monitor heap, FCM, Audit buffer 등이
포함됩니다.
데이터베이
스 공유 메
모리
activate db 명령어에 의해 데이터베이스가 활성화
될 때 할당되고, deactivate db 명령어에 의해 데이
터베이스가 비활성화되면 해제됩니다. 한 개 이상의
Bufferpool 을 비롯하여 Database Heap,
Catalog Cache, Log Buffer, Lock List, Package
Cache, Shared Sort heap, Utility Heap 등이 포함
됩니다. 동일한 데이터베이스에 접속하는 응용프로
그램들에 의해 공용으로 사용되는 메모리입니다.
응용프로그
램 공유 메
모리
병렬 처리가 가능한 환경에서 응용프로그램의 첫 번
째 에이전트 프로세스가 데이터베이스에 연결을 요
청하는 경우에 할당되며, 해당 응용프로그램과 연관
된 모든 에이전트 프로세스 사이의 정보를 교환을 위
해 사용되는 영역입니다. Application control
heap 이 포함됩니다.
응용프로그
램 개별 메
모리
지역 또는 원격 응용프로그램이 데이터베이스에 접
속을 요청하는 경우에 개별적으로 할당되고, 접속을
종료하면 해제됩니다. Sort Heap, Statement
Heap,
Query13
U DApplication
B 개 발 자 기 Heap,
본 교 육Statistics
• UNIT 01 Heap,
• Overview
Heap 등이 포함됩니다.
특정한 인스턴스에서 동시에 활성화될 수 있는 데이터베이스의
최대 개수는 인스턴스 구성 변수인 NUMDB 를 이용하여 조절합
니다.
특정한 데이터베이스에 동시에 접속할 수 있는 응용프로그램의
최대 개수는 MAXAPPLS 데이터베이스 구성 변수를 이용하여 조
절합니다.
설명
TOPIC
0107 인스턴스와 데이터베이스
01
1
DB2 UDB 데이터베이스 시스템은 엔진, 인스턴스, 데이터베이스
로 구성됩니다. 엔진, 인스턴스, 데이터베이스, 테이블스페이스
컨테이너 등은 물리적으로 분리되어 있으므로 제품의 재설치, 인
스턴스의 재생성시에도 데이터베이스와 관련된 물리적인 파일
은 보존되고, 필요시에 다시 사용할 수 있습니다.
3
한 개의 서버 머신에서 여러 개의 인스턴스를 생성할 수 있습니다. AIX
4
root 사용자가 db2icrt 명령어를 이용하여 인스턴스를 생성하면, 인스
<인스턴스의 홈디렉토리>
/sqllib
인스턴
스
<데이터베이스 디렉토리>
/NODE000
데이터베이스
턴스 사용자 계정의 홈디렉토리에 sqllib 라는 서브디렉토리가 생성됩
니다. sqllib에 생성된 일부 디렉토리와 파일은 제품이 설치된
/usr/opt/db2_08_01/
DB2 엔진
머신에서는 인스턴스마다 사용자 계정이 필요합니다.
/usr/opt/db2_08_01 디렉토리의 일부 서브디렉토리와 심볼릭 링크
5
(symbolic link)로 연결되거나 복사됩니다.
인스턴스 사용자가 db2start 명령어를 이용하여 인스턴스를 기동시키
면, sqllib에 존재하는 파일들을 이용하여 인스턴스와 관련된 여러 개의
엔진 프로세스가 생성되고, 인스턴스 수준의 공유 메모리가 할당됩니
6
다.
인스턴스 사용자가 create database 명령어를 이용하여 데이터베이
스를 생성하면, 특정 디렉토리에 데이터베이스 구성 파일을 비롯한 물
리적인 디렉토리와 파일들이 생성됩니다.
디렉토리
/dir1
파일
/dir2/file1
LV
테이블스페이스
컨테이너
7
테이블스페이스와 컨테이너를 지정하면, 실제 데이터를 물리적으로 독
립적인 공간에 저장할 수 있습니다.
/dev/rlv01
8
2
데이터베이스에 접속한 후에 create tablespace 명령어를 이용하여
DB2 UDB 제품 모듈은 AIX 머신에서는 /usr/opt/db2_08_01 디
인스턴스를 생성할 때, Windows 머신에서는 인스턴스 생성을 위한 별
도의 사용자 계정이 필요하지 않습니다. 또한, 설치시에 DB2 라는 이름
으로 기본적인 인스턴스가 생성됩니다.
렉토리에 설치되고, Windows 머신에서는 원하는 디렉토리에 설
치됩니다. 한 개의 서버 머신에서 여러 개의 인스턴스를 생성하
는 경우에도 제품은 한 번만 설치합니다.
9
다중 파티션 환경인 경우에는 한 개의 논리적인 데이터베이스를 생성
하면, 데이터베이스 파티션 개수만큼의 물리적인 데이터베이스가 생성
됩니다.
U D B 개 발 자 기 본 교 육 • UNIT 01 • Overview 14
TOPIC
0108 데이터베이스와 테이블스페이스
01
1
한 인스턴스에서 한 개 이상의 데이터베이스를 생성할 수 있습니
다.
4
5
SYSCATSPACE 테이블스페이스에는 데이터베이스의 모든 오브젝트에
대한 정보를 저장하고 있는 메타 테이블인 시스템 카탈로그 테이블이
생성됩니다.
데이터베이스의 데이터에 대한 변경 사항은 데이터베이스 트랜잭션 로
그 파일에 기록됩니다. 초기에는 3개의 기본 로그 파일과 2개의 보조 로
그 파일이 생성되며, 데이터베이스 구성 파일을 이용하여 로그 파일의
6
7
개수와 크기를 조절할 수 있습니다.
데이터베이스별로 테이블스페이스, 테이블, 인덱스 등의 다양한 오브
젝트를 생성하고, 사용자의 데이터를 테이블에 저장하여 SQL문으로 액
세스합니다.
서로 다른 데이터베이스에 속한 테이블들은 한 개의 SQL문으로 JOIN
하려면 FEDERATED 기능을 이용합니다. DB2 제품군에 대한
FEDERATED 기능은 기본적으로 제공됩니다. 다른 DBMS의 테이블과
JOIN 하려면 WII 라는 제품을 추가적으로 설치해야 합니다.
8
2
SAMPLE이라는 이름의 기본 데이터베이스가 제공됩니다. db2sampl
이라는 명령어로 생성할 수 있습니다
데이터베이스 구성 변수를 이용하여 데이터베이스별로 독립적
인 환경을 구성할 수 있습니다. 데이터베이스 구성 변수는 데이
터베이스 구성 파일에 저장되며, get / update / reset
database cfg 명령어를 이용하여 관리합니다.
3
데이터베이스가 생성됨변, 3개의 기본 테이블스페이스인
SYSCATSPACE, TEMPSPACE1, USERSPACE1이 자동적으로 생
성되며, 사용자가 다양한 유형의 테이블스페이스를 추가적으로
생성할 수 있습니다.
U D B 개 발 자 기 본 교 육 • UNIT 01 • Overview 15
TOPIC
0109 유용한 URL
01
1
온라인 정보 센터
2
온라인 제품 매뉴얼
3
SQL Cookbook
4
Redbooks
5
Technical Library
6
5
Fixpak과 Client 모듈 다운로드
http://publib.boulder.ibm.com/infocenter/db2luw/v8/index.jsp 과 http://publib.boulder.ibm.com/infocenter/db2luw/v9/index.jsp
에서 UDB에서 제공되는 명령어와 SQL문에 대한 종합적인 정보를 확인할 수 있습니다.
www-306.ibm.com/software/data/db2/udb/support/manualsv8.html 에서 영문 PDF 제품 매뉴얼을 다운로드할 수 있고, "Translated
DB2 UDB V8 product manuals in PDF format" 을 클릭하면, 한글 PDF 제품 매뉴얼을 다운로드할 수 있습니다.
http://ourworld.compuserve.com/homepages/Graeme_Birchall 에서 UDB에서 제공되는 각종 SQL 함수에 대한 설명을 예제를 이용하여
정리한 자료를 다운로드할 수 있습니다.
www.redbooks.ibm.com 에서 UDB와 관련된 기술 서적을 찾아볼 수 있습니다.
http://www-128.ibm.com/developerworks/views/db2/libraryview.jsp 에서 다양한 TIP 들을 검색할 수 있습니다.
www-306.ibm.com/software/data/db2/udb/support/downloadv8.html 에서 플랫폼별 V8용 FP과 클라이언트 모듈을 다운로드할 수 있습
니다.
V9용은 www-306.ibm.com/software/data/db2/udb/support/downloadv9.html 에서 제공됩니다.
7
사용자 게시판
www.ibmdb2.net 에서 UDB와 관련된 다양한 정보를 얻을 수 있으며, 게시판을 통해 다른 사용자들과 다양한 정보를 공유할 수 있습니다.
U D B 개 발 자 기 본 교 육 • UNIT 01 • Overview 16
TOPIC
02
01
UNIT02
명령행 처리기
UDB개발자기본교육
db2 명령행 처리기
Windows용 DB2 명령창
UNIX용 터미널 세션
DB2 세션 옵션
입력 파일을 이용한 처리 방법
온라인 도움말
U D B 개 발 자 기 본 교 육 • UNIT 02 • 명령행 처리기 17
TOPIC
02 01 db2 명령행 처리기
01
1
db2 명령행 처리기는 <DB2 명령어> 또는 <SQL문>을 실행시키
3
기 위해 기본적으로 제공되는 프로그램입니다.
db2 라는 명령어를 먼저 입력하고, <DB2 명령어> 또는 <SQL문>을
실행하는 방식을 비대화식 모드의 DB2 세션이라고 합니다. OS에 따
라 특수 문자가 포함되는 경우에는 " (쌍따옴표)가 필요할 수도 있습
니다.
$ db2 <DB2 명령어>
$ db2 <SQL문>
$ db2 "SQL문"
$ <OS 명령어>
4
db2 명령어는 한 개 이상의 옵션을 지원합니다. – (마이너스)를 이용
하여 옵션을 ON 시키고, +(플러스)를 이용하여 옵션을 OFF 시킵니다.
제공되는 옵션의 목록과 현재 상태값은 다음과 같이 확인할 수 있습
니다.
$ db2 –<옵션> <DB2 명령어>
$ db2 +<옵션> <DB2 명령어>
$ db2 list command options
2
db2 라는 명령어 프롬프트가 표시된 상태에서 <DB2 명령어>
또는 <SQL문>을 실행하는 방식을 대화식 모드의 DB2 세션이라
고 합니다.
$ db2
5
?(물음표)를 이용하여 온라인 도움말 기능을 이용할 수 있습니다.
$ db2 ? <DB2 명령어>
db2=> <db2 명령어>
db2=> <SQL문>
db2=> !<OS 명령어>
db2=> quit
6
db2 명령어를 실행하면 DB2 세션이 시작되고, 백그라운드 프로세스
인 db2bp 또는 db2bp.exe가 생성됩니다. quit 명령어는 기존의 대
화식 모드에서 생성된 db2bp 프로세스를 계속 사용하므로, 완전히
새로운 환경의 DB2 세션을 사용하려면, terminate 명령을 입력하고
다시 db2를 입력합니다.
U D B 개 발 자 기 본 교 육 • UNIT 02 • 명령행 처리기 18
TOPIC
02 02 Windows용 DB2 명령창
01
1
DB2 명령창은 Windows의 OS 명령창에서 텍스트 기반으로
DB2 명령어와 SQL문을 실행할 수 있는 환경입니다. db2라는
3
명령어를 이용하여 실행합니다.
db2 라는 명령어를 실행하면, 내부적으로 db2bp.exe가 실행됩니다.
<DB2 명령어>를 실행하려면, db2start 명령어를 이용하여 DB2 엔진
을 기동시킵니다.
C:\> db2start
C:\> db2 <DB2 명령어>
4
<SQL문>을 실행할 때에도 db2 라는 명령어를 이용합니다. <SQL문>
을 실행하려면, connect 명령어를 이용하여 특정 데이터베이스에
접속해야 합니다. 비대화식 모드에서 <DB2 명령어> 또는 <SQL문>을
실행할 때, |(파이프) 와 >(리다이렉션) 등을 함께 이용할 수 있습니
다.
C:\> db2 connect <데이터베이스명>
C:\> db2 "<SQL문>"
C:\> db2 "<SQL문>" | more
5
2
DB2 명령창 세션은 다음의 두 가지 방법으로 실행합니다.
Windows의 OS 명령창에는 DB2를 위한 환경이 설정되지 않았
으므로 DB2 명령어를 실행할 수 없습니다.
시작 → 모든 프로그램 → IBM DB2 → 명령행 도구 → 명령
창 클릭
DB2 명령창은 OS 명령창과 동일한 환경을 제공하므로 OS 명령어도
실행할 수 있습니다.
C:\> <OS 명령어>
6
세션을 완전히 종료하려면, exit 명령어로 DB2 명령창을 종료합니다.
C:\> db2 terminate
C:\> exit
시작 → 실행 → db2cmd → 엔터키
U D B 개 발 자 기 본 교 육 • UNIT 02 • 명령행 처리기 19
TOPIC
02 03 UNIX용 터미널 세션
01
1
UNIX 머신에서는 telnet 프로그램을 이용하여 터미널 세션을 열
고, db2 라는 명령어로 DB2 세션을 실행합니다.
$ . <DB2 인스턴스 사용자의 홈디렉토리>/sqllib/db2profile
$ echo $DB2INSTANCE
4
db2 라는 명령어를 실행하면, 내부적으로 db2bp가 실행됩니다.
Windows의 명령행 처리기과 동일한 방식으로 DB2 세션을 실행할
수 있습니다. quit 명령어를 이용하면 비대화식 모드로 전환합니다.
db2=> <db2 명령어>
db2=> <SQL문>
db2=> !<OS 명령어>
db2=> quit
5
2
telnet 프로그램을 이용하여 서버의 OS 사용자 계정으로 로그
인합니다.
C:\> telnet <원격 UNIX 머신의 IP 주소>
비대화식 모드의 DB2 세션을 실행하는 방법도 Windows의 명령창과
동일합니다. db2 명령어와 엔터키를 입력하면 다시 대화식 모드로
전환됩니다.
$ db2 <DB2 명령어>
$ db2 <SQL문>
$ <OS 명령어>
$ db2 <엔터키>
3
DB2 명령어와 SQL문을 사용하려면 DB2를 위한 환경을 설정해
야 합니다. db2profile을 실행하는 명령을 사용자의 .profile에
포함시키면 로그인시에 자동적으로 DB2를 위한 환경이 설정되
므로 편리합니다.
U D B 개 발 자 기 본 교 육 • UNIT 02 • 명령행 처리기 20
TOPIC
02 04 DB2 세션의 옵션
01
1
대화식 모드의 DB2 세션은 update command options 명령
어로 옵션을 조절하고, 비대화식 모드에서는 –(마이너스)와
3
+(플러스)를 이용하여 조절합니다. DB2OPTIONS 레지스터리
대화식 모드에서 옵션의 상태 전환은 다음 명령어를 이용하여 제어합
니다. 대화식 모드를 종료하면 옵션은 기본값으로 복귀합니다.
db2=> UPDATE COMMAND OPTIONS USING <옵션> ON
변수에 지정된 옵션은 모든 세션에 자동적으로 적용됩니다.
db2=> <DB2 명령어>
db2=> UPDATE COMMAND OPTIONS USING <옵션> OFF
db2=> <SQL문>
4
비대화식 모드에서는 – (마이너스)를 이용하여 옵션을 ON 시키고,
+(플러스)를 이용하여 옵션을 OFF 시킵니다. 옵션은 실행 당시에만
유효합니다.
$ db2 –<옵션> <DB2 명령어>
$ db2 +<옵션> <DB2 명령어>
5
DB2 레지스터리 변수를 이용하여 옵션을 모든 대화식 또는 비대화식
세션에 자동적으로 적용되도록 설정할 수 있습니다.
$ db2set DB2OPTIONS="-a +c"
2
제공되는 옵션의 목록과 현재 상태값은 다음과 같이 확인할 수
있습니다. 기본적으로 c,o,p,w 등의 옵션이 적용됩니다. 기본
옵션이 적용되지 않게 하려면, +를 이용하여 해당 옵션을 지정
해야 합니다.
$ db2 list command options
$ db2set DB2OPTIONS
$ db2 <DB2 명령어>
$ db2 <SQL문>
6
레지스터리 변수에서 지정한 옵션은 레지스터리 변수를 제거할 때까
지 유지됩니다. 대화식 또는 비대화식 모드에서 지정한 옵션은
DB2OPTIONS 레지스터리 변수보다 우선적으로 적용됩니다.
U D B 개 발 자 기 본 교 육 • UNIT 02 • 명령행 처리기 21
TOPIC
02 05 입력 파일을 이용한 처리 방법
01
1
DB2 세션에서 한 개 이상의 명령문 또는 SQL문을 묶어서 실행
– – <주석문>을 입력합니다.
하려면 비대화식 모드에서 입력 파일을 이용합니다. –svtf 옵션
CREATE TABLE t1
을 사용하는 것이 일반적입니다.
(c1
INT,
c2
CHAR(10));
INSERT INTO t1 VALUES (1,'A'),(2,'B');
-- SELECT * FROM org WHERE deptnumb > 10;
COMMIT;
DELETE FROM t1 WHERE c1 = 1;
COMMIT;
4
입력 파일명은 –f (file) 옵션을 이용하여 지정하며, ; (세미콜론)을 명
령문 구분자로 사용하면 –t (terminator) 옵션을 함께 사용합니다. –s
(stop)는 입력 파일의 실행 도중에 오류가 발생하면 실행을 중단하게
하고, –v (verify) 옵션은 명령어와 실행 결과를 함께 보여줍니다.
$ db2 –svtf <파일명>
2
3
입력 파일은 OS가 제공하는 에디터로 작성하며, 임의의 확장자
를 지원합니다.
$ vi <파일명>
각 명령문은 기본적으로 한 줄 단위로 구별되므로, 한 명령문을
한 줄 이상에 걸쳐 표현하려면 ; (세미콜론 부호) 등의 명령문 구
분자가 필요하며, 반드시 –t 옵션을 함께 사용해야 합니다. 주석
문은 – – (대쉬 부호 2개)를 이용합니다. SQL문에서 데이터값을
제외한 부분에서 대소문자는 구별하지 않습니다.
$ db2 –s -v -t -f <파일명>
5
자동 커미트 옵션이 기본적으로 설정되어 있으므로, 입력 파일에 포
함된 SQL문은 즉시 커미트됩니다. 입력 파일에서 <SQL문> 또는
<DB2 명령어>를 입력하고, +c 옵션을 추가하여 실행하면, COMMIT
또는 ROLLBACK문의 실행 직전 시점까지의 구간이 한 개의 트랜잭
션으로 처리됩니다.
$ db2 +c –svtf xx.db2
U D B 개 발 자 기 본 교 육 • UNIT 02 • 명령행 처리기 22
TOPIC
02 06 온라인 도움말
01
1
DB2 세션에서 ?(물음표)를 사용하여, DB2 명령어에 대한 구문
과 오류 메시지를 나타내는 SQLCODE, SQLSTATE 값에 대한 텍
3
특정한 DB2 명령어에 대한 구문과 옵션은 다음과 같이 확인합니다.
$ db2 ? <DB2 명령어>
스트 기반의 도움말을 확인할 수 있습니다.
4
SQLCODE에 대한 설명은 다음과 같이 확인할 수 있습니다.
SQLCODE는 SQLnnnnx 의 형식으로 표시되며, nnnn은 숫자입니다.
$ db2 "? SQL0100W"
5
SQLSTATE에 대한 설명은 다음과 같이 확인할 수 있습니다.
SQLSTATE는 nnnnn 형식으로 표시되는 5자리의 문자입니다.
$ db2 "? 02000"
6
대화식 모드에서도 도움말을 확인할 수 있습니다.
$ db2 <엔터키>
db2=> ?
2
db2=> ? <DB2 명령어>
DB2 세션에서 제공하는 모든 명령어의 목록은 다음과 같이 확
인합니다. ?(물음표)를 특수 문자로 인식하는 OS 에서는 비대화
식 모드에서 "(쌍따옴표)와 함께 사용합니다. 대화식 모드와
Windows에서는 쌍따옴표를 사용하지 않습니다.
$ db2 ?
db2=> ? SQLnnnn
db2=> ? nnnnn
7
SQL문에 대한 도움말은 제공하지 않습니다. 자세한 도움말은 온라인
정보 센터와 제품 설명서를 참조하십시오.
U D B 개 발 자 기 본 교 육 • UNIT 02 • 명령행 처리기 23
TOPIC
03
01
UNIT03
원격 서버 등록
UDB개발자기본교육
원격 클라이언트 지원을 위한 서버 설정
원격 노드 등록
원격 데이터베이스 등록
데이터베이스 목록 확인
데이터베이스 접속과 해제
응용프로그램 목록 확인
U D B 개 발 자 기 본 교 육 • UNIT 03 • 원격 서버 등록 24
TOPIC
03 01 원격 클라이언트 지원을 위한 서버 설정
01
1
DB2 UDB 서버 제품은 2개의 연속적인 TCP/IP 서비스 포트를 이
용하여 UNIX, Windows 등의 원격 클라이언트 제품으로부터의
3
접속을 지원합니다.
원격 클라이언트와 통신하려면 /etc/services 파일에 연속된 번호를
가진 2개의 TCP/IP 포트를 추가합니다. 포트 번호는 50000번 이상이
권장되며, 서비스명은 임의로 정의합니다. SVCENAME 구성 변수에
<서비스명> 대신에 <포트 번호>를 바로 사용할 수도 있지만,
/etc/services 파일을 사용하는 것을 권장합니다.
$ login root
$ grep <인스턴스명> /etc/services
4
<인스턴스명>c
50000/tcp
<인스턴스명>i
50001/tcp
/etc/services 파일에서 지정한 두 개의 포트 중에서 첫 번째 포트의
서비스명을 인스턴스 구성 변수인 SVCENAME에 지정하고, 인스턴
스를 재기동합니다.
$ db2 update dbm cfg using SVCENAME <서비스명>
$ db2stop force
$ db2start
2
5
TCP/IP용 통신 리스너 프로세스인 db2tcpcm이 생성된 것을 확인합
니다.
$ ps –ef | grep -i <인스턴스명> | grep db2tcpcm
6
Personal Edition은 stand-alone 용 제품으로서 원격 클라이언트를
지원하지 않습니다.
DB2 레지스터리 변수인 DB2COMM에 TCPIP를 지정합니다. 현
재 인스턴스에 대해서만 적용하는 경우에는 –g 또는 –i 옵션을
사용하지 않습니다. 대소문자는 구별하지 않습니다.
$ login <인스턴스 사용자>
$ db2set DB2COMM=TCPIP
U D B 개 발 자 기 본 교 육 • UNIT 03 • 원격 서버 등록 25
TOPIC
03 02 원격 노드 등록
01
1
원격 머신의 인스턴스에 존재하는 데이터베이스를 액세스하려
면 <원격 서버 머신의 IP 주소>와 <원격 서버 인스턴스의
3
TCP/IP 서비스 포트 번호>를 이용하여 원격 노드를 등록해야 합
니다. CATALOG TCPIP NODE 명령어를 이용합니다.
서버 머신의 인스턴스 구성 변수인 SVCENAME에 정의된 port 번호
를 확인합니다. 이 값이 < 원격 인스턴스의 TCP/IP 서비스 포트 번호>
입니다. Port 번호 대신에 서비스명을 사용했다면, /etc/services에
정의된 포트 번호를 확인합니다.
$ db2 get dbm cfg | grep SVCENAME
$ cat /etc/services
4
Windows 클라이언트의 DB2 명령창에서 catalog tcpip node 명령
어로 원격 인스턴스를 등록합니다. <노드명>은 임의로 정하고, 서버
머신에서 확인한 <원격 서버 머신의 IP 주소>와 <원격 인스턴스의
TCP/IP 서비스 포트 번호>를 이용하여 원격 노드를 등록합니다.
C:\> db2 catalog tcpip node <노드명> remote <원격 서버
머신의 IP 주소> server <원격 인스턴스의 TCP/IP 서비스 포
트 번호>
2
5
등록된 원격 노드는 list node directory 명령어로 확인할 수 있습니
다.
C:\> db2 list node directory
6
등록된 원격 노드는 uncatalog node 명령어로 제거할 수 있습니다.
서버 머신에서 인스턴스 사용자로 로그인하여 <IP 주소>를 확인
합니다. 이 값이 <원격 서버 머신의 IP 주소> 입니다.
$ login <서버 머신의 인스턴스 사용자명>
$ grep $(hostname) /etc/hosts
C:\> db2 uncatalog node <노드명>
7
UNIX 클라이언트 머신인 경우에는 인스턴스 사용자로 로그인하여
Windows 클라이언트와 동일한 방법으로 원격 서버 머신의 인스턴스
를 등록합니다.
U D B 개 발 자 기 본 교 육 • UNIT 03 • 원격 서버 등록 26
TOPIC
03 03 원격 데이터베이스 등록
01
1
원격 노드 또는 지역 노드에 존재하는 원격 데이터베이스는
C:\> db2 list node directory
CATALOG DB 명령어를 이용하여 원하는 데이터베이스 별명으
로 등록하여 액세스합니다.
2
catalog db 명령어를 이용하여 원격 데이터베이스를 등록합니다.
<등록할 데이터베이스 별명> 은 임의로 정할 수 있으마, 고유한 이름
이어야 합니다. AS 옵션을 지정하지 않으면 <원격 데이터베이스의 별
명>과 동일한 이름으로 등록됩니다. AT NODE 옵션에는 <등록된 원
격 노드명>을 이용합니다.
C:\> db2 catalog <원격 데이터베이스의 별명> as <등록할 데
이터베이스 별명> at node <등록된 원격 노드명>
5
connect 문을 이용하여 원격 데이터베이스에 접속할 때는 반드시
서버 머신의 OS 계정에 등록된 <사용자명>과 <암호>를 지정해야 합
니다.
C:\> db2 connect to <등록한 데이터베이스 별명> user <원격
사용자명> using <원격 사용자의 암호명>
6
등록된 원격 데이터베이스는 uncatalog db 명령어로 제거할 수 있
습니다.
C:\> db2 uncatalog db <등록한 데이터베이스 별명>
7
원격 데이터베이스에 대해 DB2 유틸리티를 실행하려면 등록 후에
db2ubind.lst 파일을 바인드합니다. 동일한 클라이언트 플랫폼에 대
해 한 번만 실행합니다.
C:\> cd <DB2 설치 디렉토리>/bnd
서버 머신으로 로그인하여 <원격 데이터베이스의 별명>을 확인
합니다.
$ login <서버 머신의 인스턴스 사용자명>
$ db2 list db directory
3
4
Windows의 db2 명령창에서 list node directory 명령어로 원
격 데이터베이스가 존재하는 <원격 노드명>이 등록되었는지 확
인합니다.
C:\> db2 bind @db2ubind.lst blocking all grant public
U D B 개 발 자 기 본 교 육 • UNIT 03 • 원격 서버 등록 27
TOPIC
03 04 데이터베이스 목록 확인
01
1
현재 인스턴스에 등록된 모든 데이터베이스 목록을 시스템 데이
3
list db directory 명령어에서 ON 옵션으로 드라이브명을 지정하면,
해당 드라이브에 실제로 존재하는 로컬 데이터베이스의 목록만 확인
할 수 있습니다. 데이터베이스 디렉토리에는 연관된 디렉토리명이 표
시됩니다.
C:\> db2 list node directory on c:
4
UNIX 클라이언트인 경우에는 list db directory 명령어의 ON 옵션에
create db 명령어를 실행할 때 사용한 디렉토리명을 지정합니다.
터베이스 목록이라고 합니다. 현재 인스턴스에서 생성된 지역
데이터베이스와 등록된 원격 데이터베이스의 목록을 모두 포함
2
합니다.
Windows의 db2 명령창에서 list db directory 명령어를 실행하
면, 시스템 데이터베이스의 목록을 확인할 수 있습니다. 원격 데
이터베이스는 '리모트' 유형으로 분류되며, catalog node 명령
어로 등록된 원격 노드과 catalog db 명령어로 등록한 데이터
베이스 별명이 표시됩니다. 로컬 데이터베이스는 ‘간접' 유형으
로 표시됩니다.
C:\> db2 list node directory
$ db2 list node directory on /data
U D B 개 발 자 기 본 교 육 • UNIT 03 • 원격 서버 등록 28
TOPIC
03 05 데이터베이스 접속과 해제
01
1
<DB2 명령어>와 <SQL문>을 이용하여 데이터베이스에 대한 액
3
데이터베이스에 대한 접속을 해제하려면, connect reset 문을 이용
합니다.
C:\> db2 connect reset
4
원격 데이터베이스에 접속하려면, 반드시 사용자명과 암호를 지정해
야 합니다.
C:\> db2 connect to <원격 데이터베이스명> user <원격 사용
자명> using <원격 사용자 암호>
세스를 시작하려면 활성화된 데이터베이스에 대한 접속이 필요
합니다. activate database 를 사용하여 데이터베이스를 활성
화한 후에 connect 명령어로 데이터베이스에 접속하는 것을
2
권장합니다.
connect 문을 이용하여 로컬 데이터베이스에 접속합니다. 데
이터베이스에 접속할 때는 <데이터베이스 별명>을 이용합니다.
C:\> db2 connect to <로컬 데이터베이스명>
C:\> db2 "values(current timestamp)"
C:\> db2 "values(current timestamp)"
5
DB2DBDFT 라는 레지스터리 변수를 이용하면, connect 문을 실행하
지 않고 SQL문을 요청했을 때, 자동적으로 해당 데이터베이스에 접속
됩니다. DPF 옵션을 사용하는 경우에는 DB2DBDFT 레지스터리 변수
를 설정합니다.
C:\> db2set DB2DBDFT=<기본 데이터베이스명>
C:\> db2 terminate
C:\> db2 "select * from syscat.tables"
6
terminate 명령어를 사용하면 현재의 데이터베이스 접속을 해제하
고, DB2 세션을 완전히 종료합니다.
C:\> db2 terminate
U D B 개 발 자 기 본 교 육 • UNIT 03 • 원격 서버 등록 29
TOPIC
03 06 응용프로그램 목록 확인
01
1
데이터베이스에 접속을 요청하면 통신 리스너 프로세스에 의해
중계자 프로세스인 db2agent 가 생성되어 활동에 필요한 개별
3
메모리를 할당받고, 접속된 응용프로그램은 고유한 핸들 번호로
2
엔진에 의해 관리됩니다.
Windows의 DB2 명령창에서 connect 문을 이용하여 원격 데
이터베이스에 접속합니다.
서버 머신에서 로그인하여 접속된 응용프로그램의 정보를 확인합니
다. show detail 옵션이 제공됩니다. 로컬에서 접속된 응용프로그램
은 "Application ID" 에 "*LOCAL"이 표시되며, 원격 클라이언트에서
접속된 응용프로그램은 "IP 주소"와 "port 번호"가 표시됩니다.
$ login <DB2 사용자명>
$ db2 list applications
C:\> db2 connect to <원격 데이터베이스명> user <원격
사용자명> using <원격 사용자 암호>
4
응용프로그램의 현재 상태를 확인하려면, SHOW DETAIL 옵션을 이
용합니다.
$ db2 list applications show detail
5
db2pd 또는 db2mtrk 명령어를 이용하여 db2agent 프로세스는 할
당받은 개별 메모리를 확인할 수 있습니다.
$ ps –ef | grep <인스턴스명> | grep db2agent
$ db2mtrk -p
에이전트 5284006용 메모리
6
other
apph
appctlh
16.0K
128.0K
16.0K
데이터베이스에 대한 접속을 해제하면, db2agent 프로세스는 제거
됩니다.
C:\> db2 connect reset
U D B 개 발 자 기 본 교 육 • UNIT 03 • 원격 서버 등록 30
TOPIC
04
01
UNIT04
DDL
UDB개발자기본교육
스키마
테이블
CREATE TABLE 문
데이터 유형
NULL 값과 DEFAULT 값
테이블스페이스 지정
고유키
기본키
참조 무결성
외부키
점검 제한 조건
IDENTITY 컬럼
인덱스
CREATE INDEX문
U D B 개 발 자 기 본 교 육 • UNIT 04 • D D L 31
TOPIC
04 01 스키마
01
1
테이블 등의 데이터베이스 오브젝트의 이름을 명시할 때는 <스
키마명>.<오브젝트명> 형식의 2-part name 을 사용하는 것이
5
원칙입니다. <스키마명>을 명시적으로 지정하지 않으면 <기본
스키마명>을 사용한 것으로 간주됩니다.
2
3
SQL문에서 <스키마명> 없이 <테이블명>만 지정하면, <현재 세
션의 로그온 사용자명>이 <기본스키마명>으로 인식됩니다. 아
래의 예에서 <테이블명>은 db2inst1.org로 인식됩니다.
$ login db2inst1
$ db2 connect to sample user user1 using dkagh
$ db2 values(current schema)
$ login db2inst1
$ db2 set current schema group1
$ db2 connect to sample
$ db2 values(current schema)
$ db2 "select * from org"
$ db2 "select * from org"
데이터베이스에 접속하는 connect 문에서 USER 와 USING 옵
션을 이용하면, <현 세션의 로그온 사용자명>에 관계 없이 <데
이터베이스 접속시에 사용된 사용자명>이 <기본스키마명>으로
인식됩니다. 예에서, <테이블명>은 user1.org로 인식됩니다.
$ login db2inst1
$ db2 connect to sample user user1 using dkagh
$ db2 "select * from org"
4
CURRENT SCHEMA 값은 values 문으로 현재값을 확인할 수 있습니
다. set current schema 문을 이용하여 CURRENT SCHEMA 특수 레
지스터리 변수를 변경하면, <데이터베이스 접속시 사용된 사용자명>
보다 우선적으로 적용됩니다. 예에서, <테이블명>은 group1.org로
인식됩니다.
CURRENT SCHEMA 특수 레지스터리 변수는 스키마명을 명시
적으로 지정하지 않는 경우에 사용되는 <기본스키마명>을 저장
하고 있습니다. set current schema 문은 데이터베이스에 접속
한 후에 실행할 수 있으며, 접속이 해제되면 <로그온 사용자명>
으로 복원됩니다.
6
데이터베이스의 오브젝트를 지정할 때는 개별적인 SQL문에서 <스키
마명>을 명시적으로 지정하는 것이 권장됩니다. <현재 세션의 로그
온 사용자명>, <데이터베이스 접속시에 사용된 사용자명>,
<CURRENT SCHEMA 특수 레지스터리 변수의 현재값> 보다 SQL문
에서 명시적으로 지정한 <스키마명>이 가장 우선적으로 적용됩니다.
예에서, <테이블명>은 group2.org로 인식됩니다.
$ login db2inst1
$ db2 connect to sample user user1 using dkagh
$ db2 set current schema group2
$ db2 "select * from org"
U D B 개 발 자 기 본 교 육 • UNIT 04 • D D L 32
TOPIC
04 02 테이블
01
1
사용자의 데이터는 테이블에 저장됩니다. 테이블의 데이터는 기
본적으로 한 개의 테이블스페이스에 저장됩니다. CREATE
5
$ db2 "drop table <스키마명>.<테이블명>"
TABLE, ALTER TABLE, DROP TABLE 문으로 관리합니다.
2
한 테이블스페이스에는 한 개 이상의 테이블이 저장됩니다.
6
Table 1
Table 2
$ db2 list tables for schema <스키마명>
database2
Tablespace A
Table 3
Tablespace B
Table 4
$ db2 list tables for system
$ db2 list tables for all
Tablespace A
Table 1
Table 2
7
3
create table 문을 이용하여 테이블과 컬럼 정보를 정의하고,
테이블스페이스명을 지정합니다. IMPLICIT_SCHEMA 특권이 있
으면, 존재하지 않는 <스키마명>을 이용하여 테이블을 정의할
수 있습니다. 테이블의 한 행의 총 길이는 지정한 테이블 스페이
스의 페이지 크기보다 작아야 합니다.
alter table 문을 이용하여 컬럼 추가, 고유키 추가 및 제거, 기
본키 추가 및 제거, 외부키 추가 및 제거, 점검 제한 조건 추가 및
제거 등의 변경 작업이 가능합니다.
테이블에 대한 정보는 SYSCAT.TABLES 뷰를 이용해서 확인합니다.
$ db2 "select * from syscat.tables"
8
describe table 문으로 테이블의 컬럼에 대한 정보를 확인합니다.
$ db2 "describe table <스키마명>.<테이블명>"
$ db2 "create table <스키마명>.<테이블명> (<컬럼정
의>)"
4
list tables 명령어에서 테이블의 목록을 확인할 수 있습니다.
$ db2 list tables
Database Manager Instance
database1
drop table문으로 테이블을 제거합니다.
9
db2look 명령어로 테이블에 대한 DDL문을 추출할 수 있습니다.
$ db2look –d <DB명> –e –z <스키마명> –t <테이블명> -o <파
일명>
U D B 개 발 자 기 본 교 육 • UNIT 04 • D D L 33
TOPIC
04 03 CREATE TABLE 문
01
1
create table 문은 테이블을 생성할 때 이용하는 SQL문입니다.
3
옵션에 대한 설명은 다음과 같습니다.
컬럼, 고유키, 기본키, 외부키, 점검 제한 조건 등을 정의하고, 데
옵션
이터와 인덱스를 저장할 테이블스페이스를 지정합니다.
<스키마명>
2
설명
임의의 이름으로 지정합니다. <스키마명>을 생략
하면 CURRENT SCHEMA 특수 레지스터리 변수의
자세한 옵션은 다음과 같습니다.
값이 기본 스키마명으로 사용됩니다.
<테이블명>
임의의 이름으로 지정합니다. 한 데이터베이스에
서 <스키마명>.<테이블명>은 고유해야 합니다.
<컬럼명>
테이블 내에서 고유한 임의의 이름으로 지정합니
다.
<데이터 유형>
컬럼의 데이터 유형을 지정합니다.
<NULL 허용 여
NULL값을 허용하지 않으려면 'NOT NULL' 로 지정
부>
합니다.
<기본값>
WITH DEFAULT 옵션으로 기본값을 지정합니다.
IN <TS명>
테이블의 데이터가 저장될 테이블스페이스명을 지
정합니다.
4
INDEX IN <TS
인덱스 데이터가 저장될 테이블스페이스명을 지정
명>
합니다.
LONG IN <TS
LONG 데이터가 저장될 테이블스페이스명을 지정
명> LOGGED INITIALLY
합니다.
NOT
특성은 ALTER TABLE 문으로 활성화할 때만
적용되고,
COMMIT 또는
ROLLBACK시에
해제됩니다.
NOT 사항을 로
NOT LOGGED
트랜잭션에서
해당 테이블에
대한 변경
LOGGED
SQL이 실패하면,
테이블을 재생성해야
INITIALLY모드에서 실행한
그에 기록하지
않게 합니다.
합니다.
U D B 개 발 자 기 본 교 육 • UNIT 04 • D D L 34
TOPIC
04 04 데이터 유형
01
1
기본적으로 지원되는 컬럼의 데이터 유형은 다음과 같습니다.
CREATE DISTINCT TYPE 문으로 사용자가 새로운 데이터 유형을
2
구분
추가로 생성하여 사용할 수도 있습니다.
D a ta T ypes
N um e ric
Intege r
S M A LL IN T
IN T E G E R
B IG IN T
D E C IM A L
D E C IM A L
Floating
P o int
REAL
DOUBLE
대표적인 데이터 유형에 대한 설명은 다음과 같습니다.
C haracter
S trin g
S ingle B yte
D o uble B yte
B in ary
S tring
CHAR
VARCHAR
LO N G V A R C H A R
C LO B
2
-32,768 ~ +-32,767
INT
4
-2,147,483,648 ~
+2,147,483,647
BIGINT
8
-9,223,372,036,854,775,808 ~
+9,223,372,036,854,775,807
DEC(p,s)
(p+s)/2+1
31 자리
DOUBLE
8
-1.79769E+308 ~
+1.79769E+308
n
254 바이트
n+4
4000 바이트 (4K 페이지인 경우)
32672 바이트 (32K 페이지인
경우)
10
0001-01-01 ~ 9999-12-31
TIME
8
00:00:00 ~ 24:00:00
TIMESTAMP
26
0001-01-01-00.00.00.000000 ~
9999-12-31-24.00.00.000000
VARCHAR(n)
G R A P H IC
V A R G R A P H IC
L O N G V A R G R A P H IC
D B C LO B
날 짜 DATE
B LO B
VARCHAR FOR BIT DATA
D atetim e
DATE
T IM E
T IM E S T A M P
D atalink
3
최대범위
숫 자 SMALLINT
문 자 CHAR(n)
S tring
BYTE 수
유형
페이지 크기별 SQL 한계 정보는 http://publib.boulder.ibm.com/
infocenter/db2luw/v8/topic/com.ibm.db2.udb.doc/admin/r0
001029.htm 를 참조합니다.
U D B 개 발 자 기 본 교 육 • UNIT 04 • D D L 35
TOPIC
04 05 NULL 값과 DEFAULT 값
01
1
테이블을 정의할 때, 각 컬럼에 NULL 값과 DEFAULT 값을 허용
하게 할 수 있습니다. DEFUALT 속성을 가지지 않는 컬럼은
4
WITH DEFAULT 옵션만 지정하면 시스템 기본값이 제공됩니다.
유형
INSERT 시에 반드시 명시적으로 값을 지정해야 합니다. CREATE
기본값
TABLE 문에서 NOT NULL 옵션과 WITH DEFULAT 옵션을 이용합
숫자
0
0
니다.
문자
EMPTY STRING
길이가 0 인 문자
DATE
CURRENT DATE
현재 시스템 날짜
TIME
CURRENT TIME
현재 시스템 시간
TIMESTAMP
CURRENT TIMESTAMP
현재 시스템 시간 소
인
5
CREATE TABLE 문에서 WITH DEFAULT <기본값> 옵션을 지정하면 사
용자가 지정한 값이 기본값으로 사용됩니다.
유형
2
예
NULL 값은 알 수 없는 값을 의미합니다. NULL 값은 0 또는 공백
숫자
WITH DEFAULT 10
(blank) 또는 empty string 이 아닙니다. empty string은 길이
문자
WITH DEFAULT 'xx'
DATE
WITH DEFAULT '2006-04-17'
TIME
WITH DEFAULT '14:12:30'
TIMESTAMP
WITH DEFAULT '2006-04-17-14.12.30.694001'
가 0인 값을 의미하며, 공백 문자와는 다릅니다. 테이블을 정의
할 때, 컬럼에 NULL 값을 허용하지 않으려면 CREATE TABLE 문
3
설명
에서 NOT NULL 옵션을 이용합니다.
날짜 유형의 표현식은 OS 설정에 따라 달라집니다.
$ db2 "values (current date)"
$ db2 "values (current time)"
$ db2 "values (current timestamp)"
U D B 개 발 자 기 본 교 육 • UNIT 04 • D D L 36
TOPIC
04 06 테이블스페이스 지정
01
1
CREATE TABLE 문에서 IN 키워드를 이용하여 테이블스페이스를
지정할 수 있습니다. INDEX IN, LONG IN 키워드로 테이블, 인덱
4
스, LONG 데이터를 개별적인 DMS 테이블스페이스에 저장할
수 있습니다. 지정한 테이블스페이스는 변경될 수 없습니다.
CREATE TABLE 문에서 INDEX IN 키워드를 이용하여 인덱스를 위한
데이터를 별도의 테이블스페이스에 저장할 수 있습니다. IN 옴션과
INDEX IN 옵션에서 지정한 테이블스페이스는 DMS 방식의
REGULAR 유형이어야 합니다. INDEX IN 옵션만 지정할 수는 없습니
다.
$ db2 "create table kes.t1 (c1 int, …) IN ts1 INDEX IN ts2"
2
CREATE TABLE 문에서 LONG IN 키워드를 이용하여 LONG 데이터
를 별도의 테이블스페이스에 저장할 수 있습니다. IN 옴션에서 지정
한 테이블스페이스는 DMS 방식의 REGULAR 유형이고, LONG IN 옵
션에서 지정한 테이블스페이스는 DMS 방식의 LARGE 유형이어야
합니다. INDEX IN 옵션은 지정하지 않았다면, 인덱스는 테이블과 동
일한 테이블스페이스에 저장됩니다. LONG IN 옵션만 지정할 수는
없습니다.
$ db2 "create table kes.t1 (c1 int, …) IN ts1 LONG IN ts3"
6
CREATE TABLE 문에서 IN, INDEX IN, LONG 옵션을 모두 사용하여
테이블 데이터, 인덱스 데이터, LONG 데이터를 별도의 DMS 테이블
스페이스를 저장할 수 있습니다. 한 테이블이 여러 테이블스페이스에
저장되었다면, 테이블스페이스는 함께 drop 되어야 합니다.
CREATE TABLE 문에서 IN 옵션을 지정하지 않으면, 테이블은 기
본 사용자 테이블스페이스에 저장됩니다. 기본 사용자 테이블스
페이스는 사용자가 정의한 테이블스페이스 중에서 해당 테이블
의 행의 총 길이를 수용할 수 있는 페이지 크기를 가진 첫 번째
3
5
REGULAR 유형의 테이블스페이스입니다.
CREATE TABLE 문에서 IN 옵션으로 테이블이 저장될 테이블스
페이스를 지정합니다. 테이블의 모든 데이터와 인덱스 데이터는
동일한 테이블스페이스에 저장됩니다.
$ db2 "create table kes.t1 (c1 int, …) IN ts1 INDEX IN ts2
LONG IN ts3"
$ db2 "create table kes.t1 (c1 int, …) IN ts1"
U D B 개 발 자 기 본 교 육 • UNIT 04 • D D L 37
TOPIC
04 07 고유키
01
1
고유키는 한 개 이상의 컬럼들로 구성되어 테이블의 각 행을 고
3
고유키 제한 조건을 정의하는 구문은 다음과 같습니다. 고유키를 구
성하는 각 컬럼은 NOT NULL 속성을 지정해야 합니다.
4
create table 문에서 CONSTRAINT ~ UNIQUE 라는 옵션으로 지정
합니다. <제한조건명>과 동일한 이름을 가진 고유 인덱스가 자동적
으로 생성됩니다. 고유키는 한 테이블에 여러 개 정의할 수 있습니다.
CONSTRAINT 옵션을 지정하지 않으면, 제한조건명과 인덱스의 이름
은 'SQLyymmddhhmmssxxx' 형식으로 엔진이 부여합니다. <제한조
건명>은 데이터베이스 내에서 고유해야 합니다.
$ db2 "create table kes.t1 (…, <고유키 제한 조건절>)"
5
alter table 문을 이용하여 고유키를 추가할 수 있습니다.
유하게 구별하는 값입니다. 한 테이블에 한 개 이상의 고유키를
지정할 수 있습니다. 고유키를 정의하면, 해당 컬럼들로 구성된
고유 인덱스가 자동적으로 생성됩니다.
$ db2 "alter table kes.t1 ADD <고유키 제한 조건절>"
6
2
고유키에 대응하는 인덱스가 이미 존재하면, SQL0000W 라는
alter table 문을 이용하여 고유키를 제거할 수 있습니다.
$ db2 "alter table kes.t1 DROP CONSTRAINT <제한 조건
명>"
경고 메시지가 반환되지만, 무시해도 됩니다.
U D B 개 발 자 기 본 교 육 • UNIT 04 • D D L 38
TOPIC
04 08 기본키
01
1
기본키는 고유 키와 동일한 특성을 갖지만, 한 테이블에 한 개만
3
기본키 제한 조건을 정의하는 구문은 다음과 같습니다. 기본키를 구
성하는 각 컬럼은 NOT NULL 속성을 지정해야 합니다.
4
create table 문에서 CONSTRAINT ~ PRIMARY KEY 라는 옵션으로
지정합니다. <제한조건명>과 동일한 이름을 가진 고유 인덱스가 자
동적으로 생성됩니다. 기본키는 한 테이블에 한 개만 정의할 수 있습
니다. CONSTRAINT 옵션을 지정하지 않으면, 제한조건명과 인덱스의
이름은 'SQLyymmddhhmmssxxx' 형식으로 엔진이 부여합니다. <제
한조건명>은 데이터베이스 내에서 고유해야 합니다.
$ db2 "create table kes.t1 (…, <기본키 제한 조건절>)"
5
alter table 문을 이용하여 기본키를 추가할 수 있습니다.
지정할 수 있습니다. 기본키는 한 개 이상의 컬럼들로 구성될 수
있으며, 해당 컬럼들로 구성된 고유 인덱스가 자동적으로 생성
됩니다.
$ db2 "alter table kes.t1 ADD <기본키 제한 조건절>"
6
2
고유키에 대응하는 인덱스가 이미 존재하면, SQL0000W 라는
경고 메시지가 반환되지만, 무시해도 됩니다. 고유키와 기본키
alter table 문을 이용하여 기본키를 제거할 수 있습니다.
$ db2 "alter table kes.t1 DROP CONSTRAINT <제한 조건
명>"
는 기능적으로 동일합니다. 단, IMPORT 명령어의
INSERT_UPDATE 옵션을 사용할 때에는 반드시 기본키가 필요합
니다.
U D B 개 발 자 기 본 교 육 • UNIT 04 • D D L 39
TOPIC
04 09 참조 무결성
01
1
두 테이블이 고유키와 외부키로 연결되어 외부키를 가진 테이블
에 데이터를 추가, 변경하는 경우에 데이터의 참조 무결성이 유
지됩니다. 고유키를 가진 테이블에 데이터를 변경, 제거하는 경
UPDATE 규칙
설명
NO ACTION
다른 RI 관계의 UPDATE 규칙을 먼저 적용하고, 자
신의 UPDATE 규칙을 적용합니다. 변경되는 행의
고유키 값을 참조하고 있는 자손 테이블의 행이 존
재하면, SQL0531N 오류 코드가 반환되고,
UPDATE 문이 실패합니다.
우에는 UPDATE 규칙과 DELETE 규칙이 적용됩니다.
RESTICT
2
외부키를 가진 자손 테이블에 INSERT 문으로 데이터를 추가할
때, 제공된 외부키가 부모 테이블의 고유키에 존재하는 값인지
점검합니다. 존재하지 않는 값인 경우에는 SQL0530N 오류 코드
5
다른 RI 관계의 UPDATE 규칙보다 자신의 UPDATE
규칙을 먼저 적용하는 것이 NO ACTION과 다른
점입니다.
고유키를 가진 부모 테이블에서 DELETE 문을 실행할 때는 다음과 같
이 4 가지의 DELETE 규칙을 적용받게 할 수 있습니다. CREATE TABLE
문에서 외부키를 정의할 때 ON DELETE 옵션을 이용하여 지정합니다.
가 반환되고, INSERT 문은 실패합니다. 부모 테이블에 INSERT문
DELETE 규칙
설명
을 실행할 때, 점검 규칙은 필요하지 않습니다. 자손 테이블에 외
NO ACTION
RESTICT
삭제되는 행의 고유키 값을 참조하고 있는 자손 테
이블의 행이 존재하면, SQL0532N 오류 코드가 반
환되고, DELETE 문이 실패합니다.
CASCADE
삭제되는 행의 고유키 값을 참조하고 있는 자손 테
이블의 행을 함께 삭제합니다.
SET NULL
삭제되는 행의 고유키 값을 참조하고 있는 자손 테
이블의 행의 외부키의 값을 NULL 값으로 변경합니
다. 자손 테이블의 외부키 컬럼이 NULL 을 허용하
는 컬럼일 때 지정할 수 있습니다.
부키에 입력된 데이터는 부모 테이블의 고유키에 존재하는 값이
므로 항상 참조가 가능합니다. 이러한 기능을 '참조 무결성 (RI,
3
Refrential Integrity)' 라고 합니다.
외부키는 자신의 테이블에 있는 고유키를 참조할 수도 있습니다.
동일한 부모 테이블의 고유키를 여러 자손 테이블의 외부키가
참조할 수 있습니다.
4
고유키를 가진 부모 테이블에서 UPDATE 문을 실행할 때는 다음
과 같이 2 가지의 UPDATE 규칙을 적용받게 할 수 있습니다.
CREATE TABLE 문에서 외부키를 정의할 때 ON UPDATE 옵션을
이용하여 지정합니다.
U D B 개 발 자 기 본 교 육 • UNIT 04 • D D L 40
TOPIC
04 10 외부키
01
1
외부키는 부모 테이블의 고유키 또는 기본키를 참조하는 키입니
2
외부키 제한 조건을 정의하는 구문은 다음과 같습니다.
3
create table 문에서 CONSTRAINT ~ FOREIGN KEY 라는 옵션으로
지정합니다. 외부키는 한 테이블에 여러 개 정의할 수 있습니다.
CONSTRAINT 옵션을 지정하지 않으면, 제한 조건명은
'SQLyymmddhhmmssxxx' 형식으로 엔진이 부여합니다. <제한조건
명>은 데이터베이스 내에서 고유해야 합니다.
$ db2 "create table kes.t1 (…, <외부키 제한 조건절>)"
4
alter table 문을 이용하여 외부키를 추가할 수 있습니다.
다. 참조하는 고유키 또는 기본키와 호환되는 컬럼들로 구성되
어야 하며, 각 컬럼은 NULL 값을 허용합니다. RI 관계를 유지하
기 위한 DELETE규칙과 UPDATE 규칙을 명시합니다.
$ db2 "alter table kes.t1 ADD <외부키 제한 조건절>"
5
alter table 문을 이용하여 외부키를 제거할 수 있습니다.
$ db2 "alter table kes.t1 DROP CONSTRAINT <제한 조건
명>"
U D B 개 발 자 기 본 교 육 • UNIT 04 • D D L 41
TOPIC
04 11 점검 제한 조건
01
1
테이블의 컬럼에 입력되는 값을 제한하는 조건입니다. INSERT와
UPDATE 문을 실행하면 자동적으로 입력된 값에 대한 점검이 실
2
점검 제한 조건을 정의하는 구문은 다음과 같습니다.
3
create table 문에서 CONSTRAINT ~ CHECK 라는 옵션으로 지정합
니다. 점검 제한 조건은 한 테이블에 여러 개 정의할 수 있습니다.
CONSTRAINT 옵션을 지정하지 않으면, 제한 조건명은
'SQLyymmddhhmmssxxx' 형식으로 엔진이 부여합니다. <제한조건
명>은 데이터베이스 내에서 고유해야 합니다.
$ db2 "create table kes.t1 (…, <점검 제한 조건절>)"
4
alter table 문을 이용하여 점검 제한 조건을 추가할 수 있습니다.
행되어 조건에 맞지 않는 값인 경우에는 오류를 반환합니다.
$ db2 "alter table kes.t1 ADD <점검 제한 조건절>"
5
alter table 문을 이용하여 점검 제한 조건을 제거할 수 있습니다.
$ db2 "alter table kes.t1 DROP CONSTRAINT <제한 조건
명>"
7
점검 제한 조건에 포함되는 조건식은 SQL 문의 WHERE 조건절의 표
현식과 동일합니다.
U D B 개 발 자 기 본 교 육 • UNIT 04 • D D L 42
TOPIC
04 12 IDENTITY 컬럼
01
1
INSERT 문이 실행되면 자동적으로 그 값이 증가되는 컬럼입니다.
3
컬럼의 데이터 유형은 숫자 유형으로 한 테이블에 한 개만 정의
옵션
할 수 있습니다. CREATE TABLE 문에서 GENERATED 라는 옵션
으로 지정할 수 있습니다.
4
2
주요한 옵션은 다음과 같습니다.
설명
GENERATED
ALWAYS
엔진에 의해 자동적으로 생성된 값만 허용됩니다.
사용자가 명시적으로 값을 지정하여 입력할 수
없습니다.
GENERATED BY
DEFAULT
사용자가 값을 지정하지 않는 경우에만 엔진이
자동적으로 값을 생성합니다. 값의 고유성을 보
장할 수 없습니다.
START WITH
양수 또는 음수의 시작값을 지정합니다.
INCREMENT BY
양수 또는 음수의 증가값을 지정합니다.
MAXVALUE
양수 또는 음수의 최대값을 지정합니다.
CYCLE
최대값에 도달하면 다시 최소값부터 시작합니다.
CACHE
지정된 개수의 생성값을 미리 캐쉬에 보관합니다.
사용
예는 다음과 같습니다.
CACHE 옵션에서 지정된 개수의 값은 지정된 개수의 생성값을
성능 향상을 위해 사용됩니다. 데이터베이스가 비활성화되면,
사용되지 않고 캐쉬에 남아있던 자동 생성값은 유실됩니다.
U D B 개 발 자 기 본 교 육 • UNIT 04 • D D L 43
TOPIC
04 13 인덱스
01
1
효율적인 데이터 액세스를 위해서 한 테이블에 한 개 이상의 인
2
문으로 관리합니다.
create index 문으로 컬럼명과 컬럼별 정렬 순서를 지정합니다.
덱스를 생성할 수 있습니다. CREATE INDEX 문과 DROP INDEX
4
INCLUDE 옵션으로 추가된 컬럼들은 인덱스의 데이터 페이지에 RID
와 함께 저장되어, 인덱스 전용 액세스를 가능하게 합니다. 반드시
UNIQUE 옵션을 함께 지정해야 합니다. INCLUDE 옵션에서 지정한
컬럼은 인덱스를 구성하는 컬럼이 아니므로, 이 컬럼을 이용한 조건
식으로 인해 index scan 이 선택되지는 않습니다.
$ db2 "create unique index kes.x4 on kes.t1 (c4) INCLUDE (c9)"
5
ALLOW REVERSE SCANS 옵션을 사용하면 양방향 액세스를 허용합
니다.
$ db2 "create UNIQUE index kes.x5 on kes.t1 (c5) CLUSTER
ALLOW REVERS SCANS"
6
drop index 문으로 제거하며, 테이블이 제거되면 자동적으로 제거됩
니다.
$ db2 "drop index kes.x2"
7
인덱스에 대한 정보는 SYSCAT.INDEXES 뷰 또는 describe indexes
명령어를 이용하여 확인합니다.
기본적으로 인덱스는 중복된 값을 허용하므로 중복된 행을 허용
하지 않는 인덱스를 생성하려면 UNIQUE 옵션을 이용합니다. 고
유 인덱스는 인덱스키에 NULL 값을 허용하지만, NULL 값을 가
진 행은 한 개만 허용됩니다.
$ db2 "create index kes.x2 on kes.t1 (c2)"
$ db2 "create UNIQUE index kes.x3 on kes.t1 (c3)"
3
CLUSTER 옵션을 이용하면, 해당 인덱스의 정렬 순서를 기준으
로 테이블의 데이터가 물리적으로 배치되므로 효율적인 액세스
가 가능합니다. CLUSTER 옵션을 가진 인덱스는 한 테이블에 한
개만 가능하므로, 가장 중요한 인덱스를 CLUSTER 인덱스로 정
의합니다.
$ db2 "create unique index kes.x1 on kes.t1 (c1) CLUSTER"
$ db2 "select * from syscat.indexes"
High Cluster Ratio
Index
Table
Table
Low Cluster Ratio
Index
$ db2 describe indexes for table kes.t1 show detail
8
db2look 명령어를 이용하여 테이블과 함께 인덱스에 대한 DDL을 추
출합니다.
$ db2look –d sample –e –z kes –t t1 -o t1.ddl
U D B 개 발 자 기 본 교 육 • UNIT 04 • D D L 44
TOPIC
04 14 CREATE INDEX 문
01
1
테이블에 인덱스를 생성하는 SQL문입니다. UNIQUE, CLUSTER,
INCLUDE, ALLOW REVERSE SCANS 등의 옵션을 가진 인덱스
를 생성할 수 있습니다. create index 문의 형식은 다음과 같습
니다.
2
주요한 옵션은 다음과 같습니다.
모드
설명
UNIQUE
고유 인덱스로 생성합니다.
<인덱스명>
임의의 고유한 이름으로 지정합니다.
ON <테이블명>
인덱스가 생성될 테이블명을 지정합니
다.
<컬럼명>
인덱스를 구성하는 컬럼명을 지정합니
다. 한 개 이상인 경우에는 ,(컴마)로 구
분합니다.
ASC / DESC
컬럼별 정렬 순서를 오름차순(ASC) 또
는 내림차순(DESC)로 지정합니다. 기
본값은 ASC 입니다.
INCLUDE (<컬럼명>)
인덱스의 리프 페이지에 RID와 함께 저
장되는 컬럼을 지정합니다. 한 개 이상
인 경우에는 ,(컴마)로 구분합니다.
CLUSTER
클러스터 인덱스로 지정합니다.
PCTFREE
인덱스의 각 페이지의 여유 공간 비율
로 백분율로 지정합니다. 기본값은 10
입니다.
MINPCTUSED
인덱스의 리프 페이지의 최소 사용 공
간 비율로 백분율로 지정합니다. 50 이
하로 지정하는 것이 성능에 유리합니다.
ALLOW REVERSE SCANS
역방향 액세스를 허용합니다.
U D B 개 발 자 기 본 교 육 • UNIT 04 • D D L 45
TOPIC
05
01
UNIT05
DML
UDB개발자기본교육
시스템 레지스터리
카탈로그 테이블과 뷰
NULL값 처리
CASE 문
OUTER JOIN
Dummy 테이블
Common 테이블
Temporary 테이블
Transition 테이블
MQT
Identity 컬럼
Sequence
집합 연산
FOR READ ONLY
FOR UPDATE
문자열 스킬라 함수
숫자 스칼라 함수
날짜 스칼라 함수
형변환 스칼라 함수
컬럼 함수
스냅샷 테이블 함수
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 46
TOPIC
05 01 시스템 레지스터리
01
1
Special Register 라고 부르며, SQL문에서 직접 참조하여
DBMS 시스템에 관련된 여러가지 환경 값을 확인할 수 있습니다.
3
current date 등의 레지스터리는 참조만 가능하며, current
explain mode 등은 변경도 가능합니다.
2
SQL문에서 참조되므로, 데이터베이스에 대한 접속이 필요합니다. 레
지스터리명은 대소문자를 구분하지 않습니다. 레지스터리명에 포함
된 공백 문자의 길이는 두 바이트 이상도 유효합니다.
$ db2 "select id, hire_date, current date from kes.empl"
제공되는 레지스터리의 목록은 다음과 같습니다.
4
변경하는 방법은 다음과 같습니다. 일부 레지스터리에 대한 변경은
현재의 세션에서만 유효합니다.
$ db2 set current explain mode yes
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 47
TOPIC
05 02 카탈로그 테이블과 뷰
01
1
데이터베이스를 생성하면 SYSCATSPACE 테이블스페이스에 기
3
본적인 시스템 카탈로그 테이블이 생성되어 데이터베이스에 대
한 메타데이터를 저장합니다. 카탈로그 테이블은 SYSIBM,
SYSCAT, SYSSTAT 라는 스키마명을 가집니다.
2
시스템 카탈로그 테이블의 정보는 SQL문을 이용하여 확인합니다. 카
탈로그에 저장된 데이터베이스 오브젝트인 테이블, 인덱스 등의 이름
은 대문자로 저장됩니다.
$ db2 "select * from <시스템 카탈로그 테이블>"
시스템 카탈로그 테이블의 목록을 확인합니다. 카탈로그는
SYSIBM, SYSCAT, SYSSTAT 라는 스키마명을 가집니다. 시스템
카탈로그 테이블과 뷰는 기본적으로 조회만 가능하고, SYSSTAT
스키마를 가진 시스템 카탈로그 뷰는 UPDATE도 허용됩니다.
$ db2 connect to sample
$ db2 list tables for system
4
시스템 카탈로그 뷰의 정보를 확인합니다. 시스템 카탈로그 테이블보
다 시스템 카탈로그 뷰를 액세스하는 것이 편리합니다.
$ db2 list tables for all | grep SYSIBM
$ db2 list tables for all | grep SYSCAT
$ db2 "select * from <시스템 카탈로그 뷰>"
$ db2 list tables for all | grep SYSSTAT
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 48
TOPIC
05 03 NULL값 처리
01
1
문자열의 병합시 NULL값이 포함되면 결과는 NULL이 됩니다.
NULL 값은 다른 NULL 값과 비교할 수 없으므로 JOIN 시에도 동
4
NULL 값은 알 수 없는 값이므로, 두 개의 NULL 값은 서로 비교될 수도
없으며, 같은 값으로 인식되지 않습니다. CLP는 NULL 값을 표시하기
위해 - (대쉬)를 사용하므로 주의합니다.
5
SQL문에서 NULL값을 명시하려면, NULL 이라는 키워드를 이용합니
다.
$ db2 "insert into kes.t1 values (1,’홍길동’,NULL,100)"
일한 값으로 처리되지 않습니다.
2
NULL 값은 알 수 없는 값이므로 문자열과의 병합시 그 결과는
NULL값이 반환됩니다. COALEASE 또는 VALUE 함수를 이용하
여 병합의 대상이 되는 값이 NULL값이 되지 않도록 합니다.
coalease와 value는 두 개 이상의 인수를 명시할 수 있습니다.
3
테이블을 정의할 때, 컬럼에 NULL 값을 허용하지 않으려면 NOT
NULL 키워드를 이용합니다.
$ db2 "select c1, c2, c3, nullif(c4,100) from kes.t1"
6
NULL값을 비교하려면, IS NULL 또는 IS NOT NULL 이라는 키워드를
이용합니다.
$ db2 "select * from kes.t1 where c3 IS NULL"
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 49
TOPIC
05 04 CASE 문
01
1
여러 개의 조건식을 판별하여 결과값을 반환하도록 할 때에는
CASE 문을 사용합니다. CASE 문은 SQL문에서 표현식이 위치
4
쿼리문의 SELECT 절에 CASE 문이 포함된다면, AS 키워드를 이용하
여 결과 컬럼명을 명시하도록 합니다.
될 수 있는 임의의 위치에 사용될 수 있습니다.
2
개별적인 조건식이 모두 동일한 컬럼 또는 표현식에 대한 동등
비교인 경우에는 다음과 같이 비교되는 대상을 공통적으로 표현
합니다.
3
개별적인 조건식이 모두 다르다면, 개별적으로 조건식으로 표현
합니다.
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 50
TOPIC
05 05 OUTER JOIN
01
1
OUTER JOIN 은 FROM 절에서 LEFT, RIGHT, FULL OUTER JOIN
2
INNER JOIN 인 경우에도 FROM 절에서 INNER와 ON 키워드를
키워드를 이용하고, ON 절을 이용하여 조인 조건을 표현합니다.
5
FULL OUTER JOIN은 두 테이블간의 INNER JOIN의 결과와 명시된 두
개의 테이블에서 누락된 행들을 함께 반환합니다.
이용하여 표현할 수 있습니다. 일반적으로 INNER 조인은
WHERE 절에서 조인 조건절을 언급합니다.
3
RIGHT OUTER JOIN은 두 테이블간의 INNER JOIN의 결과와 오
른쪽에 명시된 테이블에서 누락된 행들을 함께 반환합니다.
4
LEFT OUTER JOIN은 두 테이블간의 INNER JOIN의 결과와 왼쪽
에 명시된 테이블에서 누락된 행들을 함께 반환합니다.
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 51
TOPIC
05 06 Dummy 테이블
01
1
SYSIBM.SYSDUMMY1 테이블 또는 VALUES ~ INTO 구문을 이용
하여 시스템 특수 레지스터리의 값을 참조하면 편리합니다.
2
특정 테이블에 연관되지 않고, 시스템 특수 레지스터리 값을 참
조할 때는 사용합니다.
3
ESQL 또는 SQL PL에서는 VALUES~INTO 구문으로 특정 테이블
을 언급하지 않고, 직접 프로그램 변수에 특수 레지스터리 값을
저장할 수 있습니다.
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 52
TOPIC
05 07 Common 테이블
01
1
SELECT 문을 실행하는 순간에만 생성되는 뷰를 공통 테이블이
라고 합니다. WITH 절을 이용하여 한 개 이상을 표현할 수 있으
4
recursive query 를 표현할 때 이용합니다.
5
복잡한 쿼리를 간단하게 표현할 때 주로 사용됩니다. 해당 SQL문에서
만 유효하며, SQL문이 종료되면 자동적으로 소멸됩니다.
며, 이미 정의된 공통 테이블은 다음 공통 테이블 또는 FROM 절
2
3
에서 언급될 수 있습니다.
구문은 다음과 같습니다.
사용 방법은 다음과 같습니다.
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 53
TOPIC
05 08 Temporary 테이블
01
1
사용자 임시 테이블 스페이스에 temporary table을 생성할 수
있으며, 세션별로 독립적으로 생성됩니다. SESSION 이라는 스
5
사용 방법은 다음과 같습니다.
키마명을 자동적으로 갖게 되며, 세션이 종료되면 자동적으로
2
소멸됩니다.
구문은 다음과 같습니다.
3
Temporary 테이블을 정의하려면 해당 데이터베이스에 사용자
임시 테이블스페이스가 필요합니다. 사용자 임시 테이블스페이
스는 자동적으로 생성되지 않습니다.
4
세션마다 독립적으로 생성되고, 세션이 종료되면 자동적으로 소
멸됩니다. SQL문에서 언급할 때는 스키마명은 반드시 session
이라고 명시합니다.
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 54
TOPIC
05 09 Transition 테이블
01
1
UPDATE, DELETE, INSERT 문의 실행 전후의 테이블 데이터를 저
4
SQL PL 에서 사용하는 예제입니다.
장하고 있는 전이 상태의 테이블입니다.
2
OLD TABLE은 DELETE, UPDATE 문에서 사용 가능하며, NEW
TABLE은 INSERT, UPDATE 문에서 사용 가능합니다.
3
UPDATE 문을 먼저 실행하고, 그 결과 행을 조회하여 p_name
변수에 할당합니다.
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 55
TOPIC
05 10 MQT
01
1
집계 함수를 이용한 MQT(Materialized Query Table) 을 미리
정의해 두고, 필요 시점에 refresh table 명령어를 이용하여 미
리 집계를 실행하면, 집계 함수를 이용한 복잡한 쿼리의 실행 시
2
5
적절한 MQT가 존재한다면, 옵티마이저는 쿼리를 재작성하여 MQT
를 사용하도록 할 수 있습니다. 예에서, 사용자가 생성한 원래의 쿼리
는 staff_summary 라는 MQT를 사용할 수 있도록 재작성되었습니다.
간을 단축시킬 수 있습니다.
구문은 다음과 같습니다.
3
다음과 같은 형식으로 생성합니다.
4
쿼리에서 MQT를 사용하려면 REFRESH 모드에 무관하게 최소한
한 번의 refresh table 명령이 필요합니다.
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 56
TOPIC
05 11 identity 컬럼
01
1
테이블 수준에서 정의되는 identity column은 테이블의 각 행
을 고유하게 식별하게 하는 역할을 합니다.
2
데이터 유형은 숫자 유형인 integer, bigint 등을 사용합니다.
3
INSERT 문에서 언급하지 않는 경우에 자동적으로 값이 생성되어
입력됩니다.
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 57
TOPIC
05 12 Sequence
01
1
2
3
데이터베이스 수준에서 생성되며, 참조시마다 고유한 값을 생성
하는 역할을 합니다. PREVVAL과 NEXTVAL을 이용하여 참조됩
니다.
데이터 유형은 숫자 유형인 integer, bigint 등을 사용합니다.
INSERT 문에서 nextval을 참조하면 자동적으로 값이 생성되어
입력됩니다.
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 58
TOPIC
05 13 집합 연산
01
1
UNION, UNION ALL, EXCEPT, EXCEPT ALL, INTERSECT,
2
ALL 키워드는 최종 결과 집합에서 중복된 행응 허용하게 합니다.
3
UNION 문은 합집합을 생성합니다.
INTERSECT ALL 을 지원합니다.
4
INTERSECT문은 교집합을 생성합니다.
5
EXCEPT문은 차집합을 생성합니다.
ALL 이 명시되지 않으면, 내부적으로 정렬 작업이 발생합니다.
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 59
TOPIC
05 14 FOR READ ONLY
01
1
단순히 조회용으로만 사용되는 커서를 선언할 때 이 옵션을 명
시하면 Unambigous 커서가 되므로 프리컴파일 또는 바인드시
BLOCKING 옵션의 적용 범위가 확대됩니다. 데이터는 변경되
지 않으므로 WITH UR 옵션을 사용하면, 동시성이 높아집니다.
2
3
커서를 선언할 떄, FOR READ ONLY 절을 명시하여 unambiguous
커서가 되도록 하는 것이 좋습니다.
4
FOR FETCH ONLY 옵션도 동일한 의미로 사용됩니다.
사용 예는 다음과 같습니다.
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 60
TOPIC
05 15 FOR UPDATE
01
1
커서를 통한 Positioned Update 또는 Delete 를 원하는 경우
에는 For update of 다음에 갱신할 칼럼들을 콤마로 분리하여
나열합니다. 모든 컬럼들이 Update의 대상이 될 수 있다면, For
2
update 라고 지정합니다.
사용 예는 다음과 같습니다.
3
커서를 선언할 떄, FOR UPDATE 절을 명시하여 unambiguous 커서
가 되도록 하는 것이 좋습니다.
4
이 절이 사용되면 Select 시에 S(Shared) 대신에 U(Update) Lock을
적용하게 되므로 교착 상태를 방지하는데 도움이 됩니다. 커서를
fetch 후에 UPDATE 또는 DELETE 작업을 실행하는 UOW에서는 반드
시 사용하도록 합니다.
UPDATE 또는 DELETE 시 WHERE 조건절에서 해당 행을 다시 검색하
지 않고 이미 Fetch 된 행과 그 정보를 이용하므로, 검색에 필요한 비
용이 줄어들어 성능이 향상됩니다.
5
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 61
TOPIC
05 16 문자열 스칼라 함수
01
1
CHAR, VARCHAR 등의 문자열 유형에 적용되는 스칼라 함수입니다. 문자열 스칼라 함수는 다음과 같습니다.
함수
설명
함수
설명
ASCII
인수의 가장 왼쪽 문자의 ASCII 코드 값을 정수
로 리턴합니다.
LOCATE
다른 문자열 내에서 한 문자열의 시작 위치를 리턴
합니다.
CHR
인수에 의해 지정된 ASCII 코드 값을 갖고 있는
문자를 리턴합니다.
LTRIM
문자열 표현식의 시작에서 공백을 제거합니다.
POSSTR
다른 문자열 내에서 한 문자열의 시작 위치를 리턴
합니다.
CONCAT
두 문자열의 병합인 문자열을 리턴합니다.
DECRYPT_BIN,
DECRYPT_CHAR
암호 문자열을 사용하여 암호화된 데이터 해독
의 결과 값을 리턴합니다.
REPEAT
argument2의 배수만큼 반복되는 argument1로
구성된 문자열을 리턴합니다.
DECRYPT_BIN,
DECRYPT_CHAR
암호 문자열을 사용하여 암호화된 데이터 해독
의 결과 값을 리턴합니다.
REPLACE
argument1에서 argument2의 모든 어커런스를
argument3으로 대체합니다.
DIFFERENCE
SOUNDEX로 판별된대로, 두 개의 인수 문자열
에 있는 단어들의 음조 간 차이를 리턴합니다. 4
의 값은 문자열 음조가 같음을 의미합니다.
RIGHT
문자열에서 가장 오른쪽의 문자를 리턴합니다.
RTRIM
문자열 표현식의 끝에서 공백을 제거합니다.
SOUNDEX
인수에서 단어들의 음조를 나타내는 4문자 코드를
리턴합니다. 이 결과는 다른 문자열의 음조와 비교
될 수 있습니다.
SPACE
지정된 수의 공백으로 구성된 문자열을 리턴합니
다.
SUBSTR
문자열의 하위 문자열을 리턴합니다.
TRANSLATE
문자열의 하나 이상의 문자가 다른 문자로 변환된
문자열을 리턴합니다.
UCASE 또는
UPPER
모든 문자가 대문자로 변환된 문자열을 리턴합니
다.
ENCRYPT
데이터 문자열 표현식을 암호화한 결과 값을 리
턴합니다.
GENERATE_UNIQUE
동일한의 다른 모든 실행과 비교하여 고유한 비
트 데이터 문자열을 리턴합니다.
GETHINT
암호 힌트가 있는 경우를 리턴합니다.
INSERT
문자열을 리턴하며, 여기서, argument3바이트
는 argument1(argument2에서 시작)에서 삭
제되었으며 argument4는
argument1(argument2에서 시작)으로 삽입
되었습니다.
LCASE 또는 LOWER
모든 문자가 소문자로 변환된 문자열을 리턴합
니다.
LEFT
문자열에서 가장 왼쪽의 문자를 리턴합니다.
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 62
TOPIC
05 17 숫자 스칼라 함수
01
1
SMALLINT, INT, BIGINT, DECIMAL, FLOAT 등의 숫자 유형에 적용되는 스칼라 함수입니다. 숫자 스칼라 함수는 다음과 같습니다.
함수
설명
함수
설명
ABS
숫자의 절대값을 리턴합니다.
LOG10
숫자의 일반 대수(기본 10)를 리턴합니다.
ACOS
숫자의 arc cosine을 라디안으로 리턴합니다.
MOD
첫 번째 인수를 두 번째 인수로 나눈 나머지를 리턴합니다.
ASIN
숫자의 arc sine을 라디안으로 리턴합니다.
POWER
ATAN
숫자의 arc tangent를 라디안으로 리턴합니다.
첫 번째 인수를 두 번째 인수의 제곱으로 올린 결과를 리
턴합니다.
ATANH
숫자의 hyperbolic arc tangent를 라디안으로 리턴합니
다.
RADIANS
각도로 표시된 인수에 대해 라디안 수를 리턴합니다.
RAND
난수를 리턴합니다.
ATAN2
x와 y 좌표의 arc tangent를 라디안으로 표시되는 각도로
리턴합니다.
ROUND
10진수 위치의 지정된 숫자로 반올림되어진 숫자 값을 리
턴합니다.
CEIL
숫자보다 크거나 같은 최소의 정수 값을 리턴합니다.
SIGN
숫자의 부호를 리턴합니다.
COS
숫자의 cosine을 리턴합니다.
SIN
숫자의 sine을 리턴합니다.
COSH
숫자의 hyperbolic cosine을 리턴합니다.
SINH
숫자의 hyperbolic sine을 리턴합니다.
COT
인수(argument)의 cotangent를 리턴합니다. 여기서, 인
수는 라디안으로 표시되는 각도입니다.
SQRT
숫자의 제곱근을 리턴합니다.
TAN
숫자의 tangent를 리턴합니다.
TANH
숫자의 hyperbolic tangent를 리턴합니다.
TRUNCATE
10진수 위치의 지정된 숫자에서 절단된 숫자 값을 리턴합
니다.
DEGREES 각도의 숫자를 리턴합니다.
DIGITS
숫자의 절대값의 문자열 표현을 리턴합니다.
EXP
인수가 지정한 제곱으로 올릴 자연 대수의 밑 값을 리턴합
니다.
FLOOR
숫자보다 크거나 작은 최대의 정수 값을 리턴합니다.
LN
숫자의 자연 대수를 리턴합니다.
LOG
숫자의 자연 대수를 리턴합니다(LN과 동일).
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 63
TOPIC
05 18 날짜 스칼라 함수
01
1
DATE, TIME, TIMESTAMP 등의 날짜 유형의 데이터의 각종 연산과 관련된 스칼라 함수입니다. 날짜 스칼라 함수는 다음과 같습니다.
함수
설명
함수
설명
DAY
값의 일(day) 부분을 리턴합니다.
QUARTER
DAYNAME
db2start가 발행된 때의 로케일에 따라, 인수
의 요일 부분에 대한 요일 이름(예: Friday)이
포함된 대소문자 혼용 문자열을 리턴합니다.
날짜가 해당되는 분기를 표시하는 정수를 리턴
합니다.
SECOND
값의 초 부분을 리턴합니다.
DAYOFWEEK
값에서 요일을 리턴하며, 여기서 1은 일요일, 7
은 토요일입니다.
DAYOFWEEK_ISO
값에서 요일을 리턴하며, 여기서 1은 월요일, 7
은 일요일입니다.
DAYOFYEAR
값에서 일(day)을 리턴합니다.
DAYS
날짜의 정수 표현을 리턴합니다.
HOUR
값의 시간 부분을 리턴합니다.
JULIAN_DAY
B.C. 4712년 1월 1일에서 인수에 지정된 날짜
까지의 일 수를 나타내는 정수 값을 리턴합니
다.
MICROSECOND
값의 마이크로초 부분을 리턴합니다.
TIMESTAMP_FORMAT 형식 템플리트(argument2)를 사용하여 해석
된 문자열(argument1)에서 시간소인을 리턴
합니다.
TIMESTAMP_ISO
날짜, 시간 또는 시간소인 인수에 기초화 시간
소인 값을 리턴합니다. 인수가 날짜이면, 모든
시간 요소에 대해 0을 삽입합니다. 인수가 시간
이면, 날짜 요소에 대해 CURRENT DATE 값을
삽입하고 분할 시간 요소에 대해 0을 삽입합니
다.
TIMESTAMPDIFF
두 시간소인 사이의 차이에 근거하여
argument1 유형의 계산된 간격 수를 리턴합니
다. 두 번째 인수는 두 개의 시간소인 유형을 뺀
결과를 CHAR로 변환한 결과입니다.
TO_CHAR
시간소인의 CHARACTER 표현을 리턴합니다.
MIDNIGHT_SECONDS 자정과 지정된 시간 값 사이의 시간(초 단위)를 TO_DATE
나타내는 정수 값을 리턴합니다.
VARCHAR_FORMAT
값의 분 부분을 리턴합니다.
MINUTE
MONTH
값의 월 부분을 리턴합니다.
MONTHNAME
데이터베이스를 시작할 때의 로케일을 기초로
날짜 또는 시간소인이 되는 인수의 월 부분의
월 이름(예: January)을 포함하는 대소문자 혼
용 문자열을 리턴합니다.
문자열에서 시간소인을 리턴합니다.
템플리트(argument2)에 따라 형식화된 시간
소인(argument1)의 CHARACTER 표현을 리
턴합니다.
WEEK
값에서 주(일요일부터 시작)를 리턴합니다.
날짜
유형도
숫자
유형과 마찬가지로 + 또는 – 기호를 이용하여
2
값에서 주(월요일부터 시작)를 리턴합니다.
WEEK_ISO
연산할 수 있습니다. years, months, days 등의 키워드로 단위
YEAR 를 지정합니다. 값의 연도 부분을 리턴합니다
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 64
TOPIC
05 19 형변환 스칼라 함수
01
1
형변환 스칼라 함수는 특정한 데이터 유형의 값을 다른 데이터 유형의 값으로 변형시켜 주는 함수입니다. 모든 데이터 유형은 자신의 데이터 유형
명과 일치하는 형변환 스칼라 함수를 제공합니다. 형변환 스칼라 함수는 다음과 같습니다.
함수
함수
설명
BIGINT
정수 상수의 양식으로 숫자의 64 비트 정수
표현 또는 문자열을 리턴합니다.
BLOB
모든 유형의 문자열의 BLOB 표현을 리턴합
니다.
CHAR
값의 CHARACTER 표현을 리턴합니다.
CLOB
값의 CLOB 표현을 리턴합니다.
DATE
값에서 DATE를 리턴합니다.
DBCLOB
문자열의 DBCLOB 표현을 리턴합니다.
DECIMAL
숫자의 DECIMAL 표현을 리턴합니다.
DOUBLE
숫자의 DOUBLE PRECISION 표현을 리턴합
니다.
FLOAT
숫자의 FLOAT 표현을 리턴합니다.
GRAPHIC
문자열의 GRAPHIC 표현을 리턴합니다.
INTEGER
숫자의 INTEGER 표현을 리턴합니다.
LONG_VARCHAR
값의 LONG VARCHAR 표현을 리턴합니다.
설명
TIME
값에서 TIME을 리턴합니다.
TIMESTAMP
하나의 값 또는 값 쌍으로부터 TIMESTAMP를 리턴합
니다.
VARCHAR
값의 VARCHAR 표현을 리턴합니다.
VARGRAPHIC
값의 VARGRAPHIC 표현을 리턴합니다.
2
데이터 유형이 다른 두 값은 직접 비교될 수 없으므로, 반드시 형
변환 함수를 이용합니다.
LONG_VARGRAPHIC 값의 LONG VARGRAPHIC 표현을 리턴합니
다.
REAL
숫자의 REAL 표현을 리턴합니다.
SMALLINT
숫자의 SMALLINT 표현을 리턴합니다.
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 65
TOPIC
05 20 컬럼 함수
01
1
컬럼 함수는 한 건 이상의 행집합의 컬럼에 대해 함수를 적용하여 지정한 그룹별로 결과값을 반환하는 함수로 주로 집계 작업을 위해 사용됩니다.
컬럼 함수는 다음과 같습니다.
함수
AVG
설명
함수
설명
REGRESSION
REGR_R2는 회귀에 대한 결정 계수를 리턴합니다.
CORRELATION 수 쌍 세트의 상관 계수를 리턴합니다.
REGRESSION
REGR_SLOPE는 행의 기울기를 리턴합니다.
COUNT
행이나 값 세트에 행의 수나 값의 수를 리턴합니다.
REGRESSION
COUNT_BIG
행이나 값 세트에 행의 수나 값의 수를 리턴합니다.
결과는 INTEGER의 최대값보다 클 수 있습니다.
REGR_SXX는 진단 통계를 계산하는 데 사용되는 양
을 리턴합니다.
REGRESSION
REGR_SXY는 진단 통계를 계산하는 데 사용되는 양
을 리턴합니다.
REGRESSION
그룹화 세트가 생성한 소계 행을 가리키는 데 그룹화
세트와 슈퍼 그룹이 사용됩니다. 리턴된 값은 0 또는
1입니다. 1 값은 리턴된 행에서 인수의 값이 널(NULL) STDDEV
값이고 행이 그룹화 세트에 대해 생성되었음을 의미 SUM
합니다. 이 생성된 행은 그룹화 세트에 대해 소계를
VARIANCE
제공합니다.
REGR_SYY는 진단 통계를 계산하는 데 사용되는 양
을 리턴합니다.
숫자 세트의 평균을 리턴합니다.
COVARIANCE 수 쌍의 세트의 편차를 리턴합니다.
GROUPING
MAX
값 세트에서 최대값을 리턴합니다.
MIN
값 세트에서 최소값을 리턴합니다.
REGRESSION
REGR_AVGX는 진단 통계를 계산하는 데 사용되는
양을 리턴합니다.
REGRESSION
REGR_AVGY는 진단 통계를 계산하는 데 사용되는
양을 리턴합니다.
REGRESSION
REGR_COUNT는 회귀 행을 맞추는 데 사용된 널
(NULL)이 아닌 숫자 쌍의 수를 리턴합니다.
REGRESSION
REGR_INTERCEPT 또는 REGR_ICPT는 회귀 행의 y
절편을 리턴합니다.
숫자 세트의 표준 편차를 리턴합니다.
숫자 세트의 합을 리턴합니다.
숫자 세트의 분산을 리턴합니다.
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 66
TOPIC
05 21 스냅샷 테이블 함수
01
1
GET SNAPSHOT 명령어의 실행 결과와 동일한 스냅샷 정보를 테이블의 형태로 저장하는 테이블 함수입니다. SELECT 문의 FROM 절에서 표현되
고, 일반 테이블과 동일한 방법으로 조회할 수 있습니다. 대표적인 스냅샷 테이블 함수의 종류는 다음과 같습니다.
함수
함수
설명
SNAPSHOT_AGENT
응용프로그램 스냅샷에서 응용프로그램의
핸들 번호와 대응되는 db2agent 프로세
스의 pid를 반환합니다.
SNAPSHOT_APPL
응용프로그램 스냅샷에서 응용프로그램에
대한 일반적인 정보를 반환합니다.
SNAPSHOT_APPL_INFO
응용프로그램 스냅샷에서 응용프로그램의
핸들 번호와 이름, 응용프로그램 프로세스
의 pid 등을 반환합니다.
SNAPSHOT_TBS
설명
테이블 스페이스 스냅샷에서 활동 정보를 반
환합니다.
SNAPSHOT_TBS_CFG
2
테이블 스페이스 스냅샷에서 구성 정보를 반
환합니다
get dbm cfg 명령어로 시스템 모니터 스위치의 기본값을 확인
합니다.
$ db2 attach to <인스턴스명>
$ db2 updte dbm cfg using DFT_MON_LOCK on
버퍼풀 스냅샷에서 버퍼풀의 활동 정보를
반환합니다.
$ db2 updte dbm cfg using DFT_MON_SORT off
SNAPSHOT_CONTAINER
테이블 스냅샷에서 컨테이너 구성 정보를
반환합니다.
$ db2 detach
SNAPSHOT_DATABASE
데이터베이스 스냅샷에서 정보를 반환합
니다.
SNAPSHOT_DBM
인스턴스 스냄샷에서 정보를 반환합니다.
SNAPSHOT_DYN_SQL
동적 SQL 스냅샷에서 정보를 반환합니다
SNAPSHOT_FCM
FCM에 관한 정보를 반환합니다.
SNAPSHOT_LOCK
잠금 스냅샷에서 정보를 반환합니다.
SNAPSHOT_LOCKWAIT
응용프로그램 스냅샷에서 잠금 대기 정보
를 반환합니다.
SNAPSHOT_STATEMENT
응용프로그램 스냅샷에서 명령문 정보를
반환합니다.
SNAPSHOT_TABLE
테이블 스냅샷에서 활동 정보를 반환합니
다.
SNAPSHOT_BP
$ db2 get dbm cfg show detail | grep DFT_MON
3
SELECT문의 FROM 절에서 TABLE 이라는 키워드를 사용하여 스
냅샷 함수를 실행합니다. 인수로 <데이터베이스명>과 <데이터
베이스 파티션 번호>를 입력합니다. 파티션 번호가 -1 이면 현재
파티션을 의미하고, -2 이면 모든 파티션을 의미합니다. <결과
테이블에 대한 별명>은 임의로 지정합니다.
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 67
TOPIC
05 22 ROW_NUMBER 함수
01
1
결과 집합에 대해 일련 번호를 부여할 때 사용합니다. 조건에 맞는 데이터 중에서 일부 구간의 데이터만 추출할 때도 사용할 수 있습니다.
2
다음과 같이 사용합니다. 단순히 조건에 맞는 최초의 N건을 조회하려면, fecth first N rows only 를 사용합니다.
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 68
TOPIC
05 23 RANK 함수
01
1
결과 집합에 대해 순위를 부여할 때 사용합니다. 동일 순위 발생시에 발생 건수만큼 순위를 SKIP 하기를 원하지 않는다면, DENSE_RANK 함
수를 이용합니다.
2
다음과 같이 사용합니다.
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 69
TOPIC
05 24 GROUP BY 확장 옵션
01
1
GROUP BY절에서 여러가지 확장 옵션을 사용하여 다양한 집계
정보를 추출할 수 있습니다. GROUPING SETS, ROLLUP, CUBE
3
GROUPING SETS 은 여러 개의 GROUP BY 절의 실행 결과를 UNION
ALL 한 것과 동일한 의미입니다.
4
단일 컬럼에 의한 GROUP BY 의 예는 다음과 같습니다.
등의 옵션이 지원됩니다.
2
구문은 다음과 같습니다.
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 70
TOPIC
05 24 GROUP BY 확장 옵션
01
5
두 개의 GROUPING SETS 을 실행한 예는 다음과 같습니다.
6
ROLLUP 옵션은 다음과 같은 GROUPING SET과 동일합니다.
7
ROLLUP 을 실행한 예는 다음과 같습니다.
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 71
TOPIC
05 24 GROUP BY 확장 옵션
01
8
CUBE 옵션은 다음과 같은 GROUPING SET과 동일합니다.
9
CUBE 을 실행한 예는 다음과 같습니다.
10
실행 결과는 다음과 같습니다.
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 72
TOPIC
05 25 Recursive SQL
01
1
BOM 등의 Tree 구조를 가진 테이블을 access 할 때 사용합니
4
모든 부모 노드와 자손 노드를 보여주는 예제입니다.
다.
2
예제 테이블의 구조는 다음과 같습니다.
3
다음과 같이 트리 구조로 데이터가 입력되었습니다.
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 73
TOPIC
05 25 Recursive SQL
01
5
값이 ‘AAA’ 인 노드의 자손 노드를 보여주는 예제입니다.
6
각 노드의 값과 그 레벨값을 보여주는 예제입니다.
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 74
TOPIC
05 26 Correlated 서브 쿼리
01
1
Inner SELECT문의 조건절에 Outer SELECT문에서 언급된 테이블의 컬럼이 사용된 서브 쿼리를 Correlated 서브 쿼리라고 합니다.
2
자신이 속한 부서의 평균 급여보다 많은 급여를 받는 직원의 사번, 이름, 급여를 확인하는 Correlated 서브 쿼리의
예는 다음과 같습니다.
Correlated 서브 쿼리에서는 Outer SELECT 문에 대해서 Inner SELECT문이 반복적으로 실행됩니다.
U D B 개 발 자 기 본 교 육 • UNIT 05 • D M L 75
TOPIC
06
01
UNIT06
DCL
UDB개발자기본교육
사용자 인증
권한의 종류
권한별 기능
인스턴스 권한 제어 방법
데이터베이스 권한 제어 방법
특권의 종류
특권 제어 방법
U D B 개 발 자 기 본 교 육 • UNIT 06 • D C L 76
TOPIC
06 01 사용자 인증
01
1
사용자 정보는 별도로 관리하지 않고, OS의 사용자 관리 기능을
이용합니다. CONNECT문에서 제공된 사용자 ID와 암호를 OS
2
에게 전달하여 유효한 사용자인지를 점검하게 합니다. 기본 인
증 방식은 SERVER 이며, 서버의 OS가 사용자 인증을 담당합니
$ db2 connect to <데이터베이스명> user <사용자명> using <암
호명>
다.
3
CONNECT TO
sample USER bob
using pwd
모든 응용프로그램은 데이터베이스에 접속할 때, connect 문을 이
용하여 사용자 ID와 암호명을 명시하게 됩니다. 명시한 사용자 ID와
암호명이 유효하지 않으면, 데이터베이스에 대한 접속은 허용되지 않
습니다.
connect 문에서 사용자 ID와 암호를 명시하지 않으면, 현재 세션의
로그인 사용자와 암호명이 사용됩니다. 원격 데이터베이스에 접속할
때는 반드시 사용자 ID와 암호를 명시적으로 제공해야 합니다.
$ db2 connect to <데이터베이스명>
SELECT * FROM
mytable
MYTABLE
Authentication
Is this
right
password
for Bob?
Authorization
Does Bob
have
authorities or
privileges to
SELECT from
MYTABLE?
4
connect 문에서 제공된 사용자 ID와 암호를 이용하여 OS의 사용자
관리 기능을 요청합니다. 사용자 인증의 방식은 인스턴스 구성 변수
인 AUTHENTICATION에 의해 결정되며, 대표적인 인증 방식은 다음
과 같습니다.
인증방식
설명
SERVER
서버 머신의 OS가 사용자 인증을 담당합니다.
사용자 ID와 암호명이 서버 머신으로 전송됩니
다.
SERVER_ENCRYPT
서버 머신의 OS가 사용자 인증을 담당합니다.
사용자 ID와 암호명이 암호화되어 서버 머신으
로 전송됩니다.
CLIENT
클라이언트 머신의 OS가 사용자 인증을 담당
합니다. 사용자 ID 만 서버 머신으로 전송됩니
다.
U D B 개 발 자 기 본 교 육 • UNIT 06 • D C L 77
TOPIC
06 02 권한의 종류
01
1
일련의 DB2 명령어를 실행하거나 데이터베이스를 액세스할 수
있는 능력을 권한이라고 합니다. 권한에는 SYSADM, SYSCTRL,
3
SYSMAINT, SYSMON, DBADM, LOAD 등이 있으며, OS의 그룹
권한
또는 사용자에게 사용 권한을 부여합니다.
2
인스턴스 권한은 4가지로 구분됩니다. 인스턴스 구성 변수를 이용하
여 OS에 정의된 특정한 그룹 단위로 제어합니다.
인스턴스 권한과 데이터베이스 권한의 체계는 다음과 같이 분류
됩니다. 상위 권한의 소유자는 하위 권한을 자동적으로 소유합
니다. 인스턴스 사용자를 정의할 때는 고유한 일차 그룹을 지정
하고, SYSADM 권한은 인스턴스 사용자만 가지도록 하는 것이
보안에 도움이 됩니다.
SYSADM
최고의 인스턴스 권한 그룹으로 인스턴스와 데이터베
이스에 대한 모든 우지 보수, 생성, 제거와 연관된 작업
을 실행할 수 있습니다. 인스턴스에 존재하는 모든 데
이터베이스의 데이터를 직접 액세스할 수 있습니다.
SYSCTRL
인스턴스와 데이터베이스의 유지 보수, 생성, 제거 등
과 연관된 명령어를 실행할 수 있으며, 데이터에 대한
직접적인 액세스는 허용되지 않습니다.
SYSMAINT
인스턴스와 데이터베이스의 유지 보수와 연관된 명령
어를 실행할 수 있으며, 데이터에 대한 직접적인 액세
스는 허용되지 않습니다.
SYSMON
인스턴스 또는 데이터베이스의 시스템 모니터 스냅샷
과 연관된 명령어를 실행할 수 있습니다. 데이터에 대
한 직접적인 액세스는 허용되지 않습니다.
SYSADM
인스턴스 권한
설명
데이터베이스 권한
SYSCTRL
SYSMAINT
권한
DBADM
Authority
LOAD
SYSMON
4
데이터베이스 권한은 2가지로 구분됩니다. grant 문과 revoke문을
이용하여 사용자 또는 그룹 단위로 제어할 수 있습니다.
권한
설명
DBADM
특정 데이터베이스의 오브젝트에 대한 모든 관리 작업
을 할 수 있으며, 해당 데이터베이스의 데이터를 직접
액세스할 수 있습니다.
LOAD
특정 데이터베이스에 대한 LOAD 작업을 실행할 수 있
습니다. 데이터에 대한 직접적인 액세스는 허용되지 않
습니다.
U D B 개 발 자 기 본 교 육 • UNIT 06 • D C L 78
TOPIC
06 03 권한별 기능
01
1
SYSADM 권한은 모든 명령어와 SQL문을 실행할 수 있습니다.
SYSCTRL 권한은 SYSADM 이 지원하는 일부 명령어와 SQL문을
4
권한별로 실행 가능한 명령어는 다음과 같습니다.
실행할 수 없습니다. SYSMAINT 권한은 SYSMAINT 이 지원하는
일부 명령어와 SQL문을 실행할 수 없습니다. DBADM 권한은
특정 데이터베이스의 오브젝트에 대한 명령어와 SQL문을 실행
할 수 있습니다. 예를 들어, SYSCTRL 권한은 인스턴스 구성 변수
를 변경할 수 없습니다. 또, SYSMAINT 권한은 접속된 응용프로
그램을 강제로 종료시키거나, 백업 이미지를 이용하여 새로운
2
데이터베이스로 복구할 수 없습니다. DBADM 권한은 백업을 실
SYSMON
권한을 사용하여 사용자는 다음과 같은 명령어를 사
행할
수 없습니다.
용할 수 있습니다. SYSADM,SYSCTRL,SYSMAINT 권한을 가진 사
용자는 SYSMON 권한을 자동적으로 소유합니다.





3
GET DATABASE MANAGER
GET MONITOR SWITCHES
GET SNAPSHOT
LIST ACTIVE DATABASES
LIST APPLICATIONS
MONITOR SWITCHES
 LIST DCS APPLICATIONS
 RESET MONITOR
 UPDATE MONITOR SWITCHES
LOAD 권한을 사용하여 사용자는 다음과 같은 명령어를 사용할
수 있습니다. SYSADM,DBADM 권한을 가진 사용자는 LOAD 권
한을 자동적으로 소유합니다.
 LOAD
 LIST TABLESPACES
 RUNSTATS
 QUIESCE TABLESPACES FOR TABLE
U D B 개 발 자 기 본 교 육 • UNIT 06 • D C L 79
TOPIC
06 04 인스턴스 권한 제어 방법
01
1
인스턴스 권한은 OS의 그룹에게 부여하므로, 해당 그룹에 속하
5
는 사용자는 모두 동일한 인스턴스 권한을 가지게 됩니다. 인스
$ db2stop force
턴스 구성 변수인 SYSADM_GROUP, SYSCTRL_GROUP,
$ db2start
SYSMAINT_GROUP, SYSMON_GROUP으로 제어합니다.
2
SYSADM 권한을 가진 사용자로 로그인합니다.
각 구성 변수의 변경은 인스턴스를 재시작해야 반영됩니다.
6
get dbm cfg 명령어를 이용하여 인스턴스 권한과 관련된 구성 변수
의 값을 확인합니다.
$ login <인스턴스 사용자>
$ db2 get dbm cfg | grep "_GROUP"
3
update dbm cfg 명령어를 이용하여 인스턴스 구성 변수인
SYSADM_GROUP 등의 값을 OS에 정의된 <그룹명>으로 지정
합니다. 인스턴스 구성 변수인 SYSADM_GROUP 의 기본값은
인스턴스 사용자의 일차 그룹명이므로, 인스턴스 사용자의 일차
그룹에 속하는 사용자들은 SYSADM 권한을 가지게 됩니다.
SYSADM 그룹 이름
(SYSADM_GROUP) = ADMGRP
SYSCTRL 그룹 이름
(SYSCTRL_GROUP) = CTRLGRP
SYSMAINT 그룹 이름
(SYSMAINT_GROUP) = MAINTGRP
SYSMON 그룹 이름
(SYSMON_GROUP) = MOMGRP
$ db2 update dbm cfg using SYSCTRL_GROUP <그룹명>
4
update dbm cfg 명령어를 이용하여 SYSADM_GROUP 등의
값을 NULL로 지정하면 기본값으로 복귀하므로, 해당 그룹은 더
이상 인스턴스 권한을 가질 수 없습니다. NULL 은 인스턴스 구
성 변수와 데이터베이스 구성 변수의 값을 지정되지 않은 상태
로 설정하는 특수한 키워드로 반드시 대문자로 표현합니다.
$ db2 update dbm cfg using SYSCTRL_GROUP NULL
U D B 개 발 자 기 본 교 육 • UNIT 06 • D C L 80
TOPIC
06 05 데이터베이스 권한 제어 방법
01
1
데이터베이스 권한은 OS에 정의된 그룹명 또는 사용자 계정에
5
게 부여됩니다. 그룹에게 권한이 부여되면, 해당 그룹에 속하는
사용자 계정은 모두 동일한 데이터베이스 권한을 가지게 됩니다.
2
SYSADM 권한을 가진 사용자로 데이터베이스에 접속합니다.
$ db2 REVOKE LOAD ON DATABASE FROM USER <사용자명>
$ db2 REVOKE DBADM ON DATABASE FROM GROUP <그룹명>
$ login <인스턴스 사용자>
$ db2 REVOKE LOAD ON DATABASE FROM GROUP <그룹명>
$ db2 connect to <데이터베이스명>
3
grant문으로 DBADM과 LOAD 권한을 사용자에게 부여합니다.
DBADM 권한을 부여하면 데이터베이스에 대한 특권인
BINDADD, CONNECT, CREATETAB, CREATE_NOT_FENCED,
IMPLICIT_SCHEMA 등이 자동적으로 부여됩니다. LOAD 권한
을 부여 받은 사용자는 실제로 LOAD 유틸리티를 실행할 때, 해
당 테이블에 대한 INSERT 권한도 있어야 합니다.
revoke 문으로 DBADM과 LOAD 권한을 제거할 수 있습니다.
DBADM 권한을 제거해도 간접적으로 부여받은 데이터베이스에 대
한 특권은 자동적으로 제거되지 않으므로, 필요시 revoke문으로 명
시적으로 제거합니다.
$ db2 REVOKE DBADM ON DATABASE FROM USER <사용자명>
6
DBADM과 LOAD 권한은 SYSCAT.DBAUTH 뷰를 통해 확인합니다.
$ db2 "select grantee, DBADM, LOAD from syscat.dbauth"
$ db2 GRANT DBADM ON DATABASE TO USER <사용자명>
$ db2 GRANT LOAD ON DATABASE TO USER <사용자명>
4
grant문으로 DBADM과 LOAD 권한을 그룹에 부여하면, 그룹
에 속한 사용자는 간접적으로 권한을 부여 받습니다.
$ db2 GRANT DBADM ON DATABASE TO GROUP <그룹
명>
$ db2 GRANT LOAD ON DATABASE TO GROUP <그룹명>
U D B 개 발 자 기 본 교 육 • UNIT 06 • D C L 81
TOPIC
06 06 특권의 종류
01
1
데이터베이스, 테이블스페이스, 스키마, 테이블, 뷰, 인덱스, 팩
키지, SP, UDF 등의 데이터베이스 오브젝트에 대한 구체적인
SQL문을 실행할 수 있는 능력을 특권이라고 합니다. grant문과
revoke 문을 이용하여 그룹 또는 사용자별로 특권을 제어합니
다.
2
데이터베이스 오브젝트별 특권의 체계는 다음과 같이 분류됩니
다. 오브젝트를 생성한 사용자를 '오브젝트의 소유자' 라고 합니
다. 소유자는 DROP문으로 해당 오브젝트를 제거하거나,
GRANT문과 REVOKE 문으로 해당 특권을 제어할 수 있는 할 수
있는 CONTROL 특권을 부여받습니다.
3
오브젝트별로 부여할 수 있는 구체적인 특권명은 다음과 같으며,
grant 문과 revoke문을 이용하여 사용자 또는 그룹 단위로 제어할
수 있습니다. 그룹에 부여된 특권은 정적 SQL 문을 실행할 때는 적용
되지 않습니다. 응용프로그램에 포함된 정적 SQL문을 실행하는 사용
자는 해당 SQL문에 대한 명시적인 특권을 가지고 있어야 합니다.
오브젝트
설명
데이터베이
스
CONNECT, CREATETAB, IMPLICIT_SCHEMA,
BINDADD, CREATE_NOT_FENCED,
QUIESCE_CONNECT,
CREATE_EXTERNAL_ROUTINE 특권이 있습니다.
테이블스페
이스
USE 특권이 있습니다.
스키마
CREATEIN, ALTERIN, DROPIN 특권이 있습니다.
테이블
ALTER, INDEX, SELECT, INSERT, UPDATE, DELETE,
REFERENCES 특권이 있습니다.
뷰
SELECT, INSERT, UPDATE, DELETE 특권이 있습니다.
인덱스
CONTROL 등이 있습니다.
팩키지
BIND, EXECUTE 특권이 있습니다.
SP
UDF
EXECUTE 특권이 있습니다.
시퀀스
USAGE, ALTER 특권이 있습니다.
U D B 개 발 자 기 본 교 육 • UNIT 06 • D C L 82
TOPIC
06 07 특권 제어 방법
01
1
특권은 GRSANT 문과 REVOKE 문을 이용하여 사용자 또는 그룹
3
별로 제어합니다. 특정 그룹에 특권을 부여하면, 해당 그룹에 속
$ db2 grant select on table kes.t1 to group group1
하는 사용자 계정은 동일한 특권을 간접적으로 부여받게 됩니다.
$ db2 grant select on table kes.t1 to user user1
PUBLIC은 모든 사용자를 의미하는 특별한 키워드입니다.
2
특권은 grant 문과 revoke 문으로 제어합니다. DBADM과
LOAD는 특권이 아닌 권한이지만, grant문과 revoke 문으로
제어합니다. GROUP과 USER 키워드는 생략할 수 있지만, 동일
한 그룹 ID와 사용자 계정이 존재하는 경우에는 SQLSTATE
56092 가 반환되므로, 명시하는 것이 좋습니다.
grant 문으로 OS에 정의된 그룹 또는 사용자에게 특권을 부여합니다.
$ db2 "select * from syscat.tabauth"
4
한 가지 이상의 특권을 한 개의 grant 문으로 부여할 수 있습니다.
$ db2 grant select, update on table kes.t1 to user user1
5
모든 사용자에게 권한을 부여하려면 PUBLIC이라는 키워드를 이용합
니다.
$ db2 grant select on table kes.t1 to public
6
WITH GRANT OPTION을 사용하면, 권한을 부여받은 사용자는 다른
사용자에게 부여받은 권한을 전달할 수 있습니다.
$ db2 grant select on table kes.t1 to user1 with grant option
7
revoke 문으로 OS 그룹 또는 사용자에게 특권을 제거합니다.
$ db2 revoke select on table kes.t1 from user user1
U D B 개 발 자 기 본 교 육 • UNIT 06 • D C L 83
TOPIC
07
01
UNIT07
LOCK
UDB개발자기본교육
동시성과 무결성
분리 수준
분리 수준 지정 방법
잠금의 대상
테이블 잠금 유형
테이블 잠금 지정 방법
행 잠금 유형
잠금 변환 현상
잠금 상승 현상
잠금 대기 현상
교착 상태
U D B 개 발 자 기 본 교 육 • UNIT 07 • L O C K 84
TOPIC
07 01 동시성과 무결성
01
1
동시성이란 다수의 사용자가 동시에 데이터베이스 오브젝트를 액세스할 수 있도록 허용하는 매커니즘입니다. 데이터베이스 엔진은 동시성을 지
원하면서 데이터의 무결성을 보장할 수 있어야 합니다. A와 B라는 사용자가 동일한 데이터를 액세스한다면, 데이터베이스의 무결성을 위반하는
여러가지 바람직하지 않은 현상이 발생될 수 있습니다.
현상
Lost update
2
Non Repeatable Read
4
설명
Uncommitted Read
3
Phantom Read
5
갱신 유실
Lost Update
A와 B가 동일한 데이터를 동시에 조
회하고 변경하면, A가 변경한 값은 유
실되고, B가 변경한 값이 남게 됩니다.
미확약 읽기
Uncommitted Read
A가 추가 또는 갱신한 후에 COMMIT
하지 않은 데이터를 B가 조회할 수 있
도록 허용할 때, A가 COMMIT으로
트랜잭션을 종료한다면, B가 조회한
데이터는 정확한 데이터가 되지만, A
가 ROLLBACK으로 트랜잭션을 종료
한다면, B가 이미 조회한 데이터는 잘
못된 데이터가 됩니다.
반복 읽기 불가능
Non Repeatable
Read
A가 SELECT문을 실행하여 결과 집합
을 조회하고, 동일한 트랜잭션에서 동
일한 조건의 SELECT 문을 다시 요청
하면 이전의 결과 집합이 그대로 반환
되지 않습니다.
팬텀 읽기
Phantom Read
A가 SELECT문을 실행하여 10 건의
결과 집합을 조회하고, 동일한 트랜잭
션에서 동일한 조건의 SELECT 문을
다시 요청하면 이전의 결과 집합인
10건은 그대로 반환되고, B가 추가한
1 건의 행이 추가적으로 반환됩니다.
B가 새로 추가한 행을 팬텀 행이라고
합니다.
U D B 개 발 자 기 본 교 육 • UNIT 07 • L O C K 85
TOPIC
07 02 분리 수준
01
1
한 응용프로그램이 SELECT문을 실행하여 결과 집합이 반환되면,
다른 응용프로그램은 해당 결과 집합에 영향을 주는 액세스를
제한받게 됩니다. 액세스가 제한되는 대상의 범위와 SQL문의 종
2
류는 분리 수준에 의해 조절됩니다.
분리 수준은 SELECT문에 대해서만 적용됩니다. 데이터를 변경
시키는INSERT,UPDATE,DELETE 문에 의해 잠금이 적용된 행은
4
revoke 문으로 DBADM과 LOAD 권한을 제거할 수 있습니다.
DBADM 권한을 제거해도 간접적으로 부여받은 데이터베이스에 대
한 특권은 자동적으로 제거되지 않으므로, 필요시 revoke문으로 명
시적으로 제거합니다.
유형
설명
RR
Repeatable Read 의 약자입니다. 한 UOW 에서 동일한 조
건의 SELECT문을 여러 번 실행하면, 이전의 결과 집합과 항
상 동일한 결과 집합이 반환되는 것을 보장하므로 반복 읽기
가 가능합니다. 반환된 결과 집합의 모든 행과 결과 집합을
추출하기 위해 액세스된 모든 행에 대해 S 잠금을 적용합니
다. 다른 응용프로그램은 결과 집합의 데이터를 추가, 변경,
삭제할 수 없습니다.
RS
Read Stability의 약자입니다. 한 UOW 에서 동일한 조건의
SELECT문을 여러 번 실행하면, 이전의 결과 집합을 항상 포
함하고, 팬텀 행이 추가적으로 반환되는 것을 허용합니다. 반
환된 결과 집합의 모든 행에 NS 잠금을 적용합니다. 다른 응
용프로그램은 결과 집합의 데이터를 추가는 할 수 있지만, 변
경과 삭제는 할 수 없습니다.
CS
Cursor Stability의 약자입니다. 한 UOW 에서 동일한 조건의
SELECT문을 여러 번 실행하면 이전의 결과 집합이 반환되는
것을 보장하지 않습니다. 현재 처리 중인 한 개의 행에 대해
서만 NS 잠금을 설정합니다. 다른 응용프로그램은 결과 집합
의 데이터를 추가, 변경, 삭제할 수 있습니다.
UR
Uncommitted Read의 약자입니다. 한 UOW 에서 동일한
조건의 SELECT문을 여러 번 실행하면 이전의 결과 집합이 반
환되는 것을 보장하지 않습니다. 잠금을 전혀 적용하지 않습
니다. 다른 응용프로그램은 결과 집합의 데이터를 추가, 변경,
삭제할 수 있습니다. 다른 응용프로그램에서 처리 중인
UOW의 COMMIT 되지 않은 데이터를 조회할 수 있고,
COMMIT 하지 않은 데이터가 액세스되는 것을 허용합니다.
COMMIT 또는 ROLLBACK이 될 때까지 액세스가 제한됩니다.
3
분리 수준은 다음과 같이 4 가지로 구분됩니다.
U D B 개 발 자 기 본 교 육 • UNIT 07 • L O C K 86
TOPIC
07 03 분리 수준 지정 방법
01
1
분리 수준은 개별 SQL문, 세션, 팩키지, DB2 CLI 에서 지정할 수
있습니다. 개별 SQL문에서 WITH 옵션으로 분리 수준을 지정하
는 것이 가장 우선적으로 적용됩니다.
4
분리 수준의 유형을 지정하는 방법은 다음과 같습니다. 팩키지에 저
장된 SELECT문의 분리 수준이 팩키지 수준의 분리 수준과 다른 경우
에는 해당 SELECT문에만 적용됩니다.
대상
2
<분리 수준>을 지정할 때는 RR, RS, CS, UR 이라는 키워드를 이
용합니다. 대소문자는 구별하지 않습니다. WITH UR 을 지정하면,
X 잠금이 설정된 데이터도 액세스할 수 있습니다
3
다양한 환경에서 분리 수준을 설정하는 예는 다음과 같습니다.
설명
SQL문
SQL문의 마지막에 WITH 옵션을 사용하여 지정합니다.
팩키지 수준과 세션 수준의 설정값보다 우선적으로 적
용됩니다. SELECT 문, SELECT INTO 문, INSERT 문,
FOR 문, searched DELETE 문, searched UPDATE 문,
DECLARE CURSOR 문 등은 WITH 옵션을 사용할 수
있습니다.
현재 세
션
SET CURRENT ISOLATION 문을 이용하여 지정합니다.
팩키지에 저장된 동적 SQL문에 대해서 팩키지 수준의
설정값보다 우선적으로 적용됩니다.
팩키지
PREP 명령어의 ISOLATION 옵션, BIND 명령어의
ISOLATION 옵션으로 지정하며, 팩키지에 포함된 모든
SELECT문에 적용됩니다.
CLI
CLI 와 ODBC 드라이버를 통한 실행시에 적용되며,
db2cli.ini 파일의 TXNISOLATION 키워드를 이용하여
지정하거나, SQLSetConnectAttr 함수를 이용합니다.
TXNISOLATION 키워드의 값은 1(UR), 2(CS), 4(RS),
8(RR) 중에서 한 가지로 지정합니다.
CLP
CHANGE ISOLATION LEVEL 명령어를 이용하며, 데이
터베이스의 재접속시에 반영됩니다.
U D B 개 발 자 기 본 교 육 • UNIT 07 • L O C K 87
TOPIC
07 04 잠금의 대상
01
1
QUIESCE 명령어, CONNECT 명령어, LOCK TABLE문으로 인스
4
잠금을 적용하는 방법은 다음과 같습니다.
턴스, 데이터베이스, 테이블스페이스, 테이블에 사용자가 명시
적으로 잠금을 적용할 수 있습니다. SQL문을 실행하면 엔진에
의해 테이블과 인덱스의 행에 자동적으로 잠금이 적용됩니다.
2
3
대상
인스턴스
QUIESCE INSTANCE 상태라면 SYSADM /
SYSCTRL / SYSMAINT 권한을 가진 사용자와 액세
스가 허용된 사용자만 인스턴스와 데이터베이스를
액세스할 수 있습니다.
데이터베이
스
CONNECT 문을 이용하여 데이터베이스에 접속할
때 배타적 모드의 접속이 가능합니다. 기본 접속
모드는 공유적 모드이므로 여러 사용자가 동시에
접속할 수 있습니다. QUIESCE DATABASE 명령어
를 실행하면, SYSADM / SYSCTRL / SYSMAINT /
DBADM 권한을 가진 사용자와 액세스가 허용된
사용자만 데이터베이스를 액세스할 수 있습니다.
테이블스페
이스
QUIESCE TABLESPACES FOR TABLE 명령어를 실
행하면, LOAD 명령어를 실행하는 동안 해당 테이
블스페이스에 잠금을 적용합니다.
테이블
LOCK TABLE 문을 이용하여 배타적 또는 공유적
모드로 테이블 전체에 잠금을 설정할 수 있습니다.
한 테이블의 행 잠금의 비율이 지정한 기준을 초과
하면, 내부적으로 행잠금이 테이블 잠금으로 변환
될 수도 있습니다.
행
SQL문을 이용하여 데이터를 액세스하면 기본적으
로 행 수준의 잠금이 적용됩니다.
인덱스
SQL문을 이용하여 데이터를 액세스할 때, 특정한
인덱스를 이용하여 액세스하게 되면, 해당 인덱스
의 행에 잠금이 적용됩니다.
데이터베이스 내에서 잠금이 적용되는 오브젝트는 테이블스페
이스, 테이블, 행, 인덱스가 있습니다.
인스턴스, 데이터베이스, 테이블스페이스에 대한 잠금은 데이터
베이스 관리 차원의 잠금입니다. 일반적인 응용프로그램에서
SQL문으로 데이터를 액세스하므로 테이블, 행, 인덱스에 대한
잠금이 적용됩니다.
설명
U D B 개 발 자 기 본 교 육 • UNIT 07 • L O C K 88
TOPIC
07 05 테이블 잠금 유형
01
1
테이블 잠금의 유형에는 IN, IS, IX, SIX, S, U, X, Z 등이 있습니다.
테이블에 잠금이 적용되면, 행에 대한 잠금 정보는 별도로 관리
되지 않습니다. 테이블의 모든 행에 대해서 액세스가 유형별로
2
제한됩니다.
테이블 잠금 유형과 잠금 유형간의 호환표은 다음과 같습니다.
분리 수준 UR을 사용하면 Z 잠금을 제외한 모든 잠금을 무시하
고 액세스할 수 있습니다.
3
테이블 잠금 유형의 특성은 다음과 같습니다.
모
드
설명
IN
잠금 소유자는 언커미트된 데이터를 포함하여 오브젝트의
어떤 데이터든지 읽을 수 있지만, 갱신할 수는 없습니다. 다
른 동시 응용프로그램은 테이블을 읽거나 갱신할 수 있습니
다. 분리 수준이 UR로 설정된 경우에 적용됩니다. IN, IS, S, IX,
SIX, U, X 잠금과 호환됩니다.
IS
잠금 소유자는 잠긴 테이블에서 데이터를 읽을 수는 있지만,
이 데이터를 갱신할 수는 없습니다. 다른 응용프로그램은 테
이블을 읽거나 갱신할 수 있습니다. IN, IS, S, IX, SIX, U 잠금
과 호환됩니다.
IX
잠금 소유자 및 동시 응용프로그램은 데이터를 읽고 갱신할
수 있습니다. 다른 동시 응용프로그램은 테이블을 읽고 갱신
할 수 있습니다. IN, IS, IX 잠금과 호환됩니다.
SIX
잠금 소유자는 데이터를 읽고 갱신할 수 있습니다. 다른 동시
응용프로그램은 테이블을 읽을 수 있습니다. 이미 IX 모드가
적용된 테이블에 대해 S 잠금을 적용해야 하는 경우에 사용
됩니다. IN, IS 잠금과 호환됩니다.
S
동시에 실행되는 다른 응용프로그램은 잠긴 데이터를 읽을
수는 있지만, 갱신할 수는 없습니다. IN, IS, S, U 잠금과 호환
됩니다.
U
잠금 소유자는 데이터를 갱신할 수 있습니다. 다른 UOW는
잠긴 오브젝트에서 데이터를 읽을 수는 있지만, 갱신할 수는
없습니다. FOR UPDATE 옵션이 있는 커서를 이용한 SELECT
문을 실행한 경우에 적용됩니다. IN, IS, S 잠금과 호환됩니다.
X
잠금 소유자만 데이터를 읽고 갱신할 수 있습니다. IN 잠금과
호환됩니다.
Z
테이블이 변경되거나 삭제된 경우, 테이블의 인덱스가 작성
U D B 개 발 자 기 본 교 육 • UNIT 07 • L O C K 89
TOPIC
07 06 테이블 잠금 지정 방법
01
1
데이터를 액세스하면 기본적으로 행 수준의 잠금이 적용됩니다.
4
특정 테이블의 행의 수가 많고, 대부분의 행을 액세스한다면, 행
$ db2 "alter table <테이블명> LOCKSIZE TABLE"
잠금을 관리하기 위한 리소스가 많이 소모되어 응답 시간이 지
$ db2 "alter table <테이블명> LOCKSIZE ROW"
연될 수 있으므로 명시적으로 테이블 잠금을 지정하는 것이 유
2
alter table 문에서 LOCKSIZE 옵션을 이용하여 지정합니다.
리합니다.
데이터의 기본 잠금 수준은 행 잠금입니다. 기본 잠금 수준을 테
이블 잠금으로 지정하면, SQL문을 실행할 때 항상 테이블 잠금
이 적용됩니다.
5
lock table 문에서 LOCKSIZE 옵션을 이용하여 지정합니다.
$ db2 "lock table <테이블명> in SHARE mode"
$ db2 "lock table <테이블명> in EXCLUSIVE mode"
3
기본 잠금 수준을 테이블 잠금으로 높이면 동시성이 저하시키는
단점이 있지만, 잠금을 관리하기 위한 비용이 줄어들 수 있으므
로 실제적인 응답 시간은 빨라질 수 있습니다.
U D B 개 발 자 기 본 교 육 • UNIT 07 • L O C K 90
TOPIC
07 07 행 잠금 유형
01
1
2
행 잠금의 유형에는 S, U, X, W, NS, NX, NW 등이 있습니다. 행
3
행 잠금 유형의 특성은 다음과 같습니다.
에 잠금이 적용되면, 테이블에는 지시성 잠금이 적용됩니다. 잠
모드
금이 적용된 행에 대해서 액세스가 유형별로 제한됩니다.
S
동시에 실행되는 다른 응용프로그램은 잠긴 데이터를 읽을
수는 있지만, 갱신할 수는 없습니다. 분리 수준이 RR인
SELECT문을 실행한 경우에 조건에 맞는 행과 액세스에 사
용된 모든 행에 대해 적용됩니다. S, U, NS 잠금과 호환됩니
다.
U
잠금 소유자는 데이터를 갱신할 수 있습니다. 다른 UOW는
잠긴 오브젝트에서 데이터를 읽을 수는 있지만, 갱신할 수
는 없습니다. FOR UPDATE 옵션이 있는 커서를 이용한
SELECT문을 실행하여 FETCH한 경우에 적용됩니다. S, NS
잠금과 호환됩니다.
X
잠금 소유자는 잠긴 오브젝트의 데이터를 읽고 갱신할 수
있습니다. UPDATE, INSERT, DELETE문을 실행한 경우에 적
용됩니다. 다른 응용프로그램들은 X 잠금이 적용된 행에 대
한 액세스를 할 수 없습니다.
W
type-2 인덱스가 없는 테이블로 행이 삽입되는 경우에 적용
됩니다. 잠금 소유자는 잠긴 행을 변경할 수 있습니다. 중복
값 발견시 중복 값을 커미트했는지 판별하기 위해, 고유한
인덱스로의 삽입 중에도 이 잠금이 사용됩니다. NW 잠금과
호환성이 되는 것을 제외하고 이 잠금은 X 잠금과 유사합니
다. NW잠금과 호환됩니다.
NS
동시에 실행되는 다른 응용프로그램은 잠긴 행을 읽을 수는
있지만, 갱신할 수는 없습니다. S 잠금과 유사하며, 분리 수
준이 RS 또는 CS인 경우에 적용됩니다. S, U, NS, NW 잠금
과 호환됩니다.
NW
행이 인덱스에 삽입되면, NW 잠금은 다음 행에서 획득됩니
다. type-2 인덱스의 경우, 다음 행이 현재 RR 스캔에 의해
잠긴 경우에만 발생합니다. 잠금 소유자는 잠긴 행을 읽을
U D B 개 발 자 기 본 교 육 • UNIT 07 • L O C K 91
수는 있지만, 갱신할 수는 없습니다. 이 잠금 모드는 W 및
행 잠금 유형과 잠금 유형간의 호환표은 다음과 같습니다. S, NS
행 잠금이 적용된 테이블에는 자동적으로 IS 테이블 잠금이 적용
되고, U, X, W, NW 행 잠금이 적용된 테이블에는 자동적으로 IX
테이블 잠금이 적용됩니다.
설명
TOPIC
07 08 잠금 변환 현상
01
1
이미 잠금이 적용된 행 또는 테이블에 다시 잠금이 요청되면, 기
존의 잠금 정보와 수위를 비교합니다. 기존의 잠금이 더 제한적
이라면 새로운 잠금 정보는 무시됩니다. 새로운 잠금이 더 강력
하다면 기존의 잠금 정보는 새로운 잠금 정보로 변환됩니다.
2
테이블 잠금과 행 잠금의 단계는 다음과 같습니다. 하위 잠금이
적용된 상태에서 상위 잠금이 요청되면, 하위 잠금 정보는 상위
잠금 정보로 갱신됩니다.
테이블 잠금
3
테이블 잠금과 행 잠금의 변환은 개별적으로 적용됩니다.
4
SELECT문의 조건문에서 고유한 인덱스가 있는 컬럼을 이용하여 데이
터를 조회하면, 해당 행에 대해 NS 또는 S 모드의 잠금이 적용됩니다.
동일한 행에 대해 UPDATE 문을 다시 실행하면, X 잠금이 적용되고,
LOCKLIST에 저장된 해당 행에 대한 NS 또는 S 모드의 잠금 정보는 X
모드의 잠금으로 갱신됩니다.
행 잠금
Z
X
U
SI
S
I
N
I
X
동일한 오브젝트에
대한
다양한 액세스
X
U
COMMIT 또는
ROLLBACK
S
U D B 개 발 자 기 본 교 육 • UNIT 07 • L O C K 92
TOPIC
07 09 잠금 상승 현상
01
1
행잠금이 테이블 잠금으로 전환되는 현상을 잠금 상승 현상이라
4
고 합니다. 잠금 상승 현상은 교착 상태를 유발시킬 수 있으며,
동시성을 저하시킵니다. 잠금 상승 현상이 발생하지 않도록 데
이터베이스 구성 변수인 LOCkLIST와 MAXLOCKS을 조절합니
2
다.
update db cfg 명령어로 데이터베이스 구성 변수인 LOCKLIST
구성 변수를 이용하여 잠금 정보를 저장하는 메모리 영역의 크
기를 조절합니다. <크기>는 4K 페이지 단위로 지정합니다.
$ db2 connect to sample
$ db2 update db cfg for sample using LOCKLIST 4000
3
MAXLOCKS 구성 변수는 LOCKLIST 구성 변수가 지정한 크기에서 한
응용프로그램이 사용할 수 있는 최대 비율을 지정합니다. <비율>은
백분율로 표시합니다.
$ db2 connect to sample
$ db2 update db cfg for sample using MAXLOCKS 30
5
한 응용프로그램에 대한 잠금 정보의 양이 MAXLOCKS의 비율을 초
과하게 되면, 해당 응용프로그램에서 가장 많은 행 잠금을 가진 테이
블을 식별하여 그 테이블에 대한 행 잠금을 모두 취소하고, 테이블 잠
금을 적용합니다.
잠금 정보는 데이터베이스별로 공유 메모리에 있는 LOCKLIST
영역에 저장됩니다. 잠금 정보의 양이 LOCKLIST의 크기를 초과
하게 되면, 가장 많은 행 잠금을 가진 테이블을 식별하여 그 테이
블에 대한 행 잠금을 모두 취소하고 테이블 잠금을 적용합니다.
U D B 개 발 자 기 본 교 육 • UNIT 07 • L O C K 93
TOPIC
07 10 잠금 대기 현상
01
1
한 응용프로그램이 잠금을 적용한 행을 다른 응용프로그램에서
액세스하려면, 그 잠금이 해제될 때까지 대기해야 합니다. 기본
잠금 대기 시간은 무한대이며, 데이터베이스 구성 변수인
4
LOCKTIMEOUT 구성 변수의 값을 초과할 때까지 필요한 잠금을 획득
하지 못하면, 응용프로그램은 중단되어 SQL0911N, SQLSTATE
40001과 이유 코드 68 이 반환됩니다.
LOCKTIMEOUT 을 이용하여 대기 시간을 조절할 수 있습니다.
2
update db cfg 명령어로 LOCKTIMEOUT 데이터베이스 구성
변수를 설정합니다. <잠금 대기 시간>은 1초 단위로 표시합니다.
LOCKTIMEOUT 구성 변수를 변경값을 반영하려면 데이터베이
스의 재활성화가 필요합니다. 예에서는 잠금 대기 시간을 30초
로 제한합니다.
$ db2 update db cfg for sample using LOCKTIMEOUT 30
3
LOCKTIMEOUT 데이터베이스 구성 변수의 기본값은 -1로서 무
한대로 대기하는 것을 의미합니다. 일반적인 OLTP 환경에서는
잠금 대기 시간을 30초 이내로 설정하도록 합니다. 잠금 대기
시간 이내에 필요한 잠금을 획득하면, 응용프로그램은 작업을
계속할 수 있습니다.
12
locktimeout
30
3
9
6
-1
x x
x
x x
x
x LOCK
x
x x HOG
x x
x
난 지금
그 자료가
필요한데, T
T
기다리셔 !
x
x
U D B 개 발 자 기 본 교 육 • UNIT 07 • L O C K 94
TOPIC
07 11 교착 상태
01
1
두 개의 응용프로그램이 서로 잠금 대기 상태가 되는 것을 교착
상태라고 합니다. 데이터베이스 구성 변수인 DLCHKTIME을 주
기로 교착 상태에 있는 응용프로그램을 파악하고, 한 응용프로
4
교착 상태가 감지되면, 희생자(victim)로 선정된 한 쪽의 응용프로그
램은 강제로 종료되고, SQL0911N, SQLSTATE 40001과 이유 코드 2
가 반환됩니다. 교착 상태를 해결하기 위해 희생자 프로세스를 선택
하는 기준은 엔진 내부의 알고리즘으로 사용자가 조절할 수 없습니다.
그램을 강제로 종료시키면, 다른 응용프로그램은 작업을 계속합
2
니다.
update db cfg 명령어로 DLCHKTIME 데이터베이스 구성 변수
를 설정합니다. <점검 간격>은 밀리초(1000분의 1초) 단위로
표시합니다. 예에서는 점검 간격을 20초로 지정합니다.
$ db2 connect to sample
$ db2 update db cfg for sample using DLCHKTIME 20000
3
DLCHKTIME 구성 변수의 기본값은 10000 ms로 10초 간격으로
교착 상태가 점검됩니다.
UNIT OF WORK DELETE SOME CEREAL AND MILK
RAISIN
BRAN
응용프로그램 A
응용프로그램 B
DLCHKTIME
10000
milliseconds
U D B 개 발 자 기 본 교 육 • UNIT 07 • L O C K 95
TOPIC
08
01
UNIT08
SQL 고려 사항
UDB개발자기본교육
인덱스의 필요성
인덱스 선정 기준
인덱스의 구조
인덱스 관리
복합 인덱스
클러스터 인덱스
인덱스 생성 옵션
Matching Column 수
Predicate
효율적인 SQL
컬럼 함수
데이터 유형 변환
부정형 PREDICATE
BETWEEN / NOT BETWEEN
술어 변환 / OR 와 IN / LIKE
연산식을 포함한 술어 / 스칼라 함수, UDF
인덱스 컬럼 변형
여러 컬럼 값 동시 비교
중복된 테이블 SCAN
FETCH FIRST N ROWS ONLY
OPTIMIZE FOR K ROWS
FOR READ ONLY / FOR UPDATE OF
DISTINCT, GROUP BY, ORDER BY
SUBQUERY 와 JOIN
SELECT * / COUNT(*)
UNION ALL
MIN, MAX
불필요한 조건 제거
INNER JOIN / OUTER JOIN
WITH HOLD 커서
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 96
TOPIC
08 01 인덱스의 필요성
01
1
2
인덱스를 사용하면 다음과 같은 장점이 있습니다.

DB2는 테이블과 인덱스에 대한 통계 정보를 이용하여 비용 기반의 액세스 플랜을 생성합니다. Application의 성능 향상을 위해서는
적절한 인덱스를 설계하고, 인덱스를 잘 이용하는 효율적인 SQL문을 작성하는 것이 중요합니다. 또한, 인덱스에 대한 통계 정보를
유지하는 것도 중요합니다.

Query를 실행시에 적합한 인덱스가 존재하지 않으면 테이블의 모든 행을 순차적으로 access하는 Table Scan이 실행됩니다.

Index scan은 optimizer가 선택한 인덱스를 이용하여 테이블에서 해당 행을 찾아오는 액세스 방법입니다. 조건절을 잘 표현하면,
Index scan시에 인덱스 전체를 스캔할 필요도 없으므로 읽어야 할 data page의 수를 감소시킬 수 있습니다.

테이블의 크기가 커질수록 Table Scan을 사용하는 쿼리의 성능은 급격히 감소하게 되지만, 일반적으로 인덱스 파일의 크기는
작으므로, index scan은 table scan 보다 빠릅니다.

인덱스를 이용하면 테이블로부터 데이터를 읽은 후에 다시 정렬할 필요가 없는 경우가 많습니다.
다음과 같은 경우에 인덱스를 생성하는 것이 필요합니다.

기본키(Primary Key)는 인덱스로 생성되어야 합니다.

고유키(Unique Key)도 인덱스로 생성되어야 합니다.

외부키(Foreign Key)로 사용되는 컬럼들은 가급적이면 인덱스로 생성하는 것이 좋습니다.

테이블 조인의 조건에 필요한 칼럼에 대해서는 인덱스를 생성합니다.

WHERE 조건에서 자주 사용되는 컬럼들은 Index로 생성하여 성능을 향상 시킵니다.

DISTINCT, ORDER BY, GROUP BY 등에 의해 정렬에 사용되는 컬럼에 대해 인덱스를 생성하여 추가적인 정렬 작업이 필요없게
합니다.

고유성이 필요한 테이블인 경우에는 반드시 Unique Index를 생성합니다.
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 97
TOPIC
08 02 인덱스의 선정 기준
01
1
인덱스를 생성할 때는 다음과 같은 사항들을 고려합니다.

기본키(Primary Key)와 고유키(Unique Key)에 대한 인덱스는 자동적으로 생성됩니다.

외부키(Foreign Key)는 가급적이면 인덱스로 생성합니다.

가능한 값의 변경이 빈번하지 않는 컬럼을 선정합니다.

SQL문의 정렬 순서에 근거하여 인덱스키의 정렬 순서를 결정합니다.

분포도가 좋은 컬럼은 단독 컬럼으로 인덱스를 생성합니다.

조건절에 자주 조합되어 사용되는 경우는 복합 인덱스를 생성합니다. filtering이 잘 되도록 하려면, 조건식에서 "=" 연산자로 자주
비교되는 칼럼을 먼저 선택하거나, 값의 종류가 가장 많은 칼럼 순으로 구성합니다.

Index Only Access가 가능한 Index를 고려합니다.

Index key가 길면 Table를 Full Scan 하는 것 보다 오히려 느릴 수도 있으므로, 보통 16자리 이내로 선택합니다.

기존 인덱스의 컬럼들을 부분적으로 포함하는 인덱스는 생성하지 않습니다.

OLTP 환경에서 한 테이블의 Index의 개수는 3개 이하가 바람직합니다.

한 테이블의 인덱스가 너무 많거나 인덱스 키가 너무 길면, 디스크 소모량이 많아지고, query에 대한 access path를 결정하기 위한
Compilation time이 길어집니다. 또한, LOAD, REORG, RECOVERY 유틸리티 수행시 Index Build를 위한 소요 시간이 길어집니다.

Index 수가 많을수록 Insert / Delete / Update 문의 실행 부하가 증가하므로 갱신이 많은 테이블의 Index 개수는 최소로 줄입니다.

특정 범위를 이용한 조건식에 많이 이용되어 Sequential access를 유도하는 인덱스를 Cluster Index로 지정합니다.

복합 인덱스를 구성하거나, Unique Index에 include column을 포함하여 index-only access를 유도하면 성능에 도움이 됩니다.

Allow Reverse Scan 옵션을 추가한 인덱스는 양방향 scan이 가능합니다.

인덱스는 테이블과 다른 테이블스페이스에 저장하고, 별도의 BUFFERPOOL을 할당하는 것이 좋습니다.
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 98
TOPIC
08 02 인덱스의 선정 기준
01
2
3
4
다음과 같은 Column으로 인덱스를 구성하는 것이 유리합니다.

Where절에서 자주 사용되는 Column

"=" 연산자를 사용하며, 5 ~ 10% 이내의 좋은 분포도를 가지는 Column

"BETWEEN" , "IN" , "<", ">" 조건절을 사용하는 Column

Join에 자주 사용되는 Column

Primary Key, Unique Key, Foreign Key로 사용되는 Column

ORDER BY, DISTINCT, GROUP BY 구문에 사용되는 정렬에 필요한 Column
다음과 같은 Column은 인덱스에 적합하지 않습니다.

값의 종류가 많지 않아서 Cardinality가 작은 Column

값이 균등하게 분포되지 않고 특정 값이 심하게 많은 Column

갱신이 빈번한 Column

길이가 40 바이트 이상되는 Column

LOB, LONG VARCHAR, LONG VARGRAPHIC 유형의 Column
컬럼값에 대한 분포도는 다음과 같이 산출합니다.
컬럼값에 대한 분포도 = ( 1 / 컬럼값의 종류 ) * 100 = ( 컬럼값의 종류별 평균 행수 / 테이블의 총 행수 )
* 100
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 99
TOPIC
08 03 인덱스의 구조
01
1
Index는 B+ Tree 구조를 가집니다.

여러 레벨로 구성되는 non-leaf 노드는 검색하려는 키값이 저장된 leaf 노드를 찾기 위한 Search tree 입니다.

non-leaf 노드의 각 항목은 Search-key값, 레코드에 대한 pointer인 RID, 다음 레벨의 non-leaf 노드에 대한 pointer인 PGID 로
구성됩니다.

각 항목의 Search-key 값은 PGID가 지정하고 있는 다음 레벨의 non-leaf 노드에 저장된 Search-key의 최대값이 됩니다.

leaf node의 각 항목은 인덱스키와 한 개 이상의 RID로 구성됩니다.
인덱스
테이블
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 100
TOPIC
08 04 인덱스의 관리
01
1
인덱스를 생성한 후에는 다음과 같은 관리가 필요합니다.

새로 추가된 Index가 기존의 액세스 경로에 영향을 미칠 수 있습니다.

새로운 인덱스를 생성한 후에는 인덱스에 대한 통계 자료를 수집하기 위해 RUNSTATS 유틸리티를 주기적으로 실행합니다. 수집된
통계 자료는 OPTIMIZER가 ACCESS PATH를 결정하는 데에 중요한 역할을 합니다.

분포도가 양호한 컬럼도 Filtering의 범위에 따라 분포도가 나빠질 수 있습니다.

분포도의 차이가 심한 Column이 포함된 인덱스는 통계 자료를 수집할 때 "with distribution" 옵션을 이용하여 분포 정보까지 수집하는
것이 좋습니다.

Filtering의 결과로 너무 넓은 범위의 result set이 생성된 경우에는 Index 처리가 오히려 성능을 저하시킵니다.

조건절은 Index 컬럼에 변형을 주지 않고 표현할 수 있도록 합니다.

조인시에 Index가 사용되는지 확인합니다.

갱신이 빈번한 테이블의 인덱스는 REORG TABLE 또는 REORG INDEXES 명령을 이용하여 정기적으로 REORG해 주는 것이
중요합니다.

익스플레인 유틸리티를 이용하여 자주 실행되는 QUERY가 해당 인덱스를 잘 사용하고 있는지 정기적으로 확인합니다.

불필요한 인덱스는 제거합니다.
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 101
TOPIC
08 05 복합 인덱스
01
1
2
복합 인덱스의 특성은 다음과 같습니다.

하나 이상의 컬럼으로 구성되며, 인덱스키를 구성하는 최대 컬럼의 개수는 16 개입니다.

여러 컬럼들이 항상 같이 WHERE절의 조건식에서 자주 사용될 경우에 생성합니다.

조회하는 모든 컬럼이 인덱스에 포함되어 있다면, 인덱스 액세스만으로 원하는 값을 가져올 수 있습니다. 이 경우에는, 단일 Column을
이용한 인덱스 액세스 후에 RID를 이용하여 테이블을 fetch하는 것보다 빠릅니다.

'GROUP BY' 또는 'ORDER BY' 에 사용되는 컬럼들과 정렬 순서대로 Index를 구성하면 내부적인 정렬 과정을 피할 수 있습니다.

Matching Column의 개수가 많을수록 효율적인 액세스가 가능합니다.
복합 인덱스를 생성하고 사용할 때는 다음과 같은 사항을 고려합니다.

인덱스키는 분포도가 좋고, Cardinality가 높은 컬럼 순으로 구성하여 추출되는 데이터의 건수를 최소화 시킵니다.

테이블의 데이터가 특정 Column에 대해 물리적으로 정렬되어 있으면, 해당 컬럼을 첫 번째 컬럼으로 구성합니다.

GROUP BY, ORDER BY 에 사용되는 정렬 순서대로 인덱스키의 컬럼 순서를 결정합니다.

기존의 복합 인덱스의 일부 컬럼을 이용한 중복 인덱스를 생성하지 않도록 해야 합니다. 단, (X,Y,Z)로 구성된 복합 인덱스가 있는
경우에도 (Y,Z) 만을 이용한 조건식이 빈번하게 필요하다면, (Y,Z)로 구성된 복합 인덱스를 별도로 생성하는 것이 좋습니다.

복합 인덱스의 첫 번째 컬럼은 반드시 조건식의 비교 조건에 사용되도록 합니다.

복합 인덱스를 구성하는 Column list에 있는 첫 번째를 포함한 연속적인 컬럼의 집합을 선행 부분 (leading portion) 이라고 합니다.
INDEX를 사용하기 위해서는 조건절에서 반드시 선행 컬럼이 정상적인 형태로 표현되어야 합니다. 예를 들어, (X,Y,Z)로 구성된 복합
인덱스에서 X, XY, XYZ는 선행 부분이 되지만, YZ, Z는 선행 부분이 될 수 없습니다. 선행 부분이 되지 않는 경우에는 인덱스를
효율적으로 사용할 수 없습니다.

AND와 OR를 이용하여 인덱스의 각 컬럼들을 이용한 조건식을 표현할 때, 조건식의 순서와 인덱스키의 순서가 반드시 일치할 필요는
없습니다.
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 102
TOPIC
08 06 클러스터 인덱스
01
1
2
3
클러스터 인덱스의 특성은 다음과 같습니다.

테이블의 데이터에 대한 물리적인 저장 순서를 결정합니다.

각 테이블에 한 개만 생성할 수 있습니다.

테이블에 데이터가 INSERT 또는 UPDATE 될 때에는 가급적 Clustering Index의 정렬 순서에 일치하도록 저장되므로 테이블
REORG의 필요성이 상당히 줄어듭니다.

OLTP 환경에서는 효율성이 크지 않지만, OLAP 환경에서는 Clustering index의 효과가 큽니다.
설계시의 고려 사항은 다음과 같습니다.

Primary Key를 반드시 Clustering Index로 지정할 필요는 없으며, Unique하지 않아도 됩니다.

대량의 데이터가 추출되는 WHERE문의 조건식에 사용되는 Index를 지정하면 유리합니다.

DISTINCT, GROUP BY, ORDER BY 등에 의해 정렬이 수행되는 Index를 지정하면 유리합니다.

BETWEEN , > AND < , LIKE 등과 특정 범위를 지정하는 조건식에서 사용되는 Index를 지정하면 유리합니다.
클러스터 인덱스를 사용할 때에는 다음과 같은 사항을 고려합니다.

Clustering Ratio가 낮은 인덱스는 옵티마이저에 의해 선택되지 않을 수 있으므로, REORG와 RUNSTATS 유틸리티를 이용하여
인덱스에 대한 CLUSTERRATIO 값을 가능한 높게 유지합니다.

ALTER TABLE문을 이용하여 테이블의 PCTFREE를 적절히 지정하면, 데이터가 INSERT될 때 CLUSTER RATIO를 유지하기가
용이하면, reorg 의 필요성이 감소됩니다.

LOAD 유틸리티를 사용할 때에는 PAGEFREESPACE 옵션을 지정하여 CLUSTER RATIO를 유지하도록 합니다.

모든 인덱스에 대한 CLUSTER RATIO를 높게 유지할 수는 없으므로, range 검색에 가장 중요한 인덱스를 기준으로 합니다.
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 103
TOPIC
08 07 인덱스 생성 옵션
01
1
인덱스를 생성할 때, 다양한 옵션을 추가할 수 있습니다. 예는 다음과 같습니다.
SQL 문
인덱스 생성 DDL 문
SELECT
WORKDEPT, LASTNAME
CREATE UNIQUE INDEX ix01
FROM
employee
ON employee (empno)
WHERE
empno >= 10000
CLUSTER
AND
empno <= 20000
SELECT
MAX(ORDER_DATE)
CREATE UNIQUE INDEX ix01
FROM
SALES
ON sales (order_date)
ALLOW REVERSE SCANAS
SELECT
LASTNAME
CREATE UNIQUE INDEX ix01
FROM
EMPLOYEE
ON employee (workdept, lastname)
WHERE
WORKDEPT IN ('A00','D11')
SELECT
LASTNAME
CREATE UNIQUE INDEX ix01
FROM
EMPLOYEE
ON employee (workdept)
WHERE
WORKDEPT IN ('A00','D11')
INCLUDE (lastname)
설명
WHERE절의 조건식에서 range 검색에 자주 사용
되는 칼럼에 대해 cluster 인덱스를 생성합니다. 예
의 SQL에서는 WHERE 절에 사용된 empno 컬럼
에 대해 인덱스를 생성합니다.
MAX 함수 처리시에 인덱스를 역방향으로
scan하면, 한 번의 액세스만으로 값을 구할 수
있으므로, 역방향 스캔을 허용하는 옵션을
사용합니다.
INDEX ONLY ACCESS는 RID를 이용하여
테이블을 Fetch 하지 않고, 인덱스만 액세스하여
데이터를 조회할 수 있으므로 훨씬 효율적입니다.
예에서는, WORKDEPT와 LASTNAME 컬럼으로
복합 인덱스를 생성하여 INDEX ONLY ACCESS를
유도했습니다. 단, WORKDEPT 컬럼이 복합
인덱스의 첫 번째 컬럼으로 구성되어야 합니다.
INCLUDE 옵션을 이용하여 인덱스키가 아닌
컬럼의 값을 인덱스에 포함시킬 수 있습니다.
예에서는, WORKDEPT 컬럼으로 UNIQUE
인덱스를 생성하고, LASTNAME 컬럼을 INCLUDE
COLUMN으로 지정했습니다. LASTNAME 컬럼은
인덱스키로 사용될 수는 없지만, 인덱스의 LEAF
PAGE에 그 값이 저장되어 있으므로, INDEX
ONLY ACCESS가 가능합니다.
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 104
TOPIC
08 08 Matching Column 수
01
1
인덱스를 사용하는 SQL문의 matching column의 개수는 판별하는 예는 다음과 같습니다. 예에서 :H 는 변수입니다.
INDEX 컬럼 구성
SQL 문
Matching Column 수
C1,C2,C3,C4
SELECT
C1,C2,C3,C4
FROM
T1
WHERE
C1 = :H AND C2 = :H
ORDER BY C3 , C4
2
C1,C2,C3 DESC,C4
SELECT
C1,C2,C3,C4
FROM
T1
WHERE
C1 = :H AND C2 = :H
ORDER BY C3 DESC , C4
2
C1,C3,C2
SELECT
C1,C2,C3
FROM
T1
WHERE
C1 = :H AND C2 LIKE 'xxx%' AND C3 = :H
ORDER BY C2
3
C1,C3,C2
SELECT
FROM
WHERE
3
C1,C3,C2
SELECT
C1,C2,C3
FROM
T1
WHERE
C1 = :H AND C2 IN (:H, :H) AND C3 = :H
ORDER BY C2
3
C2,C3,C1
SELECT
FROM
WHERE
C1,C2,C3
T1
C1 >= :H AND C2 = :H AND C3 = :H
3
C1,C3,C2
SELECT
FROM
WHERE
MAX(C2)
T1
C1 = :H1 AND C3 = :H
2
C1,C2,C3
T1
C1 = :H AND C2 BETWEEN :H AND :H AND C3 = :H
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 105
TOPIC
08 09 Predicate
01
1
SQL 문의 WHERE, HAVING, ON 절에서 AND, OR, NOT 등을 이용하여 표현되는 개별적인 조건식을 predicate 라고 하며, 내부적으로 처리되
2
RDS (Relational Data Services) 는 문자열 결합, 스칼라 함수 적용, 연산식 판별, 데이터 유형 전환 등의 상대적으로 복잡한 stage 2
3
DMS (Data Management Services) 는 동일한 데이터
는 단계에 따라 stage 1 predicate와 stage 2 predicate로 구분됩니다.
predicate를 처리합니다.
유형과 길이를 가진 상수값과 비교되는 컬럼을 포함한
SQL문
간단한 stage 1 predicate의 처리를 담당합니다.
4
IM (Index Manager)는 인덱스 액세스를 담당합니다.
SQL 구문 오류, 권
한점검, 데이터베이
스 오브젝트 ID 변
경 작업을 실행하고,
액세스 경로 를 생
성합니다.
필요한 데이터를
BM에게 요청합니
다.
Stage 2
predicate을 적용
하고, SORT 작업을
처리합니다.
Stage 1
predicate을 적용
하고, RDS에게 전
달합니다.
버퍼풀 또는 디스
크에서 필요한 데
이터를 액세스하여
DM에게 전달합니
다.
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 106
TOPIC
08 09 Predicate
01
5
6
다음과 같은 경우에 Stage 1 predicates 로 분류됩니다.

컬럼과 비교되는 변수의 데이터 유형과 그 길이는 일치하고, 단순 연산자 (=, >, >=, <, <=)로 비교되는 조건식이 해당됩니다.

상수값으로 표현되는 IN, BETWEEN, LIKE, IS NULL 등을 이용한 조건식도 stage 1 에서 평가됩니다.

부정형 연산자인 NOT은 stage 1 에서 평가되기는 하지만, matching index scan 은 사용되지 않습니다.

AVG, SUM, COUNT 등은 인덱스의 리프 노드 또는 데이터 페이지를 액세스하여 평가되며, MIN, MAX는 한 번의 fetch로 처리될
수도 있습니다.

>ALL, >ANY, >SOME 등과 함께 사용되어 단일한 값을 반환하는 non-correlated 서브 쿼리는 stage 1 에서 평가될 수 있습니다.

일부 서브 쿼리는 옵티마이저에 의해 재작성되어 stage 1 에서 평가될 수 있습니다.
다음과 같은 경우에 Stage 2 Predicate 로 분류됩니다.

Stage 1 에서 전달된 데이터 유형 변환, 연산식, 함수 적용 등은 Stage 2 에서 처리됩니다.

Stage 1 에서 전달된 Sort / Join / Correlated subquery / Non-Correlated subquery 등은 Stage 2 에서 처리됩니다.

조건식에서 비교되는 컬럼과 변수의 데이터 유형이 다른 경우가 해당됩니다. ( 예 : WHERE C1 > 1.1 )

컬럼에 대해 연산식 또는 스칼라 함수를 포함한 술어를 사용한 경우가 해당됩니다. ( 예 : WHERE C1 * 4 > :H )

값이 아닌 표현식을 포함한 IN 절을 사용하는 경우가 해당됩니다. ( 예 : WHERE C1 IN (<표현식>) )

IN, =ALL, =ANY, =SOME 을 포함한 서브 쿼리를 사용한 경우가 해당됩니다.

correlated 서브쿼리, EXISTS 또는 NOT EXISTS 를 포함한 서브 쿼리를 사용하는 경우가 해당됩니다.

한 개의 컬럼이 두 개 이상의 다른 컬럼과 비교되는 경우가 해당됩니다. ( 예 : WHERE C1 BETWEEN C2 AND C3 )

Data Manager가 일차적으로 처리한 행 또는 컬럼을 전달받은 RDS가 Stage 2 predicate를 적용하므로, 더 많은 CPU가 소모됩니다.
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 107
TOPIC
08 09 Predicate
01
7
Predicate는 인덱스 스캔의 가능 여부와 스캔 범위에 따라 "Range delimiting predicates", "Index SARGable predicates", "Data
SARGable predicates", "Residual predicates" 로 분류되며, 각 유형별로 독립된 처리 방법 및 cost 를 가지게 됩니다. SARGable의 SARG는
Search ARGument의 약자로서 키값을 이용하여 검색할 수 있다는 의미입니다.
8
employee 테이블에 (name, dept, mgr, salary, years)로 구성된 인덱스가 있다고 가정할 때, 다음과 같이 분류할 수 있습니다.
종류
설명
예문
Range
delimiting
predicate
 Index 검색에 필요한 시작키 값 또는 종료키 값을 명시되면, 인덱스에서 해
당 페이지만 검색합니다.
SELECT name, job, salary
 검색할 인덱스의 페이지 수와 테이블의 페이지 수를 모두 줄일 수 있습니다.
WHERE NAME = 'John'
 예문에서 NAME과 DEPT에 대한 조건식은 delimiting predicate 에 해당됩
니다.
Index
SARGable
predicate
 Range 검색이 아니더라도, 조건식의 컬럼이 인덱스키에 포함된 컬럼이라
면, 인덱스 leaf page를 모두 스캔하여 조건에 맞는 데이터를 검색할 수 있
습니다.
 NAME과 DEPT 컬럼에 대한 조건식은 range delimiting predicates이지
만, YEARS에 대한 조건식은 NAME과 DEPT에 의해 결정된 범위의 모든 인
덱스 leaf page를 검색해야 하므로, Index SARGable predicates입니다.
FROM
AND
employee
DEPT = 10 ;
Select name, job, salary
from
employee
Where NAME = 'John'
And
DEPT = 10
And
YEARS > 5;
 만약 YEARS >= 5 인 경우라면, range delimiting predicate 가 될 수 있습
니다.
Data
SARGable
predicate
 조건식을 평가하기 위해 인덱스 스캔을 이용할 수 없으므로 테이블을 스캔
합니다.
SELECT name, job, salary
 SALARY 컬럼에 대한 인덱스가 없으므로 테이블을 스캔하여 조건식을 평가
해야 합니다.
WHERE salary > 1000
FROM
employee
 Data Management Services 에 의해 평가됩니다.
Residual
predicate
 테이블 액세스 후에 추가적인 I/O를 요구하는 predicate로 cost가 가장 높
습니다.
SELECT empno, msg
 ANY, ALL, SOME, IN을 사용한 서브 쿼리와 Long Varchar, LOB 데이터의
검색, Index ORing, Index ANDing 이 사용되는 경우에 해당됩니다.
WHERE msg like ‘TEST%’
 Relational Data Services 에 의해 평가됩니다.
FROM employee
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 108
TOPIC
08 09 Predicate
01
9
Predicate 유형별로 Index 사용 가능 여부와 Stage 1 처리 여부는 다음과 같습니다. op는 > , >=, < , <= 등의 연산자, Expression은 연산식
또는 함수입니다.
Index 사용
Stage 1
COL = :hv1
YES
YES
COL IS NULL
YES
COL op :hv
Index 사용
Stage 1
T1.COL1 = T1.COL2
NO
NO
YES
T1.COL1 op T1.COL2
NO
NO
YES
YES
T1.COL1 <> T1.COL2
NO
NO
COL BETWEEN :hv1 AND :hv2
YES
YES
COL op ANY (noncorrelated subquery)
YES
YES
COL LIKE 'char%'
YES
YES
COL op ALL (noncorrelated subquery)
YES
YES
COL IN (list)
YES
YES
COL IN (noncorrelated subquery)
NO
NO
COL <> value
NO
YES
COL NOT IN (noncorrelated subquery)
NO
NO
COL IS NOT NULL
NO
YES
COL = ANY (noncorrelated subquery)
NO
NO
COL NOT BETWEEN v1 AND v2
NO
YES
COL <> ANY (noncorrelated subquery)
NO
NO
COL NOT IN (list)
NO
YES
COL = (correlated subquery)
NO
NO
COL NOT LIKE 'char%'
NO
YES
COL op (correlated subquery)
NO
NO
COL LIKE '%char'
NO
YES
COL <> (correlated subquery)
NO
NO
COL LIKE '_char'
NO
YES
COL = expression
NO
NO
T1.COL = T2.COL
YES
YES
expression = value
NO
NO
T1.COL op T2.COL
YES
YES
expression <> value
NO
NO
T1.COL <> T2.COL
NO
YES
expression op value
NO
NO
유형
유형
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 109
TOPIC
08 10 효율적인 SQL
01
1
2
3
기본적으로 다음과 같은 사항들을 고려합니다.

테이블간의 연관 관계, 테이블별 데이터 크기, Index 구성 컬럼과 정렬 순서 등을 충분히 이해하도록 합니다.

조건절에 주요하게 사용되는 컬럼에 대한 값의 종류와 비율을 파악합니다.

이해하기 쉽게 작성해야 프로그램의 유지 보수가 용이합니다.

SQL문의 개수와 그 수행 횟수를 최소화합니다.

SQL문의 조건을 표현할 때는 향후에 데이터량이 증가하더라도 성능이 저하되지 않도록 날짜 구간 등의 조건을 포함하도록 합니다.

작성된 SQL에 대한 Access Path를 확인하여 조건문의 변경 또는 인덱스의 추가를 고려합니다.
SELECT절에서 다음 사항을 고려합니다.

조회할 컬럼 목록으로 * 은 사용하지 않으며, 반드시 필요한 컬럼들을 모두 나열합니다.

COUNT(*) 은 사용하지 않도록 합니다.

NOT NULL 로 지정된 컬럼에 대해서는 NULL값인지를 확인하는 함수를 사용하지 않도록 합니다.

불필요한 DISTINCT는 사용하지 않습니다.
FROM절에서 다음 사항을 고려합니다.

FROM절에 기술된 테이블들 중에서 가장 먼저 읽는 테이블을 driving table 이라고 합니다.

옵티마이저는 통계 정보에 근거하여 건수가 적은 테이블을 driving table로 선택할 가능성이 높습니다.

조건절에서 연산식, ||, not , substring , rtrim 등을 이용하여 컬럼에 변형을 가하면 driving table 로 선택되지 않을 가능성이
높아집니다.

JOIN할 테이블이 3개 이상인 경우에는 JOIN 조건을 만족하는 총 행수가 적은 집합의 JOIN 이 먼저 실행되는 것이 유리합니다.
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 110
TOPIC
08 10 효율적인 SQL
01
4
5
WHERE절에서 다음 사항을 고려합니다.

가능한 모든 조건식을 기술하여 반환되는 행의 수를 최대한 줄이도록 합니다.

조건절에서 값을 비교할 때에는 가급적 등호(=)를 사용합니다. Matching Column의 개수가 많을수록 인덱스를 효율적으로
액세스합니다.

Column과 비교되는 변수는 데이터 유형과 그 길이를 같게 합니다.

NOT을 이용한 부정 연산자를 사용하지 않도록 합니다.

BETWEEN, LIKE, IN 등을 이용하여 범위를 지정하는 조건식을 표현할 때는 최소 구간을 지정합니다.

LIKE 연산자 사용시에 첫 문자로 '%' 또는 '_'를 사용하면, Range delimiting 인덱스로 사용할 수 없습니다.

인덱스를 구성하는 컬럼에 변형을 가하면 index scan 을 사용하지 못할 수 있습니다. Column에 대해 불필요한 함수 또는 연산식을
사용하지 않도록 합니다.

Cartesian Product 가 생성되지 않도록 JOIN 조건절을 반드시 기술합니다.

JOIN의 조건절에 AND를 사용하면 복합 인덱스를 사용할 수 있습니다.
 JOIN의 조건절에 OR를 사용하면 복합 인덱스를 사용할 수 없으며, union all로 연산되므로 성능 저하의 요인이 됩니다.
다음과 같은 경우에는 일반적으로 인덱스를 사용할 수 없습니다.

! , != 연산자와 LIKE에서 '%'로 시작되는 비교 문자열을 사용한 경우에는 비교의 기준이 불분명하기 때문에 인덱스를 사용할 수
없습니다.

NOT,< > 을 이용한 부정형은 대부분 인덱스를 사용할 수 없습니다.

인덱스 컬럼을 대상으로 연산식 또는 함수를 적용하면 인덱스를 효율적으로 사용할 수 없으므로, 비교되는 상수값을 변형하여
처리하도록 합니다.

복합 인덱스 사용시에 조건식에서 인덱스의 첫 번째 컬럼을 지정하지 않으면 해당 인덱스를 효율적으로 사용할 수 없습니다.

동일한 테이블의 컬럼들을 비교하는 조건문은 인덱스를 이용할 수 없습니다.

CORRELATED SUBQUERY를 사용하면 인덱스를 사용할 수 없습니다.
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 111
TOPIC
08 10 효율적인 SQL
01
6
추가적으로 다음 사항을 고려합니다.

UNION은 내부적으로 데이터의 정렬을 유발하므로 UNION ALL로 대체하거나 사용하지 않도록 합니다.

MAX 함수는 ALLOW REVERSE 옵션이 있는 INDEX를 사용하거나, ORDER BY시에 DESC 옵션을 사용하는 것으로 대체합니다.

Having 조건절은 컬럼 함수의 계산이 끝난 후에 데이터를 filtering하므로 이미 사용한 컬럼 함수만으로 조건식을 표현하는 것이
좋습니다.

인덱스 스캔을 하는 경우에는 이미 정렬이 되어 있으므로 Order By 문장을 추가적으로 사용하지 않도록 합니다.

조건에 맞는 데이터가 1건인 경우에는 CURSOR를 선언하지 않고, 단일한 SELECT문을 사용합니다.

내부적으로 데이터 형변환을 발생하면 예상하지 않은 액세스 플랜이 생성될 수 있으므로, 필요시에는 명시적으로 형변환을 표시하도록
합니다.

조회 범위가 넓은 경우에는 Table을 Scan하는 것이 오히려 효율적일 수도 있습니다.

여러 개의 인덱스가 있을 때, Filtering이 효과적인 인덱스를 사용하기 위해서 인위적으로 특정 인덱스를 사용하지 않도록 조건식을
조작하는 경우도 있습니다.
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 112
TOPIC
08 11 컬럼 함수
01
 불필요한 데이터 유형의 변환과 연산은 피해야 합니다.
 MIN, MAX, SUM, AVG, COUNT 등의 컬럼 함수는 stage 1 또는 stage 2 에서 처리됩니다.
 정렬 작업을 요구하지 않는 GROUP BY가 사용된 경우에는 stage 1 에서 평가됩니다.
 DISTINCT 가 없는 경우에는 stage 1 에서 평가됩니다.
 (SUM(C1) + SUM(C2)) 또는 (SUM(C1) + 100) 등과 같은 연산식이 없는 경우에는 stage 1 에서 평가됩니다.
 컬럼에 대한 stage 2 술어가 없는 경우에는 stage 1 에서 평가됩니다.
 STDDEV, VAR, 등은 stage 2 에서 평가됩니다.
WORSE
BETTER
SELECT
workdept, SUM(salary)
SELECT
workdept, SUM(salary)
FROM
emp
FROM
emp
WHERE
salary > 100
WHERE
salary > 100
GROUP BY workdept
GROUP BY workdept
HAVING
HAVING
SUM(salary) + 10 > 10000;
SUM(salary) > 9990;
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 113
TOPIC
08 12 데이터 유형 변환
01
 불필요한 데이터 유형의 변환은 피해야 합니다.
 유사 유형의 데이터 유형 변환은 내부적으로 발생되며, CAST 함수를 통한 명시적인 유형 변환도 피할 수 있으면 좋습니다.
 유형의 변환이 발생하면 성능은 저하되므로, 조인의 조건으로 사용되는 컬럼들은 테이블 정의시 데이터 유형을 동일하게 하는 것이 좋습
니다.
 특히 조인시 숫자 컬럼의 데이터 유형 변환은 성능을 심하게 저하시킬 수 있습니다.
 Optimizer가 Matching Index Scan을 사용하게 하려면, 상수 또는 호스트 변수를 사용하여 비교할 때 그 데이터의 유형과 길이가 일치
하여야 합니다.
 짧은 길이의 컬럼에는 VARCHAR보다는 CHAR 유형이 유리합니다.
WORSE
FLOAT 나 DECIMAL 보다는 INTEGER를 사용하는 것이 좋습니다.
BETTER
SELECT sn, pn
SELECT sn, pn
FROM
FROM
spj
spj
WHERE qty > 100.5
WHERE qty > 100.50
AND
AND
pn = 'P5';
pn = 'P5';
strcpy(v1,"S1 ");
strcpy(v1,"S1");
SELECT sn, sname
SELECT sn, sname
FROM
FROM
s
s
WHERE sn = :v1;
WHERE sn = :v1;
SELECT name, job, salary
SELECT name, job, salary
FROM
employee e, project p
FROM
employee e, department d
WHERE
e.emp_id = cast(p.emp_id as integer)
WHERE
e.dept_id = d.dept_id
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 114
TOPIC
08 13 부정형 PREDICATE
01
 대부분의 Predicate는 stage1 에서 처리되지만, 부정형 Predicate를 사용한 경우에는 Matching Index Scan을 사용하지 못합니다.
 != 보다는 > 또는 <가 유리하며, 등호가 포함된 >= 또는 <= 이 더 유리합니다.
 그러나, 모든 행을 Select 한 후, 프로그램 로직을 통해 불필요한 행을 제거하는 것보다는, 부정형 Predicate를 사용하는 것이 더 효과적입
니다.
WORSE
BETTER
SELECT sn, sname
FROM s
WHERE NOT status > 20;
SELECT sn, sname
FROM s
WHERE status <= 20;
SELECT sn, sname
FROM s
WHERE status != 20;
SELECT sn, sname
FROM s
WHERE status < 20
OR
status > 20 ;
SELECT 'OK'
FROM emp
WHERE empno <> '000000';
만약 empno 의 최소값이
'000000' 인 것이 규칙이라면,
< > 을 > 으로 변환할 수 있습
니다.
(status) 컬럼으로 인덱스가
생성되어 있었다면, INDEX
ORING 기능을 이용할 수 있
습니다.
SELECT 'OK'
FROM
emp
WHERE empno > '000000';
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 115
TOPIC
08 14 BETWEEN
01
 >= AND <= Predicate는 Between으로 Optimizer에 의해 변경될 수 있습니다. 하지만, 항상 그런 것은 아닙니다.
WORSE
BETTER
SELECT SN, PN, JN, QTY
SELECT SN, PN, JN, QTY
FROM SPJ
FROM
WHERE PN >= 'P2' AND PN <= 'P9';
WHERE PN BETWEEN 'P2' AND 'P9';
SPJ
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 116
TOPIC
08 15 NOT BETWEEN
01
 NOT BETWEEN 문 대신에 OR 문을 사용할 수 있습니다.
 UNION ALL을 사용하는 것도 효율적입니다.
 호스트 변수를 이용하여 두 개의 BETWEEN 문으로 구성하면 Range Delimeter Predicate로서 Index Matching Scan을 이용할 수
있습니다.
WORSE
BETTER
SELECT SN, PN, JN, QTY
SELECT SN, PN, JN, QTY
FROM SPJ
FROM SPJ
WHERE QTY NOT BETWEEN 100 AND 800;
WHERE QTY < 100 OR QTY > 800;
SELECT SN, PN, JN, QTY
FROM SPJ
WHERE QTY < 100
UNION ALL
SELECT SN, PN, JN, QTY
FROM SPJ
WHERE QTY > 800;
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 117
TOPIC
08 16 술어 변환
01
 Composite Index를 효과적으로 사용하기 위해, Optimizer는 동일한 결과 집합을 만들 수 있는 Predicate로 변경을 수행합니다.
WORSE
BETTER
SELECT sn, pn, jn, qty
FROM
spj
WHERE sn = 'S5'
AND
(pn BETWEEN 'P1' AND 'P3' OR
SELECT
FROM
sn, pn,jn, qty
spj
WHERE
(sn = 'S5' AND pn BETWEEN 'P1' AND 'P3')
OR
(sn = 'S5' AND pn BETWEEN 'P6' AND 'P7');
pn BETWEEN 'P6' AND 'P7');
(sn, pn, jn) 컬럼으로 복합 인덱스가
생성되어 있었다면, 술어의 형식을
변환함으로써 효율적으로 인덱스를
사용합니다.
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 118
TOPIC
08 17 OR 와 IN
01
 Index Scan 을 이용할 수 있다면, Optimizer는 OR 술어를 IN으로 변경합니다.
 INDEX ORING 의 기능을 이용할 수 있다면, IN이 OR로 변환될 수도 있습니다.
 IN 절에 나열된 값이 표현식이 아닌 상수값인 경우라면, OR을 이용하는 경우보다 표현이 간결합니다.
WORSE
BETTER
SELECT sn, pn, jn, qty
SELECT sn, pn, jn, qty
FROM
FROM spj
WHERE sn = 'S4'
AND
(pn = 'P1' OR pn = 'P2' OR pn = 'P3' OR pn = 'P4')
AND
jn > 'J1';
비교되는 값이 상수이
므로 IN으로 표현하는
것이 더 간결합니다.
spj
WHERE sn = 'S4'
AND
pn = IN ('P1','P2','P3','P4')
AND
jn > 'J1';
sn
pn
jn
S4
P1
J1
S4
P2
J1
S4
P3
J1
S4
P4
J1
(SN, PN, JN) 컬럼으로 복
합 인덱스가 생성되어 있
었다면,
4회의 Index Scan을 가능
하다면 병렬로 수행하여
INDEX ORING을 사용할
수 있습니다.
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 119
TOPIC
08 18 LIKE
01
 % 또는 _ 문자가 앞쪽에 나오면, Non-Matching Index Scan을 사용하게 됩니다.
 % 또는 _ 문자가 뒤쪽에 나오면, Matching Index Scan을 사용할 수 있습니다.
 인덱스 컬럼의 일부 문자열을 비교할 때 substr 함수를 사용하게 되면 인덱스를 사용하지 못하게 됩니다. 이 경우에는 like를 사용하는
것이 좋을 수도 있습니다.
 호스트 변수가 사용된 경우에는 실행 시점에 SCAN 방법이 결정됩니다.
WORSE
BETTER
SELECT PN, PNAME
FROM
P
WHERE PNAME LIKE '_CH%';
% 또는 _ 문자가 앞쪽에 나
오는 like 연산 처리는 인덱
스 전체를 scan 하게 됩니다.
SELECT PN, PNAME
FROM
P
WHERE PNAME LIKE 'CH%';
SELECT PN, PNAME
SELECT PN, PNAME
FROM
FROM P
P
WHERE PNAME LIKE '%CH%';
DELETE
FROM
t1
앞쪽에 나오는 % 또는 _ 문
자를 제거하여 filtering 한
후에 추가적인 로직으로 처
리합니다.
WHERE PNAME LIKE :PNAME;
(obm_name) 인덱스를
사용할 수 없을 수도 있습
니다.
DELETE
FROM
t1
WHERE order_date = :v1
WHERE order_date = :v1
AND
AND
substr(obm_name, 1, 1) = 'F'
SUBSTR을 like로 변환하여 인
덱스를 사용할 수 있게 합니다.
obm_name LIKE 'F%'
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 120
TOPIC
08 19 연산식을 포함한 술어
01
 컬럼에 수식 연산을 사용한 경우에는 Matching Index Scan을 사용할 수 없습니다.
 컬럼에 적용될 연산식을 비교되는 호스트 변수 쪽에 적용하면 Matching Index Scan을 사용할 수 있습니다.
 컬럼에 적용될 연산식을 미리 실행하여 호스트 변수에 그 값을 저장한 뒤에 비교하면 Matching Index Scan을 사용할 수 있습니다.
WORSE
BETTER
SELECT SN, PN, QTY
FROM
v1 = 200
SPJ
WHERE QTY * 4 > :v1;
SELECT SN, SNAME
FROM
S
WHERE QTY > :v1 / 2;
v1 = 200 / 2;
SELECT SN, SNAME
FROM S
WHERE QTY > :v1;
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 121
TOPIC
08 20 스칼라 함수, UDF
01
 스칼라 함수와 UDF는 Stage 2 에서 평가됩니다.
 컬럼에 스칼라 함수를 적용하지 말고, 비교되는 호스트 변수에 스칼라 함수를 적용하는 것이 좋습니다.
 비교되는 값에 Special Register 를 이용하는 것은 Stage 1 에서 평가됩니다.
WORSE
BETTER
SELECT
SN, PN, JN, QTY
SELECT SN, PN, JN, QTY
FROM
SPJ
FROM
SPJ
WHERE
DECIMAL(QTY) > :CALC_QTY;
WHERE
DECIMAL_QTY > DECIMAL(:CALC_QTY, 7,2);
SELECT PN, DATE_RECEIVED
FROM
SHIPMENTS
WHERE DATE_RECEIVED < CURRENT DATE - 15 DAYS;
SELECT PN, DATE_RECEIVED
FROM
SHIPMENTS
WHERE MONTH_REQUIRED = MONTH(:DATE-REQUIRED);
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 122
TOPIC
08 21 인덱스 컬럼 변형
01
 인덱스 컬럼이 조건식의 표현식이나 함수에 의해 수정되는 경우에는 인덱스를 최적의 방법으로 사용할 수 없습니다.
 인덱스 컬럼을 변형시키지 말고, 비교되는 상수값을 변형하여 처리하도록 합니다.
WORSE
BETTER
SELECT *
SELECT *
FROM
FROM
EMP
WHERE
DNAME LIKE 'ABC%';
EMP
WHERE SUBSTR(DNAME,1,3) = 'ABC'
SELECT *
SELECT *
FROM
FROM
EMP
WHERE DEPTNO || JOB = '10SALESMAN';
EMP
WHERE DEPTNO = '10'
AND
JOB
= 'SALSMAN';
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 123
TOPIC
08 22
01
여러 컬럼 값 동시
비교
 한 개의 호스트 변수를 이용하여 두 개 이상의 컬럼이 동시에 비교되는 경우에는 Stage 2 에서 평가됩니다.
 한 개의 호스트 변수가 한 개의 컬럼과 비교되는 형식으로 변경하면 matching index scan이 사용됩니다.
WORSE
BETTER
SELECT PN, ORDER_DATE, RECEIVED_DATE
SELECT
PN, ORDER_DATE, RECEIVED_DATE
FROM
FROM
ORDERS
ORDERS
WHERE '1997-07-01' BETWEEN ORDER_DATE AND RECEIVED_DATE;
WHERE
ORDER_DATE
AND
RECEIVED_DATE >= '1997-07-01';
<= '1997-07-01'
(ORDER_DATE, RECEIVED_DATE)
컬럼의 복합 인덱스가 생성되어 있었
다면, Matching Index Scan을 수행
할 수 있습니다.
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 124
TOPIC
08 23 중복된 테이블 SCAN
01
 UNION 을 사용하면, 동일한 테이블에 대한 SCAN 을 여러 번 중복하게 됩니다.
 CASE 문을 이용하면 동일한 테이블에 대해 한 번의 SCAN으로 조건을 판별할 수 있으므로 더 효율적입니다.
WORSE
SELECT
FROM
WHERE
AND
BETTER
EMPNO, LASTNAME, 'Male' AS GENDER
EMP
WORKDEPT = 'D4'
SEX = 'M'
SELECT EMPNO, LASTNAME,
CASE
WHEN 'M' THEN 'Male'
WHEN 'F' THEN 'Female'
ELSE 'UNKNOWN'
UNION ALL
SELECT EMPNO, LASTNAME, 'Female' AS GENDER
FROM
EMP
WHERE WORKDEPT = 'D4'
AND
SEX = 'F'
SEX
END AS GENDER
FROM
EMP
WHERE WORKDEPT = 'D4';
UNION ALL
SELECT EMPNO, LASTNAME, 'Unknown' AS GENDER
FROM
EMP
WHERE WORKDEPT = 'D4'
AND
SEX NOT IN ('M', 'F');
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 125
TOPIC
08 24 FETCH FIRST N ROWS ONLY
01
 조건에 맞는 데이터 중에서 최초의 N건만 Fetch 해도 되는 경우에는 Fetch First 절을 사용하여 반환되는 행의 개수를 줄여주는 것이
좋습니다.
 실제 조건에 맞는 데이터 중에서 최초의 N건만 반환됩니다.
 이 절은 FOR UPDATE 절과 함께 사용될 수 없습니다.
 이 절은 데이터베이스 엔진으로부터 검색된 행을 클라이언트 응용프로그램으로 전달시 블럭킹할 행의 건수에 영향을 줍니다.
 한 번의 Fetch 요청으로 N개의 행이 클라이언트로 전송될 수 있으며, 블록에 있는 행이 다 사용될 때까지는 Fetch 요청이 클라이언트
머신에서만 처리될 수 있으므로, 서버로의 통신 부하를 줄여줄 수 있습니다.
 원격 클라이언트인 경우에는 rqrioblk, 지역 클라이언트인 경우에는 aslheapsz 라는 구성 변수가 블럭킹 버퍼의 크기에 영향을 줍니다.
WORSE
BETTER
EXEC SQL DECLARE c1 CURSOR FOR
EXEC SQL DECLARE c1 CURSOR FOR
SELECT projno, projname, repemp
SELECT projno, projname, repemp
FROM
FROM
project
project
WHERE deptno = 'D11'
WHERE deptno = 'D11'
ORDER BY projno DESC;
ORDER BY projno DESC
FETCH FIRST 10 ROWS ONLY;
EXEC SQL OPEN c1;
EXEC SQL OPEN c1;
i = 0;
do {
do {
EXEC SQL FETCH c1 INTO :v1, :v2, :v3;
EXEC SQL FETCH c1 INTO :v1, :v2, :v3;
if ( SQLCODE != 0 || i>9 ) break;
if (SQLCODE != 0) break;
i++;
} while ( 1 );
} while ( 1 );
EXEC SQL CLOSE c1;
EXEC SQL CLOSE c1;
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 126
TOPIC
08 25 OPTIMIZE FOR K ROWS
01
 OPTIMIZE FOR K ROWS를 지정하므로 옵티마이저는 K행의 검색에 적합한 액세스 플랜을 생성합니다.
 N의 값이 너무 작거나, K값보다 작거나, batch 프로그램인 경우에는 OPTIMIZE 절을 사용할 필요가 없습니다.
 N과 K, 클라이언트와 서버 측의 qrioblk 또는 aslheapsz 중에서 작은 값이 한 블럭안에 들어갈 행의 개수에 영향을 줍니다.
 조건에 맞는 행의 개수가 많고, 게시판의 첫 페이지처럼 최초의 K건이 빨리 검색되기를 원하는 경우에 주로 사용됩니다.
 조건에 맞는 데이터 중에서 최초의 N건만 Fetch 하면서 K건의 빠른 초기 검색을 원한다면, FETCH FIRST N ROWS와 OPTIMIZE FOR K
ROWS 절을 함께 사용합니다.
WORSE
BETTER
EXEC SQL DECLARE c1 CURSOR FOR
EXEC SQL DECLARE c1 CURSOR FOR
SELECT projno, projname, repemp
SELECT projno, projname, repemp
FROM
FROM
project
project
WHERE deptno = 'D11'
WHERE deptno = 'D11'
ORDER BY projno DESC;
ORDER BY projno DESC
FETCH FIRST 100 ROWS ONLY
EXEC SQL OPEN c1;
i = 0;
Result set이 100건이라는 것을
안다면, 100번째 fetch 까지만
진행하기 위해 fetch 회수를 기
억하는 로직은 불필요합니다.
OPTIMIZE FOR 20 ROWS;
EXEC SQL OPEN c1;
do {
EXEC SQL FETCH c1 INTO :v1, :v2, :v3;
do {
if ( SQLCODE != 0 || i >99 ) break;
EXEC SQL FETCH c1 INTO :v1, :v2, :v3;
i++;
if (SQLCODE != 0) break;
} while ( 1 );
} while ( 1 );
EXEC SQL CLOSE c1;
EXEC SQL CLOSE c1;
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 127
TOPIC
08 26 FOR READ ONLY
01
 단순히 조회용으로만 사용되는 커서를 선언할 때는 FOR READ ONLY 또는 FOR FETCH ONLY 절을 사용합니다.
 이 절을 이용하면 Unambigous 커서가 되므로 프리컴파일 또는 바인드시 BLOCKING 옵션을 ALL 또는 UNAMBIGUOUS로 지정할 때
Row Blocking기능을 사용하게 되므로 성능에 유리합니다.
 데이터는 변경되지 않을 것이므로 WITH UR 옵션을 함께 사용하면 S Lock 도 설정되지 않으므로 동시성이 높아집니다.
WORSE
BETTER
EXEC SQL DECLARE c1 CURSOR FOR
EXEC SQL DECLARE c1 CURSOR FOR
SELECT projno, prstdate, prendate
SELECT projno, prstdate, prendate
FROM
FROM
project
project
WHERE deptno = 'D11'
WHERE deptno = 'D11'
ORDER BY projno DESC
ORDER BY projno DESC
WITH UR;
FOR READ ONLY
WITH UR;
EXEC SQL OPEN c1;
EXEC SQL OPEN c1;
do {
EXEC SQL FETCH c1 INTO :v1, :v2. :v3;
if (SQLCODE != 0) break;
} while ( 1 );
do {
EXEC SQL FETCH c1 INTO :v1, :v2. :v3;
if (SQLCODE != 0) break;
} while ( 1 );
EXEC SQL CLOSE c1;
EXEC SQL CLOSE c1;
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 128
TOPIC
08 27 FOR UPDATE OF
01
 커서를 통한 Positioned Update 를 원하는 경우에는 For update of 다음에 갱신할 칼럼들을 콤마로 분리하여 나열합니다.
 모든 컬럼들이 Update의 대상이 될 수 있다면, For update 라고 지정합니다.
 커서를 통한 Positioned Delete 를 원하는 경우에도 For update 라고 지정합니다.
 Positioned UPDATE/DELETE를 이용하면, UPDATE 또는 DELETE 시 WHERE 조건절에서 해당 행을 다시 검색하지 않고 이미 Fetch 된
행과 그 정보를 이용하므로, 검색에 필요한 비용이 줄어들어 성능이 향상됩니다.
 이 절이 사용되면 Select 시에 S(Shared) 대신에 U(Update) Lock을 적용하게 되므로 교착 상태를 방지하는데 도움이 됩니다.
WORSE
BETTER
EXEC SQL DECLARE c1 CURSOR FOR
EXEC SQL DECLARE c1 CURSOR FOR
SELECT projno, prstdate, prendate
SELECT projno, prstdate, prendate
FROM
FROM
project
WHERE deptno = 'D11';
project
WHERE deptno = 'D11'
FOR UPDATE OF prstdate, prendate;
EXEC SQL OPEN c1;
EXEC SQL OPEN c1;
do {
EXEC SQL FETCH c1 INTO :v1, :v2. :v3;
UPDATE 커서임을 명시적으로
표시하여 교착 상태 발생을 방지
합니다.
do {
if (SQLCODE != 0) break;
EXEC SQL FETCH c1 INTO :v1, :v2. :v3;
EXEC SQL UPDATE project
if (SQLCODE != 0) break;
SET prenddate = CURRENT DATE
EXEC SQL UPDATE project
WHERE projno = :v1;
} while ( 1 );
EXEC SQL CLOSE c1;
조건에 맞는 데이터를 다시 검
색하여 UPDATE를 실행하게
됩니다.
SET prenddate = CURRENT DATE
WHERE CURRENT OF c1;
} while ( 1 );
EXEC SQL CLOSE c1;
Positioned UPDATE를 사용하
므로 성능에 도움이 됩니다.
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 129
TOPIC
08 28 DISTINCT, GROUP BY, ORDER BY
01
 불필요한 DISTINCT와 ORDER BY, GROUP BY 절은 가급적 배제합니다.
 이 절을 사용하면 SORT 작업이 요구되는데, SORTHEAP이 부족한 경우에는 임시 테이블 등을 통한 정렬 작업이 발생하므로, CPU 사용
량이 증가하게 됩니다.
 GROUP BY 절은 수행 중에 중복된 값을 제거 하면서 SORT TREE 를 구성합니다. DISTINCT는 모든 값을 정렬한 후 중복된 값을 제거합
니다.
 이 절이 사용되면 커서의 OPEN 시점에 RESULT SET이 모두 만들어진 후 FETCH를 하게 됩니다.
 이 절을 사용해야만 한다면, 적합한 인덱스를 생성하고, 인덱스의 컬럼 순서대로 정렬을 지정하여 SORT 작업이 발생하는 것을 방지하
는 것이 좋습니다.
WORSE
결과 집합에 UNIQUE KEY, PRIMARY KEY, UNIQUE INDEX를 구성하는 컬럼들이 포함되어 있다면 DISTINCT는 불필요합니다.
BETTER
 group by에서 지정한 컬럼을 이용하여 결과 집합을 정렬하고자 한다면, 추가적으로 order by를 사용할 필요가 없습니다.
SELECT DISTINCT city
SELECT
city
FROM
FROM
t1
t1;
DISTINCT 보다는 GROUP BY
가 효율적입니다.
GROUP BY city;
SELECT DISTINCT empno, lastname
FROM
employee;
SELECT empno, lastname
FROM
employee;
(empno)로 UNIQUE 인덱스가
있다면, DISTINCT는 불필요합
니다.
SELECT
issue_code, pos_code, SUM(book_qty)
FROM
t1
SELECT
issue_code, pos_code, SUM(book_qty)
WHERE
stock_chng_type = :v1 AND book_qty > 0
FROM
t1
GROUP BY
issue_code, pos_code
WHERE
stock_chng_type = :v1 AND book_qty > 0
ORDER BY
issue_code
GROUP BY
issue_code, pos_code
issue_code 순으로 이미 정렬되
었으므로 OREDER BY를 제거
합니다.
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 130
TOPIC
08 29 SUBQUERY 와 JOIN
01
 SUBQUERY 보다는 JOIN이 일반적으로 더 효율적입니다.
 SUBQUERY와 JOIN 간의 상호 변환은 옵티마이저에 의해 대부분은 자동적으로 조절될 수 있습니다.
 Null 을 허용하지 않는 Outer SELECT의 컬럼과 비교하는 Inner SELECT의 컬럼이 Null값인 경우에는 성능이 저하됩니다.
 여러 개의 서브 쿼리가 AND로 연결되어 있다면, Filtering 이 잘 되는 서브 쿼리를 앞쪽에 배치하는 것이 성능에 도움이 됩니다.
 Outer SELECT의 컬럼과 Inner SELECT의 비교 컬럼의 데이터 유형이 일치하지 않아서 Outer SELECT의 컬럼에 대한 데이터 유형의 변
환이 필요한 경우에는 성능이 저하됩니다.
WORSE
BETTER
EXEC SQL DECLARE c1 FOR
EXEC SQL DECLARE c1 FOR
SELECT ISSUE_GB,
FROM
SELECT ISSUE_GB,
ISSUE_CODE,
ISSUE_CODE,
VALUE(DIFF_GB,'3'),
VALUE(DIFF_GB, '3'),
VALUE(DIFF, 0),
VALUE(DIFF, 0),
VALUE(CURR_PRICE, 0),
VALUE(CURR_PRICE, 0),
VALUE(SELL_PRICE, 0),
VALUE(SELL_PRICE, 0),
VALUE(BUY_PRICE , 0)
VALUE(BUY_PRICE , 0)
TVJONGCURR
FROM
WHERE ISSUE_GB = :v1
AND
TVJONGMAST B
ISSUE_CODE IN ( SELECT ISSUE_CODE
ORDER BY ISSUE_CODE;
TVJONGCURR A,
WHERE A.ISSUE_GB = :v1
FROM TVJONGMAST
AND
A.ISSUE_GB = B.ISSUE_GB
WHERE ISSUE_GB = :v1
AND
A.ISSUE_CODE = B.ISSUE_CODE
AND
AND
B.ADMIN_GB = :v3
ADMIN_GB = :v2 )
ORDER BY ISSUE_CODE;
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 131
TOPIC
08 30 SELECT *
01
 SELECT LIST에는 반드시 필요한 칼럼만 명시합니다.
 테이블의 모든 칼럼의 자료를 선택하고자 하는 경우라도 * 대신에 컬럼명을 일일이 나열하는 것이 바람직합니다.
 불필요한 컬럼까지 fetch 하므로 응답 시간이 증가되어 비효율적입니다.
 SELECT 해야 할 컬럼을 모두 가진 인덱스가 존재하더라도 Index Only Access를 할 수 없습니다.
 SELECT 에서 * 을 사용하면 칼럼이 추가되는 경우 등 테이블 구조가 변경되면 테이블이 사용된 모든 프로그램에 수정이 필요하게 됩니
다.
 SELECT 문의 가독성이 향상되며, 향후 운영시에도 도움이 됩니다.
WORSE
BETTER
EXEC SQL DECLARE c1 CURSOR FOR
EXEC SQL DECLARE c1 CURSOR FOR
SELECT *
SELECT projno, prstdate, prendate
FROM
FROM
project
WHERE deptno = 'D11';
project
WHERE deptno = 'D11';
EXEC SQL OPEN c1;
EXEC SQL OPEN c1;
do {
do {
EXEC SQL FETCH c1 INTO :v1, :v2. :v3;
EXEC SQL FETCH c1 INTO :v1, :v2. :v3;
if (SQLCODE != 0) break;
if (SQLCODE != 0) break;
} while ( 1 );
EXEC SQL UPDATE project
SET prenddate = CURRENT DATE
EXEC SQL CLOSE c1;
WHERE projno = :v1;
} while ( 1 );
EXEC SQL CLOSE c1;
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 132
TOPIC
08 31 COUNT(*)
01
 단순히 테이블에 데이터가 존재하는지를 확인하기 위해 COUNT(*) 을 사용하지 않도록 합니다.
 대신에 상수를 이용한 SELECT문을 실행하여 SQLCODE 값으로 판별합니다. 즉, SQLCODE가 100이면 데이터가 0건, 0이면 1건, -811
이면 2건 이상인 것으로 판별합니다.
 인덱스에 있는 특정 컬럼의 값이 NULL 값이 아닌 건수를 확인하려면, COUNT 함수에서 * 대신에 해당 컬럼명을 명시합니다.
WORSE
BETTER
EXEC SQL SELECT COUNT(*)
EXEC SQL SELECT 1
INTO
:v1
INTO
:v1
FROM
project
FROM
project
WHERE deptno = 'D11';
if (v1 > 0) {
WHERE deptno = 'D11';
if (SQLCODE == -811) {
printf("데이터가 존재합니다");
printf("데이터가 존재합니다");
return;
SELECT 문의 결과가 두 행 이
상이면, SQLCODE -811이 반
환됩니다.
return;
}
}
EXEC SQL SELECT deptno, COUNT(*)
INTO
FROM
:v1
project
WHERE deptno > 'D11'
AND
projno IS NOT NULL
EXEC SQL SELECT deptno, COUNT(projno)
INTO
:v1
FROM
project
WHERE deptno > 'D11'
GROUP BY deptno;
(deptno, projno) 인덱스가 있고,
projno가 NULL이 아닌 건수를
확인하는 경우에 유리합니다.
GROUP BY deptno;
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 133
TOPIC
08 32 UNION ALL
01
 UNION 절은 정렬 작업을 필요로 합니다.
 결과 집합에 대한 정렬이 불필요한 경우에는 UNION 대신 UNION ALL을 사용하여 정렬이 발생하지 않도록 합니다.
WORSE
SELECT
FROM
WHERE
AND
BETTER
EMPNO, LASTNAME, 'Male' AS GENDER
EMP
WORKDEPT = 'D4'
SEX = 'M'
SELECT
FROM
WHERE
AND
EMPNO, LASTNAME, 'Male' AS GENDER
EMP
WORKDEPT = 'D4'
SEX = 'M'
UNION
UNION ALL
SELECT EMPNO, LASTNAME, 'Female' AS GENDER
FROM
EMP
WHERE WORKDEPT = 'D4'
AND
SEX = 'F'
SELECT EMPNO, LASTNAME, 'Female' AS GENDER
FROM
EMP
WHERE WORKDEPT = 'D4'
AND
SEX = 'F'
UNION
UNION ALL
SELECT EMPNO, LASTNAME, 'Unknown' AS GENDER
FROM EMP
WHERE WORKDEPT = 'D4'
AND
SEX NOT IN ('M', 'F');
SELECT EMPNO, LASTNAME, 'Unknown' AS GENDER
FROM EMP
WHERE WORKDEPT = 'D4'
AND
SEX NOT IN ('M', 'F');
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 134
TOPIC
08 33 MIN, MAX
01
 MIN 또는 MAX 값을 구하기 경우에는 FETCH FIRST 절을 이용하면 유용합니다.
 필요하다면, ALLOW REVERSE SCANS 옵션을 가진 인덱스를 생성하도록 합니다.
WORSE
BETTER
SELECT
MIN(salary)
SELECT
salary
FROM
emp
FROM
emp
WHERE
dept = 'DBA' ;
WHERE
dept = 'DBA'
SELECT
MAX(salary)
FROM
emp
WHERE
dept = 'DBA' ;
(salary) 컬럼에 대한 ASC 인덱
스가 있는 경우에는 인덱스에 대
ORDER BY salary
한 한 번의 fetch 만으로 MIN 값
FETCH FIRST 1 ROWS ONLY;
을 얻을 수 있습니다.
SELECT
salary
FROM
emp
WHERE
dept = 'DBA'
ORDER BY salary DESC
FETCH FIRST 1 ROWS ONLY;
(salary) 컬럼에 대한 DESC 인덱
스가 있는 경우에는 인덱스에 대
한 한 번의 fetch 만으로 MIN 값
을 얻을 수 있습니다. ASC 인덱
스로 ALLOW REVERSE SCANS
옵션을 준 경우에도 동알합니다.
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 135
TOPIC
08 34 불필요한 조건 제거
01
 where 절의 predicate은 가능한 간단하게 작성합니다.
 조건에 맞는 자료를 filtering 하는데 도움이 되지 않는 불필요한 조건절은 추가하지 않도록 합니다.
WORSE
BETTER
SELECT
sale_time, a_qty, b_qty
SELECT
sale_time, a_qty, b_qty
FROM
t1
FROM
t1
WHERE
sale_date = :v1
WHERE
sale_time = ( SELECT MAX(sale_time)
AND
sale_time = ( SELECT MAX(sale_time)
FROM
t1
WHERE
sale_date = :v1 );
FROM
t1);
T1 테이블을 매일 오전 9시 기준
으로 최근 일자분만 남기고
truncate 작업을 실행한다고 가
정하면, sale_date 컬럼으로 날
짜를 비교하는 것은 불필요한 작
업입니다.
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 136
TOPIC
08 35 INNER JOIN
01
 JOIN 시에는 반드시 조인의 조건을 명시하도록 합니다.
 적합한 JOIN 조건이 명시되지 않으면, 두 테이블간의 모든 경우를 조합하는 카테시안곱이 실행되어 성능이 저하됩니다.
 JOIN하는 두 테이블 중에서 적어도 한 테이블의 PRIMARY KEY 또는 UNIQUE 컬럼을 JOIN PREDIACATE 로 사용하도록 합니다. 그렇
지 않으면 옵티마이저는 해당 조인을 카테시안곱으로 간주하고 실행 비용을 높게 예측하게 됩니다.
 JOIN 의 술어로 사용되는 컬럼들은 인덱스로 구성되어 있는 것이 좋습니다.
WORSE
BETTER
SELECT
EMP.EMPNO, EMP.LASTNAME, DEPT.DEPTNAME
SELECT
EMP.EMPNO, EMP.LASTNAME, DEPT.DEPTNAME
FROM
EMP, DEPT
FROM
EMP, DEPT
WHERE
EMP.WORKDEPT = DEPT.DEPTNUMB;
WHERE
EMP.WORKDEPT = DEPT.DEPTNUMB;
(deptnumb) 컬럼은 DEPT 테이
블의 PRIMARY KEY 입니다.
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 137
TOPIC
08 36 OUTER JOIN
01
1
left outer join에서 on절과 where을 잘못 사용하시면 엉뚱한 결과가 나옵니다. 특히 on 절에 상수를 사용할때는 주의하시기 바랍니다.
SELECT
FROM
deptno, deptname, mgrno
department
DEPTNO
-----A00
B01
C01
D01
D11
D21
E01
E11
E21
DEPTNAME
----------------------------SPIFFY COMPUTER SERVICE DIV.
PLANNING
INFORMATION CENTER
DEVELOPMENT CENTER
MANUFACTURING SYSTEMS
ADMINISTRATION SYSTEMS
SUPPORT SERVICES
OPERATIONS
SOFTWARE SUPPORT
SELECT
FROM
DEPTNO
-----A00
B01
C01
D01
E11
D21
E21
D11
E01
MGRNO
-----000010
000020
000030
000060
000070
000050
000090
000100
SELECT
deptno, deptname, mgrno
FROM
department2
DEPTNO DEPTNAME
MGRNO
------ ----------------------------- ------
A00
SPIFFY COMPUTER SERVICE DIV. 000010
B01
PLANNING
000020
C01
INFORMATION CENTER
000030
a.deptno, a.deptname, a.mgrno, b.deptno, b.deptname, b.mgrno
department a LEFT OUTER JOIN department2 b ON a.deptno = b.deptno
DEPTNAME
----------------------------SPIFFY COMPUTER SERVICE DIV.
PLANNING
INFORMATION CENTER
DEVELOPMENT CENTER
OPERATIONS
ADMINISTRATION SYSTEMS
SOFTWARE SUPPORT
MANUFACTURING SYSTEMS
SUPPORT SERVICES
MGRNO
-----000010
000020
000030
000090
000070
000100
000060
000050
DEPTNO
-----A00
B01
C01
-
DEPTNAME
----------------------------SPIFFY COMPUTER SERVICE DIV.
PLANNING
INFORMATION CENTER
-
MGRNO
-----000010
000020
000030
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 138
TOPIC
08 36 OUTER JOIN
01
2
b.deptno < 'C00' 절은 DB2의 optimizer가 department2 table의 predicate사용되도록 SQL이 rewrite됩니다. department2 table
에 대해 b.deptno <'C00' 절이 먼저 수행되고, 이 결과 값과 department table이 join을 합니다.
SELECT
FROM
DEPTNO
-----A00
B01
D01
E11
D21
E21
C01
D11
E01
3
a.deptno, a.deptname, a.mgrno, b.deptno, b.deptname, b.mgrno
department a LEFT OUTER JOIN department2 b ON a.deptno = b.deptno AND b.deptno < 'C00'
DEPTNAME
----------------------------SPIFFY COMPUTER SERVICE DIV.
PLANNING
DEVELOPMENT CENTER
OPERATIONS
ADMINISTRATION SYSTEMS
SOFTWARE SUPPORT
INFORMATION CENTER
MANUFACTURING SYSTEMS
SUPPORT SERVICES
MGRNO
-----000010
000020
000090
000070
000100
000030
000060
000050
DEPTNO
-----A00
B01
-
DEPTNAME
----------------------------SPIFFY COMPUTER SERVICE DIV.
PLANNING
-
MGRNO
-----000010
000020
-
department와 department2 table에 대한 outer join을 수행하고 그 결과 값에 대해 b.deptno < 'C00' 절을 수행합니다.
SELECT
FROM
WHERE
DEPTNO
-----A00
B01
a.deptno, a.deptname, a.mgrno, b.deptno, b.deptname, b.mgrno
department a LEFT OUTER JOIN department2 b ON a.deptno = b.deptno
b.deptno < 'C00'
DEPTNAME
----------------------------SPIFFY COMPUTER SERVICE DIV.
PLANNING
MGRNO
-----000010
000020
DEPTNO
-----A00
B01
DEPTNAME
----------------------------SPIFFY COMPUTER SERVICE DIV.
PLANNING
MGRNO
-----000010
000020
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 139
TOPIC
08 36 OUTER JOIN
01
4
a.deptno < 'C00' 절은 department table과 department2 table간의 left outer join을 하는 predicate이 됩니다. department
table의 deptno가 C00보다 작은 값에 대해서만 department2 table과 outer join을 수행합니다. 그러나, 이것이 department table
의 건수를 제한하는 것은 아닙니다.
SELECT
FROM
DEPTNO
-----A00
B01
C01
D01
D11
D21
E01
E11
E21
SELECT
FROM
WHERE
DEPTNO
-----A00
B01
a.deptno, a.deptname, a.mgrno, b.deptno, b.deptname, b.mgrno
department a LEFT OUTER JOIN department2 b ON a.deptno = b.deptno AND a.deptno < 'C00'
DEPTNAME
----------------------------SPIFFY COMPUTER SERVICE DIV.
PLANNING
INFORMATION CENTER
DEVELOPMENT CENTER
MANUFACTURING SYSTEMS
ADMINISTRATION SYSTEMS
SUPPORT SERVICES
OPERATIONS
SOFTWARE SUPPORT
MGRNO
-----000010
000020
000030
000060
000070
000050
000090
000100
DEPTNO
-----A00
B01
-
DEPTNAME
----------------------------SPIFFY COMPUTER SERVICE DIV.
PLANNING
-
MGRNO
-----000010
000020
-
a.deptno, a.deptname, a.mgrno, b.deptno, b.deptname, b.mgrno
department a LEFT OUTER JOIN department2 b ON a.deptno = b.deptno
a.deptno < 'C00'
DEPTNAME
----------------------------SPIFFY COMPUTER SERVICE DIV.
PLANNING
MGRNO
-----000010
000020
DEPTNO
-----A00
B01
DEPTNAME
----------------------------SPIFFY COMPUTER SERVICE DIV.
PLANNING
MGRNO
-----000010
000020
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 140
TOPIC
08 36 WITH HOLD 커서
01
 COMMIT 후에도 커서의 현재 위치를 유지하려면 커서를 선언할 때 WITH HOLD 옵션을 사용합니다.
 대량의 데이터를 처리할 때, 일정한 건수 별로 COMMIT 을 실행함으로써, 전체 UOW 의 크기를 줄일 수 있습니다.
 커서를 CLOSE 하면 커서의 현재 위치는 유실됩니다.
WORSE
EXEC SQL DECLARE c1 CURSOR FOR
SELECT projno, prstdate, prendate
FROM project
WHERE deptno = 'D11';
EXEC SQL OPEN c1;
do {
EXEC SQL FETCH c1 INTO :v1, :v2. :v3;
if (SQLCODE != 0) break;
EXEC SQL UPDATE project
SET prenddate = CURRENT DATE
WHERE projno = :v1;
} while ( 1 );
EXEC SQL CLOSE c1;
EXEC SQL COMMIT;
BETTER
EXEC SQL DECLARE c1 CURSOR WITH HOLD FOR
SELECT projno, prstdate, prendate
FROM project
WHERE deptno = 'D11';
EXEC SQL OPEN c1;
I = 0;
do {
EXEC SQL FETCH c1 INTO :v1, :v2. :v3;
if (SQLCODE != 0) break;
EXEC SQL UPDATE project
SET prenddate = CURRENT DATE
WHERE projno = :v1;
i++;
if (i == 500) {
EXEC SQL COMMIT;
i = 0;
}
} while ( 1 );
EXEC SQL CLOSE c1;
EXEC SQL COMMIT;
U D B 개 발 자 기 본 교 육 • UNIT 08 • SQL 고려 사항 141
TOPIC
09
01
UNIT09
익스플레인
UDB개발자기본교육
SQL 컴파일러
통계 자료 갱신
익스플레인 도구
액세스 플랜의 기본 형식
데이터 액세스 유형과 기법
단일 테이블 액세스 유형
Table Scan
Matching Index Scan
Non-matching Index Scan
One Fetch Access
Index Only Access
다중 Index Access
IN List Index Access
Sequential Prefetch
List Prefetch
Index ORing
Index ANDing
다중 테이블 액세스 유형
Cartesian Product
Nested Loop 조인
Merge Scan 조인
Hash 조인
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 142
TOPIC
09 01 SQL 컴파일러
01
1
DB2는 시스템 카탈로그에 저장된 여러가지 통계 자료와 구성 변수값을 이용하여 비용 기반 (Cost-based)의 Optimizer를 이용하여 요청된 SQL
2
옵티마이저가 내부적으로 여러 단계를 수행하여 입력된 SQL문을 컴파일하
문에 대한 최소 비용의 액세스 플랜을 선택합니다.
고, 실행할 수 있는 액세스 플랜을 생성하는 과정을 SQL 컴파일이라고 합니
다. 이 과정에서 필요에 따라 요청된 SQL문을 보다 효율적인 SQL문으로 재
작성하기도 합니다.
3
4
5
옵티마이저는 다음과 같은 정보를 고려합니다.

테이블, 컬럼, 인덱스에 대한 통계 정보

CPU 처리 속도, DISK I/O 속도, 통신 대역폭, 병렬 처리 가능 여부

버퍼풀과 sortheap 의 크기

동시 사용자수, Isolation level, blocking, lock 관련 구성 정보 등
최종적으로 생성된 Access plan 에는 다음과 같은 정책이 포함됩니다.

데이터 액세스 방법으로 테이블 스캔 또는 인덱스 스캔이 결정됩니다.

어떤 인덱스가 사용될 것인지를 결정하며, 다양한 인덱스 스캔 옵션이
선택됩니다.

조인의 방법과 순서가 결정됩니다.
정적 SQL문에 대한 Access plan은 팩키지로 생성되어 데이터베이스에 저
장되고, 동적 SQL문에 대한 액세스 플랜은 실행시에 팩키지 캐쉬에 저장됩
니다.
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 143
TOPIC
09 01 SQL 컴파일러
01
6
SQL 컴파일러가 실행하는 각 과정에 대한 설명은 다음과 같습니다.
과정
설명
쿼리 구문 분석 (Parse Query)
SQL 쿼리를 분석하여 구문의 유효성을 확인합니다. 구문 오류가 검출되면, 처리를 중단하고
해당 SQL 오류를 리턴합니다. 쿼리 구문 분석이 완료되면, 쿼리에 대한 내부적인 표현이
QGM(Query Graph Model)에 작성되고 저장됩니다.
의미 점검 (Check Sementics)
명령문의 각 부분에 의미상 불일치되는 부분이 있는지 확인합니다. 참조 제한 조건, 테이블 점
검 제한 조건, 트리거와 뷰 등의 작동 의미를 QGM에 추가합니다. QGM은 쿼리 블록, 서브쿼
리, 상관 관계, 파생된 테이블, 표현식, 데이터 유형, 데이터 유형 변환, 코드 페이지 변환, 파티
션 키를 포함한 쿼리에 대한 모든 의미를 기록합니다. 의미 점검의 예로 YEAR 스칼라 함수에서
인수로 지정된 컬럼의 데이터 유형이 날짜 시간 데이터 유형인지 확인하는 것을 들 수 있습니
다.
쿼리 재작성 (Rewrite Query)
QGM에 저장된 여러 가지 정보를 이용하여 쿼리를 최적화된 형식으로 변환하여 QGM에 저장
합니다.
푸쉬다운 분석 (Pushdown Anaysis)
SQL문을 실행하는데 필요한 조작을 Federated 된 데이터 소스에서 원격으로 평가할 수 있는
지 또는 푸시다운 하는지 여부를 분석합니다.
액세스 플랜 최적화 (Optimize Access
Plan)
QGM에 저장된 정보를 기반으로 쿼리의 의미, 인덱스, 기본 테이블, 파생된 테이블, 서브쿼리,
상관 관계 등을 분석하고, 입력된 SQL문을 실행할 수 있는 다양한 액세스 플랜을 생성합니다.
옵티마이저는 시스템 카탈로그의 통계 자료를 이용하여 실행 비용을 측정하고, 생성된 액세스
플랜 중에서 최소 비용의 액세스 플랜을 선택합니다. 액세스 플랜에는 테이블의 액세스 순서,
사용할 인덱스 선택, 조인 방법, 액세스 유형 등이 포함됩니다.
원격 SQL 생성 (Generate Remote SQL)
선택한 액세스 플랜이 Federated 된 데이터 소스에서 작동할 수 있는 단계 세트로 구성되어
야 하는 경우에는 데이터 소스 SQL dialect를 기본으로 하여 효율적인 SQL문을 작성합니다.
실행 코드 생성 (Generate Executable)
선택된 액세스 플랜과 QGM을 사용하여 쿼리에 대한 실행 액세스 플랜과 섹션을 작성합니다.
정적 SQL문에 대한 액세스 플랜은 데이터베이스의 시스템 카탈로그 테이블에 패키지로 저장
되고, 동적 SQL문에 대한 액세스 플랜은 패키지 캐시에 저장됩니다.
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 144
TOPIC
09 02 통계 자료 갱신
01
1
2
3
옵티마이저가 액세스 플랜을 결정할 때는 시스템 카탈로그에 저장된 각종 통계 정보를 이용합니다. 효율적인 액세스 플랜을 생성하려면
테이블과 인덱스 등에 대한 통계 자료를 정확하게 관리하는 것이 중요합니다. 다음과 같은 경우에 runstats 명령어를 이용하여 통계 정보를
갱신하도록 합니다.

새로운 인덱스가 추가된 경우

테이블 데이터의 10% 이상이 변경된 경우

REORG, LOAD, 대량 데이터의 IMPORT, MQT 생성 등의 작업이 실행된 경우

데이터베이스 구성 변수 등이 변경된 경우
테이블과 인덱스에 대해 다음 정보를 수집합니다.

테이블과 인덱스에 할당된 page 수

테이블과 인덱스에서 사용 중인 page 수

테이블에서 Overflow가 발생한 데이터 건수

테이블의 데이터 건수
RUNSTATS
REBIND
테이블의 각 컬럼과 인덱스의 첫 번째 컬럼에 대해 다음 정보를 수집합니다.

각 컬럼에서 구별되는 값의 개수

각 컬럼의 평균 길이

각 컬럼별에서 두 번째로 큰 값

각 컬럼에서 두 번째로 작은 값

각 컬럼에서 NULL값을 가진 행의 수
REORGCHK
REORG
REORG NEEDED?
NO
APPLICATION
YES
RUNSTATS
REBIND
EXECUTION
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 145
TOPIC
09 02 통계 자료 갱신
01
4
5
인덱스에 대해 수집되는 통계 정보는 다음과 같습니다.

인덱스 leaf page 수

인덱스 search tree의 레벨

인덱스의 clustering 정도

인덱스키의 첫 번째 컬럼의 값으로 구별되는 값의 개수, 처음 두 개의 컬럼을 결합한 값으로 구별되는 값의 개수, 처음 세 개의 컬럼을
결합한 값으로 구별되는 값의 개수, 처음 네 개의 컬럼을 결합한 값으로 구별되는 값의 개수, 인덱스키의 모든 컬럼의 값을 결합한 값으로
구별되는 값의 개수

할당된 page에 대한 사용 중인 page의 비율

인점한 page와 gap이 크지 않은 leaf page의 비율

인덱스의 leaf page에서 모든 RID가 DELETE로 표시된 page 수

인덱스의 leaf page에서 모든 행이 DELETE되지 않은 page에 있는 RID 중에서 DELETE로 표시된 RID 개수
자주 사용되는 runstats 명령어는 다음과 같습니다.
RUNSTATS ON TABLE kes.t1
RUNSTATS ON TABLE kes.t1 FOR INDEXES ALL
RUNSTATS ON TABLE kes.t1 AND INDEXES ALL
RUNSTATS ON TABLE kes.t1 WITH DISTRIBUTION AND DETAILED INDEXES ALL
RUNSTATS ON TABLE kes.t1 ON KEY COLUMNS AND INDEXES ALL
RUNSTATS ON TABLE kes.t1 ON COLUMNS (c1, (c2, c3), c4 LIKE STATISTICS) AND INDEXES ALL
RUNSTATS ON TABLE kes.t1 WITH DISTRIBUTION ON COLUMNS (c5 NUM_FREQVALUES 20 NUM_QUANTILES 40) AND INDEXES ALL
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 146
TOPIC
09 03 익스플레인 도구
01
1
SQL 컴파일러가 생성한 액세스 플랜을 확인하는 익스플레인 도구에는 GUI기반의 Visual Explain와 텍스트 기반의 db2exfmt, db2expln 등의
유틸리티가 있습니다. 익스플레인 정보는 쿼리 처리를 위한 조작 시퀀스, 비용 정보, 사용된 predicate 및 Filtering factor 값, SQL문에서 참조
된 모든 오브젝트에 대한 통계 정보 등을 포함하므로, 개별 SQL 명령문의 실행 방법을 파악과 성능 향상을 위한 SQL문의 변경 또는 실행 환경 조
2
절에 도움을 줄 수 있습니다.
db2expln 명령어는 인덱스 액세스 여부,사용된 인덱스, 조인
의 방법 등의 간단한 액세스 플랜과 쿼리의 실행 비용을 확인
특성
하는 데 주로 사용됩니다. 옵티마이저에 대한 자세한 정보는
3
표시하지 않습니다.
db2exfmt 명령어는 익스플레인 테이블의 내용을 정해진 형
GUI 출력
식의 텍스트로 생성하는 도구입니다. db2expln 명령어의 실
텍스트 출력
행 결과를 포함한 상세한 액세스 플랜 정보와 옵티마이저에
대한 정보를 확인하는데 사용됩니다. Prefetch 방식, 인덱스
Explain
테이블
Visual
Explain
db2exfmt
db2expln
O
O
O
'Quick and Dirty'
정적 SQL문 분석
O
액세스 방향, filtering factor 값 등의 상세한 정보를 확인할
4
때 유용합니다.
제어 센터에서 실행되는 Visual Explain은 GUI 방식으로 익
스플레인 정보를 제공합니다. db2exfmt 명령어와 동일한 정
보를 제공합니다.
5
익스플레인 테이블은 SQL 컴파일 과정에서 생성되는 정보를
보관합니다. Visual Explain 또는 db2exfmt 유틸리티를 사용
하려면, 익스플레인 테이블을 미리 생성하여야 합니다. 생성
스크립트는 인스턴스 사용자의 홈디렉토리에 있는
sqllib/misc/EXPLAIN.DDL 입니다.
$ login <인스턴스 사용자>
$ db2 connect to <DB명>
$ db2 -tvf $HOME/sqllib/misc/EXPLAIN.DDL
지원되는 정적 SQL
O
O
O
O
지원되는 동적 SQL
O
O
O
O
지원되는 CLI 응용프로
그램
O
O
O
DRDA Application
Requester 지원
O
상세 옵티마이저 정보
O
O
O
다중 명령문 분석
O
응용프로그램 내에서 액
세스 가능한 정보
O
O
O
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 147
TOPIC
09 03 익스플레인 도구
01
6
Visual Explain 의 실행 예는 다음과 같습니다.
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 148
TOPIC
09 03 익스플레인 도구
01
7
db2expln의 실행 예는 다음과 같습니다.
$ db2expln -d sample -q "select * from kes.empl where id=1" -t -g
============== STATEMENT ===========================
Isolation Level
= Cursor Stability
Blocking
= Block Unambiguous Cursors
Query Optimization Class = 5
Partition Parallel
= No
Intra-Partition Parallel
= No
SQL Path = "SYSIBM", "SYSFUN", "SYSPROC", "POST01"
SQL Statement:
select name
from kes.empl
where id =1
Estimated Cost = 12.869981
Estimated Cardinality = 1.000000
(
2) Access Table Name = KES.EMPL ID = 2,15
| Index Scan: Name = KES.EMPL_PK01 ID = 1
| | Regular Index (Not Clustered)
| | Index Columns:
| | | 1: ID (Ascending)
| #Columns = 7
| Single Record
| Fully Qualified Unique Key
| #Key Columns = 1
| | Start Key: Inclusive Value
| | | | 1: 1
(
(
| | Stop Key: Inclusive Value
| | | | 1: 1
| Data Prefetch: Eligible 0
| Index Prefetch: None
| Lock Intents
| | Table: Intent Share
| | Row : Next Key Share
| Sargable Predicate(s)
2) | | Return Data to Application
| | | #Columns = 7
1) Return Data Completion
End of section
Optimizer Plan:
RETURN
( 1)
|
FETCH
( 2)
/
\
IXSCAN Table:
( 2)
KES
|
EMPL
Index:
KES
EMPL_PK01
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 149
TOPIC
09 03 익스플레인 도구
01
8
db2exfmt의 실행 예는 다음과 같습니다.
$ db2 set current explain mode EXPLAIN
$ db2 "select * from kes.empl where name = ‘MARIA’"
$ db2exfmt -d sample -g TIC -w -1 -n % -s % -# 0 –t
Original Statement:
-----------------select *
from kes.empl
where name = 'MARIA'
Access Plan:
----------Total Cost:
Query Degree:
Rows
RETURN
( 1)
Cost
I/O
|
743.226
TBSCAN
( 2)
429.993
227
|
23040
TABLE: KES
EMPL
429.993
1
2) TBSCAN: (Table Scan)
Cumulative Total Cost:
429.993
Cumulative CPU Cost:
5.10532e+007
Cumulative I/O Cost:
227
. . .
Arguments:
--------MAXPAGES: (Maximum pages for prefetch)
ALL
PREFETCH: (Type of Prefetch)
SEQUENTIAL
ROWLOCK : (Row Lock intent)
NEXT KEY SHARE
SCANDIR : (Scan Direction)
FORWARD
TABLOCK : (Table Lock intent)
INTENT SHARE
TBISOLVL: (Table access Isolation Level)
CURSOR STABILITY
Predicates:
---------2) Sargable Predicate
Relational Operator:
Equal (=)
Subquery Input Required:
No
Filter Factor:
0.0322581
Predicate Text:
-------------(Q1."NAME" = 'MARIA')
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 150
TOPIC
09 04 액세스 플랜 기본 형식
01
1
EXPLAIN INSTANCE 항목에는 익
스플레인을 실행한 시간과 사용자
명 등의 기본적인 정보가 표시됩
니다.
3
Package Context 항목에는 익
스플레인의 대상이 되는 팩키지명
과 생성시의 옵션값이 표시됩니
다.
$ db2exfmt -d sample -g TIC -w -1 -n % -s % -# 0 –t
******************** EXPLAIN INSTANCE ********************
EXPLAIN_TIME:
2006-05-22-16.29.01.594001
EXPLAIN_REQUESTER:
KR000663
2
Database Context:
---------------Parallelism:
CPU Speed:
Comm Speed:
Buffer Pool size:
Sort Heap size:
Database Heap size:
Lock List size:
Maximum Lock List:
Average Applications:
Locks Available:
None
3.778754e-007
0
250
256
600
50
22
1
1122
Package Context:
--------------SQL Type:
Optimization Level:
Blocking:
Isolation Level:
Dynamic
5
Block All Cursors
Cursor Stability
---------------- STATEMENT
QUERYNO:
QUERYTAG:
Statement Type:
Updatable:
Deletable:
Query Degree:
1 SECTION 201 ---------------33
CLP
Select
No
No
1
Database Context 항목에는
SQL문 컴파일에 이용되는 데이터
베이스 구성 변수의 현재 설정값
과 버퍼풀의 크기 등이 표시됩니
다.
4
STATEMENT와 SECTION 항목에
는 STATEMENT 번호, SECTION 번
호, SQL문의 유형 등이 표시됩니
다.
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 151
TOPIC
09 04 액세스 플랜 기본 형식
01
5
Original Statement 항목에는 입
력된 원래의 SQL문이 표시됩니다.
Original Statement:
------------------
select name
from kes.empl
where id=1
Optimized Statement:
-------------------
SELECT Q1."NAME" AS "NAME"
FROM KES.EMPL AS Q1
WHERE (Q1."ID" = 1)
7
Access Plan 항목에는 access
Access Plan:
path가 tree 형태로 표시됩니다.
Total Cost:
12.87
Query Degree: 1
Rows
RETURN
( 1)
Cost
I/O
|
1
FETCH
( 2)
12.87
1
/----+---\
1
4
IXSCAN TABLE: KES
( 3)
EMPL
0.0155141
0
|
4
INDEX: KES
EMPL_PK01
전체 실행 비용과 병렬 처리 여부
를 알 수 있으며, tree를 구성하는
각 항목은 I/O 비용, 실행 비용, 처
리 순번, operation명, 반환된 건
수 등을 포함합니다. 실행 일련 번
호의 역순으로 아래쪽부터 위쪽
방향으로 해석합니다.
6
Optimized Statement 항목에는
옵티마이저가 SQL문 컴파일 과정
에서 재작성한 SQL문이 표시됩니
다.
-----------
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 152
TOPIC
09 04 액세스 플랜 기본 형식
01
8
Plan Details 항목에는 access
path tree에 표시된 각
operation 에 대한 상세 정보가
표시됩니다.
Plan Details:
------------1) RETURN: (Return Result)
Cumulative Total Cost:
...
2) FETCH : (Fetch)
Cumulative Total Cost:
...
3) IXSCAN: (Index Scan)
Cumulative Total Cost:
Cumulative CPU Cost:
Cumulative I/O Cost:
Cumulative Re-Total Cost:
Cumulative Re-CPU Cost:
Cumulative Re-I/O Cost:
Cumulative First Row Cost:
Estimated Bufferpool Buffers:
10
Arguments 항목은 3) IXSCAN
항목에서 사용된 인덱스 스캔에
대한 특성을 표시합니다.
Prefetch 사용 여부와 인덱스 스
캔의 방향 등이 포함됩니다.
12.87
12.87
0.0155141
41056
0
0.00211421
5595
0
0.0155141
1
Arguments:
--------MAXPAGES: (Maximum pages for prefetch)
ALL
PREFETCH: (Type of Prefetch)
NONE
ROWLOCK : (Row Lock intent)
NEXT KEY SHARE
SCANDIR : (Scan Direction)
FORWARD
TABLOCK : (Table Lock intent)
INTENT SHARE
9
3) IXSCAN 항목은 access path
tree 에서 처리 순번이 (3) 으로 표
시된 인덱스 스캔에 대해 상세하
게 설명합니다. Cumulative I/O
Cost 값으로 표시된 것은 I/O 비용
이고, Cumulative Total Cost 값
으로 표시된 것은 실행 비용입니
다.
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 153
TOPIC
09 04 액세스 플랜 기본 형식
01
11
Predicates 항목은 3) IXSCAN 항목에서 검색 조건식
으로 사용된 predicates의 특성을 설명합니다. 예에서,
조건식으로 사용된 (ID=1)은 range delimiting
predicates입니다. (startkey,stopkey)=(1,1)로 판별
되어 matching index scan이 가능합니다. Filter
Factor 값은 0.25이므로 해당 테이블의 데이터 중에서
25%가 반환되는 것으로 예측됩니다.
Predicates:
---------2) Start Key Predicate
Relational Operator:
Subquery Input Required:
Filter Factor:
Equal (=)
No
0.25
Predicate Text:
-------------(Q1."ID" = 1)
2) Stop Key Predicate
Relational Operator:
Subquery Input Required:
Filter Factor:
Equal (=)
No
0.25
Predicate Text:
-------------(Q1."ID" = 1)
12
Input Streams 항목은 3) IXSCAN 항목에서 인덱스
스캔 중에 검색된 인덱스키에 대한 정보를 표시합니
다. 예에서, 인덱스 KES.EMPL_PK01에서 인덱스키로
사용된 ID 컬럼과 해당되는 RID가 검색되었고, 총 4건
이 존재하는 것으로 예측되었습니다.
Input Streams:
------------1) From Object KES.EMPL_PK01
Estimated number of rows: 4
Number of columns:
2
Subquery predicate ID: Not Applicable
Column Names:
-----------+Q1.$RID$+Q1."ID"
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 154
TOPIC
09 04 액세스 플랜 기본 형식
01
13
Output Streams 항목은 3) IXSCAN 항목에서 인덱
스 스캔 후의 정보를 표시합니다. 예에서, 조건에 맞는
데이터가 1건이 검색되어 상위 operator 에게 전달됩
니다. Operator #2는 2) FETCH 입니다. 반환되는
데이터 건수가 많은 operator 를 중점적으로 분석하
도록 합니다.
14
Objects Used in Access Plan 항목은 액세스 플랜에
사용된 테이블과 인덱스에 대한 정보를 표시합니다.
예에서, 인덱스 KES.EMPL_PK01과 테이블 KES.EMPL
이 사용되었습니다. 옵티마이저가 SQL 컴파일시에 참
고한 통계 자료도 함께 표시됩니다.
Output Streams:
-------------2) To Operator #2
Estimated number of rows: 1
Number of columns:
0
Subquery predicate ID: Not Applicable
Objects Used in Access Plan:
--------------------------Schema: KES
Name:
EMPL_PK01
Type:
Index
Time of creation: 2006-05-22-14.02.58.864000
Last statistics update:
Number of columns:
1
Number of rows:
4
...
Index clustering statistic:
20.000000
Index leaf pages:
1
Index tree levels:
1
...
Schema: KES
Name:
EMPL
Type:
Table
Time of creation: 2006-05-22-14.02.58.804001
Last statistics update:
Number of columns:
7
Number of rows:
4
Width of rows:
37
...
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 155
TOPIC
09 04 액세스 플랜 기본 형식
01
15
액세스 플랜에 사용되는 주요 operator 의 종류는 다음과 같습니다.
연산자
설명
TBSCAN
데이터 페이지에서 직접 필요한 모든 데이터를 읽어 행을 검색합니다.
IXSCAN
테이블의 인덱스를 스캔하여 일련의 순서화된 행을 산출합니다.
HSJOIN
둘 이상의 테이블이 조인 컬럼에서 해시된 해시 조인을 표시합니다.
MSJOIN
병합 조인으로 외부 및 내부 테이블이 모두 조인-술어 순서로 되어야 합니다.
NLJOIN
중첩 루프 조인으로 외부 테이블 행마다 한 번씩 내부 테이블에 액세스합니다.
INSERT / DELETE / UPDATE
테이블에서 행을 추가 / 삭제 / 갱신합니다.
FETCH
인덱스에서 검색된 RID를 사용하여 테이블에서 컬럼을 페치합니다.
FILTER
한 개 이상의 조건으로 데이터를 필터합니다.
GRPBY
지정된 컬럼과 함수의 공통값에 따라 행을 구분하고, 집합 함수를 평가합니다.
RIDSCN
한 개 이상의 인덱스로부터 얻어진 일련의 행 ID(RID)를 스캔합니다.
SORT
지정된 컬럼의 순서로 행을 정렬하며, 중복된 항목을 제거할 수 있습니다.
IXAND
두 개 이상의 인덱스를 스캔하여 나온 RID에 대해 AND 작업을 수행합니다.
UNIQUE
특정 컬럼에 대해 중복된 값을 가진 행을 제거합니다.
TEMP
여러 번 다시 읽을 수 있도록 데이터를 임시 테이블에 저장합니다.
TQUEUE
데이터베이스 에이전트들 사이에 테이블 데이터를 전송합니다.
UNION
여러 테이블의 행을 이어 붙입니다.
RETURN
쿼리로부터 사용자에게 데이터를 리턴함을 의미합니다.
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 156
TOPIC
09 05 데이터 액세스 유형과 기법
01
1
SQL문의 조건절을 평가하여 데이터를 액세스하는 방법에는 table scan과 Index scan 이 있습니다. Index Scan은 검색 방법에 따라 다음과 같
이 분류됩니다.
방법
2
Scan 대상
추가적인 access 기법
One Fetch Access
Index
Index Only Access
Index
Matching Index Scan
Index
Sequential Prefetch를 이용한 Index Scan
Index
Sequential prefetch
List Prefetch를 이용한 Index Scan
Index
List Prefetch
다중 Index Access
Index
Index ORing, Index ANDing
Non-matching Index Scan
Index
Table Scan
Table
Better
Worse
효율적인 데이터 액세스를 위해 다음과 같은 Access 기법이 지원됩니다.다중 테이블을 액세스를 위한 Join 기법은 다음과 같습니다.
3

Sequential Prefetch

Nested Loop 조인

List Prefetch

Merge Scan 조인

Index ORing

Hash 조인

Index ANDing
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 157
TOPIC
09 06 단일 테이블 액세스 플랜 유형
01
1
단일한 테이블을 액세스하는 쿼리에 대한 액세스 플랜은 테이블을 직접 액세스하는 table scan과 인덱스를 이용하여 테이블을 액세스하는
2
Index scan은 다음과 같은 다양한 액세스 path를 선택하게 됩니다.
index scan 으로 구별됩니다.

Prefetch를 사용하지 않는 일반적인 인덱스
스캔

Sequential prefetch를 이용하는 인덱스
스캔

List prefetch를 이용하는 인덱스 스캔

Index Oring을 이용하는 인덱스 스캔

Index ANDing를 이용하는 인덱스 스캔
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 158
TOPIC
09 07 Table Scan
01
1
2
인덱스를 사용하지 못하고 Table 전체를 Scan하는 방법입니다.

검색 조건에 맞는 적절한 Index가 없는 경우에 선택됩니다.

일반적으로 인덱스를 이용하는 것보다 I/O 가 많아져서 성능이 저하됩니다.

적절한 인덱스가 있더라도 인덱스의 cluster율이 낮거나, Table의 크기가 작은 경우에는 table을 scan 하는 것이 더 효율적인 것으로
선택될 수도 있습니다.
다음과 같은 경우입니다.
SELECT *
FROM
kes.t1
WHERE c2 = ‘MARIA'
(c1)로 UNIQUE 인덱스만
있고, (c2)에 대한 인덱스
가 없다면, table scan을
실행해야 합니다.
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 159
TOPIC
09 07 Table Scan
01
3
테이블을 스캔을 사용하는 SQL문에 대한 익스플레인 예입니다. 사용된 조건식은 Data-Sargable predicate 유형이며, Sequential prefetch
4
사용자가 입력한 원래의 SQL문입니다. 조
를 이용한 테이블 스캔이 이용되었습니다.
건식 (name=‘MARIA’)에 사용된 컬럼인
(name)에 대한 인덱스가 없다고 가정하
겠습니다.
Original Statement:
-----------------select *
from kes.empl
where name = 'MARIA'
Access Plan:
----------Total Cost:
Query Degree:
6
실행 순번 2에 해당하는 <Operator #2>의
연산자는 TBSCAN으로 Table scan 이 선
택된 것을 표시합니다. 예측된 I/O 비용은
227, 실행 비용은 429.993, 반환되는 건수
는 743.226건입니다.
Rows
RETURN
( 1)
Cost
I/O
|
743.226
TBSCAN
( 2)
429.993
227
|
23040
TABLE: KES
EMPL
429.993
1
5
실행 비용은 429.993 이며, 병렬
7
사용된 테이블은 KES.EMPL 이며,
처리는 발생하지 않았습니다.
현재 데이터는 23040건입니다.
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 160
TOPIC
09 07 Table Scan
01
8
테이블 스캔시에 Sequential
prefetch가 사용되었습니다.
2) TBSCAN: (Table Scan)
Cumulative Total Cost:
429.993
Cumulative CPU Cost:
5.10532e+007
Cumulative I/O Cost:
227
. . .
Arguments:
--------MAXPAGES: (Maximum pages for prefetch)
ALL
PREFETCH: (Type of Prefetch)
SEQUENTIAL
ROWLOCK : (Row Lock intent)
NEXT KEY SHARE
SCANDIR : (Scan Direction)
FORWARD
TABLOCK : (Table Lock intent)
INTENT SHARE
TBISOLVL: (Table access Isolation Level)
CURSOR STABILITY
Predicates:
---------2) Sargable Predicate
Relational Operator:
Equal (=)
Subquery Input Required:
No
Filter Factor:
0.0322581
10
Filtering에 사용된 실제 조건식은
9
조건식은 = 연산자를 사용하는
Data Sargable predicate 이며,
Filter Factor는 0.0322581 입니
다.
Predicate Text:
-------------(Q1."NAME" = 'MARIA')
(NAME=‘MARIA’) 입니다.
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 161
TOPIC
09 07 Table Scan
01
11
테이블 스캔에 사용된 테이블명은
KES.EMPL 입니다.
Input Streams:
------------1) From Object KES.EMPL
Estimated number of rows:
23040
Number of columns:
6
Subquery predicate ID:
Not Applicable
12
테이블 KES.EMPL에서 23040건의
데이터가 있으며, RID를 포함하여
6개의 컬럼을 가져옵니다.
Column Names:
-----------+Q1.$RID$+Q1."SALARY"+Q1."HIREDATE"
+Q1."WORKDEPT"+Q1."EMPNO"+Q1."NAME"
Output Streams:
-------------2) To Operator #1
Estimated number of rows:
743.226
Number of columns:
5
Subquery predicate ID:
Not Applicable
13
예측되는 반환 건수는 743.226 건
이고, 반환 컬럼의 개수는 5개입니
다.
Column Names:
-----------Q2."SALARY"+Q2."HIREDATE"+Q2."WORKDEPT"
+Q2."NAME"+Q2."EMPNO"
Objects Used in Access Plan:
--------------------------Schema: KES
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 162
TOPIC
09 08 Matching Index Scan
01
1
인덱스의 일정 구간만을 Scan하는 방법입니다.
 검색 조건에 맞는 적절한 Index가 있고, 인덱스 Search Tree를 사용하여 조건에 맞는 데이터를 검색하기 위한 시작 Leaf Page를 찾을
수 있는 경우입니다.
 Range-Delimiting Predicates를 사용하는 경우에 선택됩니다.
2
다음과 같은 경우입니다.
SELECT
C2, C5
FROM
T1
WHERE C1 = 130;
(C1) 으로 시작되는 인덱
스가 있다면, 조건식
(C1=130) 은 Matching
Column 입니다.
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 163
TOPIC
09 08 Matching Index Scan
01
3
조건절에서 인덱스 컬럼에 대한 시작 시점과 끝 시점이 명시되어 있는 경우에 인덱스의 일부분만 스캔하여 원하는 데이터를 검색하는 예입니다.
사용된 조건식은 Range Delimiting predicate 유형이므로 matching index scan이 가능합니다.
Original Statement:
-----------------select empno, name
from kes.empl
where empno between 13000 and 13010
Optimized Statement:
------------------SELECT Q1."EMPNO" AS "EMPNO",
Q1."NAME" AS "NAME"
FROM KES.EMPL AS Q1
WHERE (Q1."EMPNO" <= 13010)
AND (13000 <= Q1."EMPNO")
4
사용자가 입력한 원래의 SQL
문에는 BETWEEN이 사용되
었습니다.
5
옵티마이저는 AND 연산자
를 이용한 두 개의 조건식으
로 SQL문을 재작성하였습
니다.
6
실행 순번 3에 해당하는 <Operator #3>의
연산자는 IXSCAN으로 index scan 이 선
택된 것을 표시합니다. 예측된 I/O 비용은
1, 실행 비용은 12.8874, 반환되는 건수는
11.0001건입니다.
7
인덱스 스캔에 사용된 인덱스는
KES.EMPL_PK01 입니다.
Access Plan:
----------Total Cost:
Query Degree:
25.7463
1
Rows
RETURN
( 1)
Cost
I/O
|
11.0001
FETCH
( 2)
25.7463
2
/---+---\
11.0001
23040
IXSCAN TABLE: KES
( 3)
EMPL
12.8874
1
|
23040
INDEX: KES
EMPL_PK01
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 164
TOPIC
09 08 Matching Index Scan
01
3) IXSCAN: (Index Scan)
Cumulative Total Cost:
12.8874
Cumulative CPU Cost:
88008.9
Cumulative I/O Cost:
1
Cumulative Re-Total Cost:
0.0180875
Cumulative Re-CPU Cost:
42547.9
Cumulative Re-I/O Cost:
0
Cumulative First Row Cost:
12.8794
Estimated Bufferpool Buffers: 2
8
10
인덱스 스캔시에 Prefetch는
사용되지 않았습니다.
Range Delimiting predicate
의 stop key는 <= 연산자를 사
용하며, Filter Factor 는
0.56467 입니다.
Arguments:
--------MAXPAGES: (Maximum pages for prefetch)
1
PREFETCH: (Type of Prefetch)
NONE
ROWLOCK : (Row Lock intent)
NEXT KEY SHARE
SCANDIR : (Scan Direction)
FORWARD
TABLOCK : (Table Lock intent)
INTENT SHARE
9
인덱스 스캔은 순방향으로
11
인덱스 스캔시의 중단 시점
실행되었습니다.
Predicates:
---------2) Stop Key Predicate
Relational Operator:
Less Than or Equal (<=)
Subquery Input Required:
No
Filter Factor:
0.56467
Predicate Text:
-------------(Q1."EMPNO" <= 13010)
을 판별하는 stop key로 사
용된 조건식은
(EMPNO<=13030) 입니다.
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 165
TOPIC
09 08 Matching Index Scan
01
12
Range Delimiting predicate
의 Start key는 <= 연산자를 사
용하며, Filter Factor 는
0.435807입니다.
3) Start Key Predicate
Relational Operator:
Less Than or Equal (<=)
Subquery Input Required:
No
Filter Factor:
0.435807
Predicate Text:
-------------(13000 <= Q1."EMPNO")
14
사용된 인덱스명은
KES.EMPL_PK01 입니다.
13
Input Streams:
------------1) From Object KES.EMPL_PK01
인덱스 스캔시의 시작 시점
을 판별하는 start key로 사
용된 조건식은
(13000<=EMPNO) 입니다.
Estimated number of rows:
23040
Number of columns:
2
Subquery predicate ID:
Not Applicable
15
인덱스 KES.EMPL_PK01에는
23040건의 데이터가 있으며, RID
를 포함하여 2개의 컬럼을 가져옵
니다.
Column Names:
-----------+Q1."EMPNO"(A)+Q1.$RID$
Output Streams:
-------------2) To Operator #2
16
예측되는 반환 건수는 11.0001건
이고, 반환 컬럼의 개수는 1개입니
다. 비정규 분포를 가지는 테이블
에 대한 Range 검색의 에측 반환
건수는 frequecy과 quantile 정
보를 이용하여 계산됩니다.
Estimated number of rows:
11.0001
Number of columns:
1
Subquery predicate ID:
Not Applicable
Column Names:
-----------+Q1."EMPNO"(A)
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 166
TOPIC
09 09 Non-matching Index Scan
01
1
인덱스의 Leaf Page 전체를 Scan하는 방법입니다.
 조건식에 사용된 컬럼이 인덱스에 포함된 컬럼이므로 시작 Leaf Page를 찾을 수는 없지만, 인덱스를 사용하여 검색이 가능한
경우입니다.
 Index-Sargable Predicates를 사용하는 경우에 선택됩니다.
 Cluster율이 낮은 인덱스 scan시에 RID를 sort 하여 table을 액세스합니다.
2
다음과 같은 경우입니다.
SELECT
C1, C3, C5
FROM
T1
WHERE C2 = 1
AND
C3 > 0
(C1,C2,C3)로 구성된 인덱
스가 있을 때, Matching
Column은 없지만, 인덱스
를 스캔하여 조건에 맞는 값
을 검색하는 것이 가능합니
다.
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 167
TOPIC
09 09 Non-matching Index Scan
01
3
조건절에 인덱스키에 포함된 컬럼이 명시되어 있는 경우에 인덱스 전체를 스캔하여 원하는 데이터를 검색하는 예입니다. (workdept, hiredate,
empno)로 구성된 인덱스가 있다고 할 때, 예에서 사용된 조건식은 Index Sargable predicate 유형으로 Non-matching index scan에 해당
됩니다.
Original Statement:
-----------------select empno, workdept, salary
from kes.empl
where workdept = 'D01' and empno < 10
Optimized Statement:
------------------SELECT Q1."EMPNO" AS "EMPNO",
'D01' AS "WORKDEPT",
Q1."SALARY" AS "SALARY"
FROM KES.EMPL AS Q1
WHERE (Q1."EMPNO" < 10)
AND
(Q1."WORKDEPT" = 'D01')
4
사용자가 입력한 원래의 SQL
문에는 BETWEEN이 사용되
었습니다.
5
옵티마이저는 AND 연산자
로 연결된 두 개의 조건식의
순서가 변경되도록 SQL문
을 재작성하였습니다.
6
연산자는 IXSCAN으로 index scan 이 사
용되었으며, 예측된 I/O 비용은 23.5372,
실행 비용은 122.587, 반환되는 건수는
1.125건입니다.
7
인덱스 스캔에 사용된 인덱스는
KES.EMPL_IX04 입니다.
Access Plan:
----------Total Cost:
Query Degree:
137.017
1
Rows
RETURN
( 1)
Cost
I/O
|
1.125
FETCH
( 2)
137.017
24.6597
/---+---\
1.125
23040
IXSCAN TABLE: KES
( 3)
EMPL
122.587
23.5372
|
23040
INDEX: KES
EMPL_IX04
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 168
TOPIC
09 09 Non-matching Index Scan
01
3) IXSCAN: (Index Scan)
Cumulative Total Cost:
122.587
Cumulative CPU Cost:
6.43672e+006
Cumulative I/O Cost:
23.5372
Cumulative Re-Total Cost:
2.65613
Cumulative Re-CPU Cost:
6.24811e+006
Cumulative Re-I/O Cost:
0
Cumulative First Row Cost:
111.791
Estimated Bufferpool Buffers: 23.75
8
10
인덱스 스캔시에 Sequential
Prefetch가 사용되었습니다.
Index Sargable predicate인
(EMPNO < 10) 은 Filter Factor
가 0.000390625 입니다.
Arguments:
--------MAXPAGES: (Maximum pages for prefetch)
17
PREFETCH: (Type of Prefetch)
SEQUENTIAL
ROWLOCK : (Row Lock intent)
NEXT KEY SHARE
SCANDIR : (Scan Direction)
FORWARD
TABLOCK : (Table Lock intent)
INTENT SHARE
9
인덱스 스캔은 순방향으로
실행되었습니다.
Predicates:
---------2) Sargable Predicate
Relational Operator:
Less Than (<)
Subquery Input Required:
No
Filter Factor:
0.000390625
Predicate Text:
-------------(Q1."EMPNO" < 10)
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 169
TOPIC
09 09 Non-matching Index Scan
01
11
Range Delimiting predicate
의 Start key는 = 연산자를 사용
하며, Filter Factor 는 0.125입
니다.
3) Start Key Predicate
Relational Operator:
Equal (=)
Subquery Input Required:
No
Filter Factor:
0.125
Predicate Text:
-------------(Q1."WORKDEPT" = 'D01')
12
3) Stop Key Predicate
Relational Operator:
Equal (=)
Subquery Input Required:
No
Filter Factor:
0.125
Predicate Text:
-------------(Q1."WORKDEPT" = 'D01')
13
사용된 인덱스명은
KES.EMPL_IX04 입니다.
인덱스 스캔시의 시작과 종료
leaf page를 판별하는 start
/ stop key로 사용된 조건식
은 (WORKDEPT=‘D01’) 입니
다.
Input Streams:
------------1) From Object KES.EMPL_IX04
. . .
Output Streams:
-------------2) To Operator #2
Estimated number of rows:
1.125
Number of columns:
1
Subquery predicate ID:
Not Applicable
14
인덱스 KES.EMPL_IX04에서 RID
와 EMPNO 값을 가져옵니다.
Column Names:
-----------+Q1."EMPNO"
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 170
TOPIC
09 10 One Fetch Access
01
1
인덱스의 Leaf Page 중에서 한 페이지만 액세스하는 방법입니다.
 적절한 인덱스가 있고, Leaf Page에서 한 페이지만 액세스하여 검색이 가능한 경우입니다.
 MIN 또는 MAX 함수를 사용할 때 이용됩니다.
2
다음과 같은 경우입니다.
SELECT
MIN(C1)
SELECT
MAX(C1)
FROM
T1
FROM
T1
SELECT
MIN(C2)
SELECT
MIN(C1)
FROM
T1
FROM
T1
WHERE C1 = 5
WHERE C1 > 5
SELECT
MAX(C2)
SELECT
MAX(C3)
FROM
T1
FROM
T1
WHERE C1=5
WHERE C1=5
AND
AND
C2=10
AND
C3 > 5
C2 BETWEEN 5 AND 10
(C1,C2,C3)로 구성된 인덱스
가 있을 때, One-Fetch
Access가 가능합니다.
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 171
TOPIC
09 11 Index Only Access
01
1
2
인덱스만 액세스하여 조건식을 평가하고, SELECT절에서 요청된 컬럼을 인덱스에서 가져오는 방법입니다.

WHERE 조건절과 SELECT절에 표현된 컬럼들이 모두 인덱스에 있는 컬럼인 경우에 해당합니다.

테이블을 액세스할 필요가 없습니다.
다음과 같은 경우입니다.
SELECT
C1, C2
SELECT
C1, C2
SELECT
COUNT(*)
FROM
T1
FROM
T1
FROM
T1
WHERE C1 > 0
WHERE C1 = 1
AND
SELECT
T1.C1, T1.C2, T2.C3
FROM
T1, T2
WHERE T1.C1 > 0
AND
T1.C1 = T2.C1
(C1,C2)로 구성된 인덱스가
있을 때, 인덱스만 액세스하여
도 C1,C2 값을 반환할 수 있습
니다.
C2 > 2
T1 테이블에 (C1,C2)로 구성된 인덱스가 있고, T2 테이블에
(C1)으로 구성된 인덱스만 있을 때는 Index Only Access가
안 됩니다. 만약, T2 테이블에 (C1) 인덱스를 생성할 때,
INCLUDE(C3) 옵션을 추가하였다면, Index Only Access가
가능합니다.
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 172
TOPIC
09 11 Index Only Access
01
3
인덱스만 사용하여 원하는 데이터를 검색하는 예입니다. 적합한 복합 인덱스 또는 Include column 옵션이 있는 인덱스가 사용됩니다.
Original Statement:
-----------------select empno, workdept
from kes.empl
where empno = 10
4
사용자가 입력한 원래의 SQL
문에는 select 절에 EMPNO
컬럼이 있습니다.
Optimized Statement:
------------------SELECT 10 AS "EMPNO",
Q1."WORKDEPT" AS "WORKDEPT"
FROM KES.EMPL AS Q1
WHERE (Q1."EMPNO" = 10)
5
옵티마이저는 WHERE 조건
절을 이용하여 SELECT절에
서 요청된 EMPNO 컬럼의
값을 상수 10으로 대체하여
SQL문을 재작성하였습니
다.
6
연산자는 IXSCAN으로 index scan 이 선
택된 것을 표시합니다. 예측된 I/O 비용은
1, 실행 비용은 12.8801, 반환되는 건수는 1
건입니다. RID를 파악하여 테이블에서
fetch 합니다.
7
인덱스 스캔에 사용된 인덱스는
KES.EMPL_PK01 입니다.
Access Plan:
----------Total Cost:
Query Degree:
25.7351
1
Rows
RETURN
( 1)
Cost
I/O
|
1
FETCH
( 2)
25.7351
2
/---+---\
1
23040
IXSCAN TABLE: KES
( 3)
EMPL
12.8801
1
|
23040
INDEX: KES
EMPL_PK01
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 173
TOPIC
09 11 Index Only Access
01
8
(EMPNO, WORKDEPT)로 구성된 복합 인덱스를 생성하고, 통계 정보를
변경합니다.
create unique index kes.empl_ix02
on kes.empl (empno, workdept);
runstats on table kes.empl and detailed indexes all;
9
또는 (EMPNO) 로 구성된 인덱스에 (WORKDEPT)를 INCLUDE COLUMN
으로 생성하고, 통계 정보를 변경합니다.
create unique index kes.empl_ix02
on kes.empl (empno)
include (workdept);
runstats on table kes.empl and detailed indexes all;
10
인덱스를 스캔한 후에 테이블을 fetch 하
지 않고, EMPNO, WORKDEPT 컬럼을 가
져옵니다.
11
인덱스 스캔에 사용된 인덱스는
KES.EMPL_IX02 입니다.
Original Statement:
-----------------select empno, workdept
from kes.empl
where empno = 10
Access Plan:
----------Total Cost:
Query Degree:
12.8844
1
Rows
RETURN
( 1)
Cost
I/O
|
1
IXSCAN
( 2)
12.8844
1
|
23040
INDEX: KES
EMPL_IX02
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 174
TOPIC
09 12 다중 Index Access
01
1
2
한 테이블에 대해 'AND' 나 'OR' 조건을 수행시에 조건식에 대한 Index가 각각 존재할 경우 여러 인덱스 scan의 결과를 조합하는 방법입니다.

내부적으로 각 인덱스의 RID에 대한 교집합 또는 합집합을 실행하여 최종적인 RID 리스트에 대응되는 데이터만 액세스합니다.

RID 리스트 작성 과정에서 'List Prefetch' 가 발생하므로 OLTP 환경에서는 비효율적일 수도 있습니다.
다음과 같은 경우입니다.
인덱스 IX1(C1), IX2(C2)가 있
을 때, 내부적으로 Index
ANDing과 Index ORing이 발
생됩니다.
C1=34 조건식은
Matching Column으
로 IX1을 이용하여
RID 리스트가 작성됩
니다.
SELECT
C3, C4
FROM
T1
WHERE ( C1 = 34)
OR
C1=40 조건식은
Matching Column으
로 IX1을 이용하여
RID 리스트가 작성됩
니다.
C1=34 에서 생성된
RID 리스트와 OR 연산
을 실행하여 최종 RID
리스트를 생성하여 테
이블을 fetch합니다.
( C1 = 40 AND C2 = 'A' )
C2='A' 조건식은
Matching Column으
로 IX2를 이용하여
RID 리스트가 작성됩
니다.
C1=40 과 C2='A' 에
서 생성된 RID 리스트
로 AND 연산을 실행
하여 공통된 RID만 생
성합니다.
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 175
TOPIC
09 13 IN list Index Scan
01
1
IN 절의 값을 이용하여 다중 Index Access를 실행하는 방법입니다.
 인덱스를 사용할 수 있는 검색 조건식의 IN 절에서 두 개 이상의 상수값이 나열되어 있는 경우에 해당됩니다.
 Query Parallelism이 지원되므로 성능에 유리합니다.
2
다음과 같은 경우입니다.
SELECT
C2, C4
FROM
T1
(C1,C2,C3)로 구성된 인덱스
가 있을 때, 3개의 Matching
Column으로 INDEX Scan을
수행합니다.
WHERE C1=1
AND
C2 IN (1, 2, 3)
AND
C3 > 0
SELECT
C2, C4
SELECT
C2, C4
SELECT
C2, C4
FROM
T1
FROM
T1
FROM
T1
WHERE C1=1
+
WHERE C1=1
+
WHERE C1=1
AND
C2 =1
AND
C2 =2
AND
C2 =3
AND
C3 > 0
AND
C3 > 0
AND
C3 > 0
내부적으로 IN 절을 변형하
여, 3개의 SQL로 병렬 처리
하고, 결과를 UNION 합니다.
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 176
TOPIC
09 14 Sequential Prefetch
01
1
2
Table scan 또는 Index scan시에 인접해 있는 여러 페이지의 데이터를 한꺼번에 버퍼풀로 미리 read 해 두는 기능입니다.

프리페치는 비동기 방식으로 실행되며, 대량의 데이터를 처리할 때 유리합니다.

프리페치가 사용되지 않는 경우에 I/O 의 기본 단위는 1 페이지입니다.

Cluster Ratio가 80% 미만인 경우에는 Sequential Prefetch 를 수행하지 않습니다.
다음과 같은 경우입니다.
2) TBSCAN: (Table Scan)
PREFETCH: (Type of Prefetch)
SEQUENTIAL
ROWLOCK : (Row Lock intent)
NEXT KEY SHARE
SCANDIR : (Scan Direction)
FORWARD
TBISOLVL: (Table access Isolation Level)
CURSOR STABILITY
2) Sargable Predicate
Relational Operator:
Filter Factor:
Equal (=)
0.0278811
Predicate Text:
-------------(Q1."NAME" = 'JOHNS')
SELECT
*
FROM
kes.empl
WHERE name = 'JOHNS'
(NAME) 컬럼에 대한 인
덱스가 없으므로
Sequential prefetch를
이용한 table scan을 실
행합니다.
익스플레인 tool을 이
용하여 prefetch가 실
행되었는지 확인할 수
있습니다.
Rows
RETURN
( 1)
Cost
I/O
|
14453.6
TBSCAN
( 2)
25862.5
14408
|
518400
TABLE: KES
EMPL
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 177
TOPIC
09 15 List Prefetch
01
1
2
동일한 데이터 페이지를 여러 번 I/O 하지 않기 위해 인덱스에서 검색된 RID를 정렬하여 테이블을 액세스하는 방법입니다.

인덱스에서 조건에 맞는 RID들을 검색하여 데이터 페이지 순으로 RID를 정렬하여 해당 데이터
페이지를 fetch 합니다.

80% 미만의 Cluster Ratio를 갖는 단일 인덱스 액세스에 발생합니다.

다중 인덱스 액세스시의 Index ORing과 Index ANDing 을 실행하기 위에 발생합니다.

RID 정렬은 성능에 영향을 주므로 OLTP 환경에서는 적합하지 않습니다.
다음과 같은 경우입니다.
SELECT
*
FROM
kes.empl
WHERE name < 'JOHNS'
(NAME) 컬럼에 대한 인
덱스가 있고, cluster
ratio가 80% 미만이라면,
List prefetch를 이용한
index scan을 실행합니
다.
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 178
TOPIC
09 16 Index ORing
01
1
2
RID 리스트에 대한 OR 연산을 실행하는 기법입니다.

다중 Index Access 를 실행할 때 내부적으로 사용됩니다.

개별 인덱스를 scan하여 생성된 RID 리스트들을 모두 결합한 후에 중복된 RID는
제거합니다.
다음과 같은 과정으로 처리됩니다.
SELECT
*
FROM
t1
WHERE (lastname = 'Free' )
OR
(firstname BETWEEN 'David' AND 'Dennis')
인덱스 IX1 (LASTNAME), IX2
(FIRSTNAME) 이 있다면,
Index ORing이 발생할 수도 있
습니다.
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 179
TOPIC
09 16 Index ORing
01
3
(EMPNO)와 (WORKDEPT)에 대한 인덱스가 따로 존재할 때, 두 개의 인덱스를 개별적으로 액
Access Plan:
-----------
세스한 결과를 UNION 하는 예입니다. 사용된 조건문은 2개의 Range Delimiting predicate
를 OR로 연결한 것입니다.
Original Statement:
-----------------select empno, name, workdept
from kes.empl
where empno = 10 or workdept = 'D01'
4
사용자가 입력한 원래의 SQL
문에는 BETWEEN이 사용되
었습니다.
Optimized Statement:
------------------SELECT Q1."EMPNO" AS "EMPNO",
Q1."NAME" AS "NAME",
Q1."WORKDEPT" AS "WORKDEPT"
FROM KES.EMPL AS Q1
WHERE ((Q1."EMPNO" = 10) OR
(Q1."WORKDEPT" = 'D01'))
5
6
SQL문은 재작성되지 않았
습니다.
연산자는 SORT로 index scan 후에 선택된
RID들을 정렬하여 index Oring에 사용합
니다.
7
연산자는 IXSCAN으로 index scan 이 선
8
사용된 인덱스는 각각 KES.EMPL_PK01과
택된 것을 표시합니다.
KES.EMPL_IX01 입니다.
Total Cost:
261.007
Query Degree:
1
Rows
RETURN
( 1)
Cost
I/O
|
2880.88
FETCH
( 2)
261.007
102.339
/---+---\
2880.88
23040
RIDSCN TABLE: KES
( 3)
EMPL
76.0501
5.625
/-----+-----\
1
2880
SORT
SORT
( 4)
( 6)
12.8812
63.1695
1
4.625
|
|
1
2880
IXSCAN
IXSCAN
( 5)
( 7)
12.8801
61.5793
1
4.625
|
|
23040
23040
INDEX: KES
INDEX: KES
EMPL_PK01
EMPL_IX01
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 180
TOPIC
09 17 Index ANDing
01
1
2
RID 리스트에 대한 AND 연산을 실행하는 기법입니다.

다중 Index Access 실행시에 내부적으로 사용됩니다.

개별 인덱스를 scan 하면서 hash 함수를 적용하여 RID 리스트에 대한 bitmap을 생성합니다.

두 개의 인덱스에 대한 bitmap으로 AND 연산을 먼저 실행하고, 그 결과를 이용하여 다음
인덱스의 bitmap과 AND 연산을 실행하는 것을 반복합니다.

최종적으로 생성된 bitmap을 이용하여 테이블에서 해당되는 데이터를 fetch 합니다.
다음과 같은 과정으로 처리됩니다.
SELECT
price
FROM
products
WHERE price > 250
AND
units > 10
AND
color = ‘Blue’
인덱스 IX1 (UNITS), IX2
(PRICE), IX3 (COLOR) 이
있다면, Index ANDing이
발생할 수 있습니다.
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 181
TOPIC
09 18 다중 테이블 액세스
01
1
2
여러 개의 테이블을 액세스하는 쿼리는 조인을 사용하게 됩니다.

조인의 대상이 되는 두 개의 테이블을 Outer 테이블과 Inner 테이블이라고 하며, 조인의 유형과 실행 비용에 따라 그 역할이
결정됩니다.

조인하는 테이블이 2개 이상이더라도, 한 번에 두 개의 테이블만 조인이 실행되고, 그 결과는 임시 테이블에 저장되어 다음
테이블과 조인을 반복합니다.

조인의 조건식을 반드시 기술하고, 조건식에 사용되는 컬럼에 대하여 인덱스를 생성하도록 합니다.
 조인의 대상 데이터 건수를 최소한으로 줄일 수 있도록 local predicate를 표현하는 것이 중요합니다. 불필요한 중복 조인은
조인의
내부적인 처리
방법은 다음과 같이 분류됩니다.
제거하도록
합니다.

Nested Loop 조인

Merge Scan 조인

Hash 조인
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 182
TOPIC
09 19 Cartesian Product
01
1
Outer 테이블에서 조건을 만족하는 모든 행과 Inner 테이블에서 조건을 만족하는 모든 행을 조합한 결과를 반환하므로 result set의 크기가 심
하게 커질 수 있습니다. 조인의 조건이 명시되지 않거나, N:1:M 의 관계를 가지는 테이블간의 조인에서 발생할 수 있습니다.
Original Statement:
-----------------select *
from kes.employee, kes.department
3
2
사용자가 입력한 원래의 SQL
문에 조인 조건이 없습니다.
연산자는 NLJOIN으로 nested loop 조인을 실행합니다. 조인 조건이 없으므로,
실행 비용과 반환되는 데이터 건수가 심하게 커집니다.
2) NLJOIN: (Nested Loop Join)
Cumulative Total Cost:
7.37708e+009
Cumulative CPU Cost:
4.74925e+014
Cumulative I/O Cost:
4.08086e+009
. . .
Input Streams:
------------2) From Operator #3
Estimated number of rows: 518400
Number of columns:
15
. . .
Output Streams:
-------------5) To Operator #1
Estimated number of rows: 2.6454e+011
Number of columns:
20
Access Plan:
----------Total Cost: 7.37708e+009
Query Degree: 1
Rows
RETURN
( 1)
Cost
I/O
|
2.6454e+011
NLJOIN
( 2)
7.37708e+009
4.08086e+009
/-----+-----\
518400
510300
TBSCAN
TBSCAN
( 3)
( 4)
25843.4
14230.4
14434
7872
|
|
518400
510300
TABLE: KES TABLE: KES
EMPLOYEE DEPARTMENT
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 183
TOPIC
09 20 Nested Loop 조인
01
1
2
Outer 테이블의 각 행에 대해 Inner 테이블을 한 번씩 scan 하는 조인 기법입니다.

Inner 테이블의 크기가 작은 경우에 적합합니다. 조인 조건식에 사용된 컬럼에 대한 인덱스가 있다면, 인덱스 스캔이 가능합니다.

Outer 테이블의 데이터 건수가 적을수록 적합합니다. 조인 조건식에 사용된 컬럼에 대한 인덱스가 있는 것이 성능에 도움이 됩니다.

조인 컬럼에 대해 인덱스가 클러스터 인덱스인 경우에 유리합니다.
다음과 같은 과정으로 처리됩니다.
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 184
TOPIC
09 21 Merge Scan 조인
01
1
2
Outer 테이블과 Inner 테이블을 한 번씩만 scan 하는 조인 기법입니다.

Inner 테이블을 한 번만 scan 하므로 Nested Loop 조인보다 일반적으로 유리합니다.

조인을 실행하기 전에 조인의 대상이 되는 행들은 조인 컬럼에 대해 정렬이 되어 있어야 하므로, 인덱스가 있는 경우에 성능에 도움이
됩니다.

조인의 대상이 되는 행의 수를 최소화할 수 있도록 filtering 조건식을 표현하는 것이 중요합니다.
다음과 같은 과정으로 처리됩니다.
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 185
TOPIC
09 22 Hash 조인
01
1
2
Hash 함수를 이용하여 Inner 테이블에 대한 lookup 테이블을 생성하여 조인하는 기법입니다.

Inner 테이블을 scan 하여 조인 컬럼의 값에 hash 함수를 적용하여 lookup 테이블을 생성합니다.

Outer 테이블의 행에 hash 함수를 적용하여 해당하는 bucket을 결정하고, bucket 을 scan 하여 조인의 대상을 판별합니다.

조인 조건식의 컬럼의 데이터 유형과 그 길이가 같고, = 을 이용하여 비교하는 경우에 해당됩니다.

Outer 테이블을 Probe 테이블, Inner 테이블을 Build 테이블이라고도 합니다.
다음과 같은 과정으로 처리됩니다.
U D B 개 발 자 기 본 교 육 • UNIT 09 • 익스플레인 186
TOPIC
10
01
UNIT10
Oracle 비교
UDB개발자기본교육
데이터 유형
함수
데이터 유형 변환
NULL 값
시스템 레지스터리
DUMMY TABLE
ROWNUM
RAWID
날짜 연산
집합 연산
DECODE 문
값을 반환하는 UPDATE, INSERT, DELETE문
OUTER JOIN
SEQUENCE
SYNONYM
저장 프로시저
사용자 정의 함수
트리거
TEMPORARY TABLE
SUMMARY TABLE
계층적 쿼리
SQLCA 확인
U D B 개 발 자 기 본 교 육 • UNIT 10 • Oracle 비교 187
TOPIC
10 01 데이터 유형
01
CHAR, VARCHAR2, LONG, NUMBER, DATE, LOB 등이 있습니다.
ORACLE
CHAR, VARCHAR, SMALLINT, INT, BIGINT, DEC, FLOAT, DATE,
TIME, TIMESTAMP, LOB 등이 있습니다.
DB2 UDB
U D B 개 발 자 기 본 교 육 • UNIT 10 • Oracle 비교 188
TOPIC
10 02 함수
01
자주 사용되는 문자, 숫자, 날짜, 변환, 날짜 함수입니다. 이름이나 형식이
약간 다른 함수도 있으며, UDF를 생성하여 쉽게 대응할 수 있는 함수들도
다수입니다.
DB2가 지원하는 함수 중에 대표적인 것은 다음과 같습니다. 필요시 UDF
를 생성하여 사용할 수 있습니다. UDF는 SQL/PL, C, JAVA 등을 이용하
여 작성합니다.
ORACLE
DB2 UDB
ASCII
ABS
ADD_MONTH
AVG
ASCII
ABS
DAY
AVG
CHR
CEIL
LAST_DAY
COUNT
CHR
ASIN
DAYNAME
CORRELATION
CONCAT
COS
MONTHS_BETWEEN
MAX
CAST
CEIL
DAYOFWEEK
COUNT
CONVERT
EXP
NEW_TIME
MIN
CONCAT
DEGITS
DAYOFYEAR
COUNT_BIG
INITCAP
FLOOR
NEXT_DAY
STDDEV
INSERT
DEGREES
DAYS
COVARIANCE
INSTR
GREATEST
ROUND
SUM
LEFT
EXP
HOUR
MAX
INSTRB
LEAST
TRUNC
VARIANCE
LENGTH
FLOOR
MICROSECOND
MIN
LENGTH
LN
TO_CHAR
LOCATE
HEX
MINUTE
STDDEV
LENGTHB
LOG
TO_DATE
LOWER
LN
MONTH
SUM
LOCATE
MOD
TO_MULTI_BYTE
LTRIM
LOG10
MONTHNAME
VARIANCE
LOWER
POWER
TO_NUMBER
NULLIF
MOD
QUARTER
CUBE
LPAD
ROUND
TO_SINGLE_BYTE
POSSTR
POWER
SECOND
GROUPING SET
LTRIM
SIGN
SYSDATE
REPEAT
RADIANS
TO_CHAR
RANK
NVL
SIN
USER
REPLACE
RAND
TO_DATE
ROLLUP
REPLACE
SQRT
RIGHT
ROUND
TIME
ROW_NUMBER
RPAD
TAN
RTRIM
SIGN
TIMESTAMP
CHAR
RTRIM
TRUNC
SPACE
SIN
TIMSTAMPDIFF
DATE
SUBSTR
SUBSTR
SINH
TIMSTAMP_FORMAT
DEC
SUBSTRB
TRANSLATE
SQRT
WEEK
GRAPHIC
TRANSLATE
UPPER
TAN
YEAR
INT
UPPER
VALUE
TRUNC
+ n DAYS
VARCHAR
U D B 개 발 자 기 본 교 육 • UNIT 10 • Oracle 비교 189
TOPIC
10 03 데이터 유형 변환
01
필요시 데이터 유형의 변환이 발생합니다.
명시적인 데이터 타입이 맞지 않을 경우에는 조작을 허용하지 않습니다.
필요시, 명시적인 데이터 유형 변환 함수나 CAST 함수를 사용합니다.
ORACLE
DB2 UDB
create table t1 (c1 INT);
insert into t1 values (int(‘1’));
select * from t1 where c1 = int(‘1’);
create table t1 (c1 INT);
insert into t1 values (cast(‘1’ as int));
select * from t1 where c1 = cast(‘1’ as int);
U D B 개 발 자 기 본 교 육 • UNIT 10 • Oracle 비교 190
TOPIC
10 04 NULL 값
01
문자열의 병합시 NULL값이 포함되면 NULL값을 empty string으로 처리
합니다.
ORACLE
문자열의 병합시 NULL값이 포함되면 결과는 NULL이 됩니다. NULL 값
은 다른 NULL 값과 비교할 수 없으므로 JOIN 시에도 동일한 값으로 처리
되지 않습니다.
DB2 UDB
U D B 개 발 자 기 본 교 육 • UNIT 10 • Oracle 비교 191
TOPIC
10 05 시스템 레지스터리
01
SYSDATE를 비롯한 여러가지 값을 제공합니다.
ORACLE
Special Register 변수를 이용하여 시스템에 관련된 여러가지 값을 SQL문
에서 시용하거나 환경 설정을 위해 사용합니다.
DB2 UDB
Pseudo Column
SYSDATE
USER
ROWNUM
ROWID
U D B 개 발 자 기 본 교 육 • UNIT 10 • Oracle 비교 192
TOPIC
10 06 DUMMY TABLE
01
DUAL 을 이용합니다.
ORACLE
SYSIBM.SYSDUMMY1 을 이용합니다.
DB2 UDB
U D B 개 발 자 기 본 교 육 • UNIT 10 • Oracle 비교 193
TOPIC
10 07 ROWNUM
01
ROWNUM을 이용하여 반환되는 행의 개수를 제한합니다.
ORACLE
FETCH FIRST n ROWS ONLY 구문이나 ROW_NUMBER 함수를 이용합
니다.
DB2 UDB
U D B 개 발 자 기 본 교 육 • UNIT 10 • Oracle 비교 194
TOPIC
10 08 ROWID
01
ROWID를 이용하여 처리할 행을 지정합니다.
ORACLE
ROWID는 제공되지 않습니다. 테이블 차원의 identity column을 이용하거
나, 데이터베이스 차원의 sequence를 이용합니다.
DB2 UDB
SELECT rowid, deptno FROM scott.dept;
ROWID
DEPTNO
---------------------------------------------------------AAABbnAAFAAAAESAAA
10
AAABbnAAFAAAAESAAB
20
AAABbnAAFAAAAESAAC
30
AAABbnAAFAAAAESAAD
40
UPDATE emp
SET
sal = 999
WHERE rowid IN (SELECT rowid
FROM
emp
WHERE ename LIKE 'A%');
U D B 개 발 자 기 본 교 육 • UNIT 10 • Oracle 비교 195
TOPIC
10 09 날짜 연산
01
DATE 유형을 이용하여, 날짜, 시간, 시간 소인을 처리합니다.
ORACLE
DATE, TIME, TIMESTAMP 유형을 이용하여, 날짜, 시간, 시간 소인을
처리합니다. 지원되지 않는 함수는 UDF를 이용합니다.
DB2 UDB
U D B 개 발 자 기 본 교 육 • UNIT 10 • Oracle 비교 196
TOPIC
10 10 집합 연산
01
UNION, UNION ALL, MINUS, INTERSECT 를 지원합니다.
ORACLE
UNION, UNION ALL, EXCEPT, EXCEPT ALL, INTERSECT,
INTERSECT ALL 을 지원합니다.
DB2 UDB
(SELECT C1.*,COUNT(*)
FROM CUSTOMER_KNOWN_GOOD
GROUP BY C1.CUST_NBR, C1.NAME...
MINUS
SELECT C2.*, COUNT(*)
FROM CUSTOMER_TEST C2
GROUP BY C2.CUST_NBR, C2.NAME...)
UNION ALL
(SELECT C3.*,COUNT(*)
FROM CUSTOMER_TEST C3
GROUP BY C3.CUST_NBR, C3.NAME...
MINUS
SELECT C4.*, COUNT(*)
FROM CUSTOMER_KNOWN_GOOD C4
GROUP BY C4.CUST_NBR, C4.NAME...)
U D B 개 발 자 기 본 교 육 • UNIT 10 • Oracle 비교 197
TOPIC
10 11 DECODE 문
01
여러가지 조건문을 판별할 때, DECODE 문을 사용합니다.
ORACLE
CASE 문을 이용합니다.
DB2 UDB
U D B 개 발 자 기 본 교 육 • UNIT 10 • Oracle 비교 198
TOPIC
10 12 값을 반환하는 UPDATE, INSERT, DELETE문
01
RETURNING INTO 구문을 이용합니다.
ORACLE
SELECT INTO과 FROM NEW TABLE 구문을 이용합니다.
DB2 UDB
U D B 개 발 자 기 본 교 육 • UNIT 10 • Oracle 비교 199
TOPIC
10 13 OUTER JOIN
01
플러스 (+) 기호를 이용하여 outer join 의 기준을 표시합니다.
ORACLE
LEFT, RIGHT, FULL OUTER JOIN 구문을 이용합니다.
DB2 UDB
U D B 개 발 자 기 본 교 육 • UNIT 10 • Oracle 비교 200
TOPIC
10 14 SEQUENCE
01
CURRVAL과 NEXTVAL을 이용하여 참조됩니다.
데이터베이스 차원에서 생성되며, PREVVAL과 NEXTVAL을 이용하여 참
조됩니다.
ORACLE
create sequence dept_seq
start with 500
increment by 1;
insert into dept values (dept_seq.nextval, ‘Sales’);
insert into dept values (dept_seq.nextval, ‘Marketting’);
select * from dept;
C1
C2
-----------------------------500
Sales
501
Marketting
select dept_seq.currval from dual;
1
-----------------------------501
DB2 UDB
create sequence dept_seq
start with 500
increment by 1
cache 20
no cycle
no maxvalue;
drop sequence dept_seq restrict;
insert into dept values (nextval for dept_seq, ‘Sales’);
insert into dept values (nextval for dept_seq, ‘Marketting’);
select * from dept;
C1
C2
-----------------------------500
Sales
501
Marketting
select prevval for dept_seq from sysibm.sysdummy1;
1
-----------------------------501
U D B 개 발 자 기 본 교 육 • UNIT 10 • Oracle 비교 201
TOPIC
10 15 SYNONYM
01
PUBLIC, PRIVATE SYNONYM이 있습니다.
PUBLIC SYNONYM은 존재하지 않으며, PRIVATE SYNONYM은 ALIAS
에 대응됩니다.
ORACLE
CREATE SYNONYM scott_emp FOR scott.emp;
SELECT empno, ename FROM scott_emp;
DB2 UDB
CREATE TABLE kim.t1 (c1 INT);
SELECT * FROM kim.t1;
CREATE ALIAS kim.a1 FOR kim.t1;
SELECT * FROM kim.a1;
CREATE ALIAS lee.t1 FOR kim.a1;
SELECT * FROM lee.t1;
U D B 개 발 자 기 본 교 육 • UNIT 10 • Oracle 비교 202
TOPIC
10 16 저장 프로시저
01
CREATE OR REPLACE PROCEDURE 문을 이용하여 생성합니다.
ORACLE
CREATE PROCEDURE 문을 이용하여 저장 프로시저를 생성합니다.
REPLACE 옵션은 지원하지 않으므로 변경시 DROP을 선행해야 합니다.
DB2 UDB
U D B 개 발 자 기 본 교 육 • UNIT 10 • Oracle 비교 203
TOPIC
10 17 사용자 정의 함수
01
CREATE OR REPLACE FUNCTION 문을 이용하여 생성합니다.
ORACLE
CREATE FUNCTION 문을 이용하여 사용자 정의 함수를 생성합니다.
REPLACE 옵션은 지원하지 않습니다.
DB2 UDB
U D B 개 발 자 기 본 교 육 • UNIT 10 • Oracle 비교 204
TOPIC
10 18 트리거
01
CREATE OR REPLACE TRIGGER 문을 이용합니다.
ORACLE
CREATE TRIGGER 문을 이용하여 트리거를 생성합니다. INSERT,
UPDATE, DELETE 트리거는 개별적으로 생성됩니다.
DB2 UDB
U D B 개 발 자 기 본 교 육 • UNIT 10 • Oracle 비교 205
TOPIC
10 19 TEMPORARY TABLE
01
CREATE GLOBAL TEMPORARY TBALE 문을 이용합니다.
사용자 임시 테이블 스페이스에 temporary table을 생성할 수 있으며, 세
션별로 독립적으로 생성됩니다. SESSION 이라는 스키마명을 자동적으로
갖게 되며, 세션이 종료되면 자동적으로 소멸됩니다.
ORACLE
CREATE GLOBAL TEMPORARY TABLE my_temp_table (
column1 NUMBER,
DB2 UDB
CREATE USER TEMPORARY TABLESPACE apptemps
MANAGED BY SYSTEM USING ('apptemps');
column2 NUMBER
) ON COMMIT DELETE ROWS;
DECLARE GLOBAL TEMPORARY TABLE t_employees
LIKE employee NOT LOGGED;
CREATE GLOBAL TEMPORARY TABLE my_temp_table (
column1 NUMBER,
DECLARE GLOBAL TEMPORARY TABLE t_dept
column2 NUMBER
( deptid CHAR(6), deptname CHAR(20) )
) ON COMMIT PRESERVE ROWS;
ON COMMIT DELETE ROWS NOT LOGGED ;
DECLARE GLOBAL TEMPORARY TABLE t_projects
AS ( fullselect ) DEFINITION ONLY
ON COMMIT PRESERVE ROWS NOT LOGGED
WITH REPLACE IN TABLESPACE apptemps;
INSERT INTO session.t_dept VALUES (‘000001’,’DEPT-A’);
U D B 개 발 자 기 본 교 육 • UNIT 10 • Oracle 비교 206
TOPIC
10 20 MQT
01
CREATE MATERIALIZED VIEW 문을 이용합니다.
집계 함수를 이용한 MQT 을 미리 정의해 두면, 집계 함수를 이용한 복잡
한 쿼리의 실행 시간을 단축시킬 수 있습니다.
ORACLE
DB2 UDB
CREATE MATERIALIZED VIEW sum_sales
BUILD IMMEDIATE
REFRESH COMPLETE
ENABLE QUERY REWRITE
AS
SELECT product_nbr,
SUM(sales) sum_sales
FROM SALES;
ALTER SESSION SET
QUERY_REWRITE_ENABLED=TRUE;
SET AUTOTRACE ON
SELECT SUM(sales)
FROM
SALES;
SET CURRENT MAINTAINED TABLE TYPES FOR
OPTIMIZATION=ALL
U D B 개 발 자 기 본 교 육 • UNIT 10 • Oracle 비교 207
TOPIC
10 21 계층적 쿼리
01
CONNECT BY~START WITH 절을 이용합니다.
ORACLE
SELECT 문에서 WITH로 정의되는 COMMON TABLE 을 이용합니다.
DB2 UDB
U D B 개 발 자 기 본 교 육 • UNIT 10 • Oracle 비교 208
TOPIC
10 22 SQLCA 확인
01
SQL문이 실행될 때마다 SQLCA의 SQLCODE, SQLSTATE 등의 값이 변
경되므로, 오류 발생 여부를 확인할 수 있습니다.
ORACLE
DROP TABLE employee;
DB2 UDB
db2 ‘? SQL0100N’
SQL0100W FETCH, UPDATE 또는 DELETE에 대한 행이
없거나 쿼리 결과가 빈 테이블입니다.
show sqlcode
db2 ‘? 02000’
SQLSTATE 02000: 다음 예외 중 하나가 발생했습니다.
SELECT INTO문 또는 INSERT문의 부속선택의 결과가 빈
테이블이었습니다. 탐색한 UPDATE 또는 DELETE문에서
식별된 행 수가 0 이었습니다. FETCH문에서 참조된 커서의
위치가 결과 테이블의 마지막 행 다음입니다.
EXEC SQL DELETE FROM t1 WHERE c1 = 1;
if ( SQLCODE == 0 )
{
EXEC SQL COMMIT;
…….
}
else
{
EXEC SQL ROLLBACK;
......
}
U D B 개 발 자 기 본 교 육 • UNIT 10 • Oracle 비교 209
TOPIC
11
01
UNIT11
프로그램 유형
UDB개발자기본교육
ESQL
CLI
API
JDBC
저장 프로시저
사용자 정의 함수
주석문
exception 처리
dynamic SQL
WITH UR
기타 고려 사항
U D B 개 발 자 기 본 교 육 • UNIT 11 • 프로그램 유형 210
TOPIC
11 01 ESQL
01
1
ESQL은 데이터의 액세스는 SQL문으로 구현하고, 프로그램의 로직은 프로그래밍 언어로 구현하는 혼합 방식입니다. 프리컴파일과 SQL문에 대
한 바인드, 프로그래밍 언어에 대한 컴파일과 링크 과정을 통해서 팩키지와 바이너리 실행 파일을 생성합니다.
$ db2 connect to sample
$ db2 prep myapp.sqc BINDFILE
$ db2 bind myapp.bnd blocking all grant public
$ xlc -c myapp.c –I~db2inst1/sqllib/include
$ xlc -o myapp myapp.o -ldb2 –L~db2inst1/sqllib/lib
$ myapp
U D B 개 발 자 기 본 교 육 • UNIT 11 • 프로그램 유형 211
TOPIC
11 01 ESQL
01
2
DB2 사용자로 로그인하여 ESQL/C 소스 파일을 작성합니다. 확장자를 sqc 로 지정합니다.
#include <stdio.h>
EXEC SQL INCLUDE SQLCA;
EXEC SQL CONNECT RESET;
return (-1);
}
int main()
{
EXEC SQL BEGIN DECLARE SECTION;
char fname[13];
char lname[16];
char newfname[13];
EXEC SQL END DECLARE SECTION;
EXEC SQL COMMIT;
EXEC SQL CONNECT RESET;
return(0) ;
}
3
EXEC SQL CONNECT TO sample;
printf("Enter the lastname : ");
gets(lname);
EXEC SQL SELECT FIRSTNME INTO :fname
FROM employee
WHERE LASTNAME = :lname;
if (SQLCODE == 0)
printf("First name = %s\n", fname);
else if (SQLCODE == 100)
printf("Data is not found\n");
else {
printf("Select Error : SQLCODE = %ld\n", SQLCODE);
EXEC SQL ROLLBACK;
prep 명령어로 프리컴파일하고, bind 명령어로 팩키지를 생성합니다.
$ db2 connect to <데이터베이스명>
$ db2 prep <소스파일명>.sqc bindfile
$ db2 bind <소스파일명>.bnd blocking all grant public
4
C 컴파일러를 이용하여 컴파일과 링크를 실행하십시오.
$ xlc -c <소스파일명>.c –I~<인스턴스명>/sqllib/include
$ xlc -o <실행파일명> <소스파일명>.o -ldb2 –L~<인스턴스
명>/sqllib/lib
5
바이너리 형식의 실행 모듈을 실행하십시오.
$ <실행파일명>
Enter the lastname : LEE
First name = Newman
U D B 개 발 자 기 본 교 육 • UNIT 11 • 프로그램 유형 212
TOPIC
11 02 CLI
01
1
CLI는 데이터를 액세스하는 SQL문은 C 라이브러리 형식으로 된 API 로 구현하고, 프로그램의 로직은 C 언어로 구현하는 방식입니다. C 언어
에 대한 컴파일과 링크 과정을 통해서 바이너리 실행 파일을 생성합니다. ESQL 에서 지원하는 동적 SQL문에 대응하는 API 가 모두 지원됩니다.
$ xlc -c mycli.c –I~db2inst1/sqllib/include
$ xlc -o mycli mycli.o -ldb2 –L~db2inst1/sqllib/lib
$ mycli
U D B 개 발 자 기 본 교 육 • UNIT 11 • 프로그램 유형 213
TOPIC
11 02 CLI
01
2
DB2 사용자로 로그인하여 CLI 소스 파일을 작성합니다. 확장자를 c 로 지정합니다.
#include <stdio.h>
#include <sqlcli1.h>
printf("DEPTNUMB LOCATION
printf("-------- ------------\n" ) ;
sqlrc = SQLFetch( hstmt );
main() {
SQLHANDLE henv;
SQLHANDLE hdbc;
SQLHANDLE hstmt;
SQLCHAR * stmt = ( SQLCHAR * ) "SELECT deptnumb,
location FROM org";
SQLRETURN sqlrc = SQL_SUCCESS;
struct
{ SQLINTEGER ind ;
SQLSMALLINT val ;
} deptnumb ;
struct
{ SQLINTEGER ind ;
SQLCHAR val[15] ;
} location ;
SQLAllocHandle(SQL_HANDLE_ENV,
SQL_NULL_HANDLE, &henv);
SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
SQLConnect(hdbc, (SQLCHAR *)"SAMPLE", SQL_NTS,
NULL, SQL_NTS, NULL, SQL_NTS);
SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
SQLExecDirect( hstmt, stmt, SQL_NTS ) ;
\n" ) ;
if (sqlrc == SQL_NO_DATA_FOUND)
printf("\n Data not found.\n");
while (sqlrc != SQL_NO_DATA_FOUND)
{
sqlrc = SQLGetData( hstmt, 1, SQL_C_SHORT,
&deptnumb.val,
0, &deptnumb.ind ) ;
sqlrc = SQLGetData( hstmt, 2, SQL_C_CHAR,
location.val,
15, &location.ind ) ;
printf( "%-8d %-14.14s \n", deptnumb.val, location.val ) ;
sqlrc = SQLFetch( hstmt );
}
SQLFreeStmt(hstmt, SQL_CLOSE);
SQLEndTran(SQL_HANDLE_DBC, hdbc, SQL_COMMIT);
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
SQLDisconnect(hdbc);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
return(0);
}
U D B 개 발 자 기 본 교 육 • UNIT 11 • 프로그램 유형 214
TOPIC
11 02 CLI
01
3
C 컴파일러를 이용하여 컴파일과 링크를 실행하십시오.
$ xlc -c <소스파일명>.c –I~<인스턴스명>/sqllib/include
$ xlc -o <실행파일명> <소스파일명>.o -ldb2 –L~<인스턴스
명>/sqllib/lib
4
바이너리 형식의 실행 모듈을 실행하십시오.
$ <실행파일명>
DEPTNUMB LOCATION
--------------------------------10
New York
15
Boston
20
Washington
38
Atlanta
42
Chicago
51
Dallas
66
San Francisco
84
Denver
10
New York
15
Boston
20
Washington
38
Atlanta
42
Chicago
51
Dallas
66
San Francisco
84
Denver
U D B 개 발 자 기 본 교 육 • UNIT 11 • 프로그램 유형 215
TOPIC
11 03 API
01
1
API는 DB2 명령어를 C 라이브러리 형식으로 된 API 로 구현하는 방식입니다. 데이터 액세스에 SQL문을 사용하고, 프로그램 로직을 C 언어로
구현하는 것은 ESQL/C 와 동일합니다.
using CLP
export to artexprt of del
select *
from artists
using API
sqluexpr(dataFileName,
NULL,
NULL,
&dataDescriptor,
pAction,
SQL_DEL,
NULL,
msgFileName,
SQLU_INITIAL,
&outputInfo,
NULL,
&sqlca);
U D B 개 발 자 기 본 교 육 • UNIT 11 • 프로그램 유형 216
TOPIC
11 03 API
01
2
DB2 사용자로 로그인하여 API 를 포함한 ESQL/C 소스 파일을 작성합니다. ESQL/C 소스이므로 확장자는 sqc 로 지정합니다.
$ login <DB2 사용자>
$ vi <소스파일명>.sqc
#include <stdio.h>
#include <stdlib.h>
#include <sqlutil.h>
pAction->length = strlen(actionString);
strcpy(pAction->data, actionString);
strcpy(msgFileName, "tbexport.MSG");
outputInfo.sizeOfStruct = SQLUEXPT_OUT_SIZE;
printf("
printf("
printf("
int main()
{
struct sqlca sqlca;
sqluexpr(dataFileName,
NULL,
NULL,
&dataDescriptor,
pAction,
SQL_DEL,
NULL,
msgFileName,
SQLU_INITIAL,
&outputInfo,
NULL,
&sqlca);
free(pAction);
EXEC SQL connect reset;
return 0;
char dataFileName[256];
struct sqldcol dataDescriptor;
char actionString[256];
struct sqlchar *pAction;
char msgFileName[128];
struct sqluexpt_out outputInfo;
EXEC SQL connect to sample;
strcpy(dataFileName, "ORG.DEL");
dataDescriptor.dcolmeth = SQL_METH_D;
strcpy(actionString, "SELECT deptnumb, deptname
FROM org");
pAction = (struct sqlchar *)malloc(sizeof(short) +
sizeof(actionString) + 1);
client destination file name: %s\n", dataFileName);
action
: %s\n", actionString);
client message file name : %s\n", msgFileName);
}
U D B 개 발 자 기 본 교 육 • UNIT 11 • 프로그램 유형 217
TOPIC
11 03 API
01
3
prep 명령어로 프리컴파일하고, bind 명령어로 팩키지를 생성합니다.
$ db2 connect to <데이터베이스명>
$ db2 prep <소스파일명>.sqc bindfile
$ db2 bind <소스파일명>.bnd blocking all grant public
4
C 컴파일러를 이용하여 컴파일과 링크를 실행하십시오.
$ xlc -c <소스파일명>.c –I~<인스턴스명>/sqllib/include
$ xlc -o <실행파일명> <소스파일명>.o -ldb2 –L~<인스턴스명>/sqllib/lib
5
바이너리 형식의 실행 모듈을 실행하십시오.
$ <실행파일명>
$ cat ORG.DEL
10,"Head Office"
15,"New England"
20,"Mid Atlantic"
38,"South Atlantic"
42,"Great Lakes"
51,"Plains"
66,"Pacific"
84,"Mountain"
10,"Head Office"
. . .
U D B 개 발 자 기 본 교 육 • UNIT 11 • 프로그램 유형 218
TOPIC
11 04 JDBC
01
1
JDBC 드라이버는 DB2 클라이언트 제품에 포함되어 있습니다. JDBC type2, type3, type4 를 지원하며, ESQL 방식인 SQLJ 도 지원합니다.
$ javac myjdbc.java
$ java myjdbc
U D B 개 발 자 기 본 교 육 • UNIT 11 • 프로그램 유형 219
TOPIC
11 04 JDBC
01
2
DB2 사용자로 로그인하여 JAVA 소스 파일을 작성합니다. 확장자는 java 로 지정합니다.
$ login <DB2 사용자>
$ vi <소스파일명>.java
import java.sql.*;
ResultSet rs = stmt.executeQuery("SELECT * from employee");
System.out.print("Received results:\n\n");
while (rs.next()) {
String a = rs.getString(1);
String str = rs.getString(2);
System.out.print(" empno= " + a + " firstname= " + str + "\n");
}
rs.close();
stmt.close();
con.close();
} catch( Exception e ) {
e.printStackTrace();
}
class myjdbc {
static {
try {
Class.forName("COM.ibm.db2.jdbc.app.DB2Driver"
).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public static void main(String argv[]) {
Connection con = null;
String url = "jdbc:db2:sample";
String user = "db2admin";
String pswd = "ibmdb2";
try {
con = DriverManager.getConnection(url);
Statement stmt = con.createStatement();
U D B 개 발 자 기 본 교 육 • UNIT 11 • 프로그램 유형 220
TOPIC
11 04 JDBC
01
3
Java 버전을 확인하십시오.
8
$ java -version
java version "1.3.1"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1)
4
Java 버전에 맞는 컴파일러가 실행되고 있는지 확인하십시오.
$ which javac
/usr/java13_64/bin/javac
type4 를 사용하는 경우에는 class명과 url만 변경하면 됩니다.
$ login <DB2 사용자>
$ vi <소스파일명>.java
import java.sql.*;
class myjdbc {
static {
try {
5
PATH, CLASSPATH 환경 변수가 적절히 구성되었는지 확인하십시오.
$ echo $PATH
$ echo $CLASSPATH
6
Javac 명령어로 컴파일합니다.
$ javac <소스파일명>.java
7
java 명령어로 자바 클래스 파일을 실행합니다. 실행 결과는 다음과 같습니다.
$ java <클래스파일명>
Received results:
empno=000010 firstname=CHRISTINE
empno=000020 firstname=MICHAEL
…
Class.forName("com.ibm.db2.jcc.DB2Driver")
.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String argv[]) {
Connection con = null;
String url = "jdbc:db2://10.10.10.148:51000/samp
le";
String user = "db2admin";
String pswd = "ibmdb2";
<생략>
U D B 개 발 자 기 본 교 육 • UNIT 11 • 프로그램 유형 221
TOPIC
11 05 저장 프로시저
01
1
저장 프로시저는 클라이언트 머신의 응용프로그램에서 실행해야 하는 로직을 서버의 데이터베이스에 저장하여 서버 머신에서 직접 실행함으
로써 클라언트와 서버 간의 데이터 전송량을 줄이고,성능을 향상시킵니다.
2
공용 로직을 저장 프로시저로 만들어서 사용하면 관리가 용이합니다. 클라이언트 응용프로그램의 개별적인 코딩으로 인한 오류와 소스를 반복
3
저장 프로시저는 실행시에 서버의 자원을 사용하여 실행됩니다. 일반적으로 클라이언트 머신보다 서버 머신의 사양이 좋으므로, 실행 시간이
적으로 작성해야 하는 부담을 줄일 수 있습니다. 프로시저의 로직이 변경되면, 서버의 저장 프로시저만 재생성하면 됩니다.
단축될 수 있습니다.
4
서버 머신의 OS 에 의존적인 로직의 구현이 가능합니다. 클라이언트가 Windows 이고, 서버가 UNIX라면, UNIX 에서만 지원되는 기능을 로직에
포함시킬 수 있습니다.
5
저장 프로시저의 유형은 작성하는 언어에 의해 2 가지로 분류됩니다.
유형
설명
외부 소
스
ESQL, C, Java 등의 프로그래밍 언어로 작성된 라이
브러리를 이용하며, 스칼라 값 또는 결과 집합을 반환
합니다.
SQL
6
7
SQL/PL 로 작성되며, 스칼라값 또는 결과 집합을 반
환합니다.
저장 프로시저는 SQL/PL, ESQL, C, Java 등의 언어를 이용하여 생성합니다.
저장 프로시저에 대한 정보는 SYSCAT.ROUTINES 뷰를 이용해서 확인합니다.
$ db2 "select * from syscat.routines"
8
db2look 명령어로 SQL 저장 프로시저에 대한 DDL문을 추출할 수 있습니다.
$ db2look –d <DB명> –e -o <출력파일명>
U D B 개 발 자 기 본 교 육 • UNIT 11 • 프로그램 유형 222
TOPIC
11 05 저장 프로시저
01
9
SQL 저장 프로시저를 위한 로직을 작성하여 임의의 <파일명>으로 저장합니다.
$ cat <파일명>
CREATE PROCEDURE myproc (IN deptNumber CHAR(3),
OUT medianSalary DOUBLE)
LANGUAGE SQL
BEGIN
DECLARE SQLCODE INTEGER;
DECLARE SQLSTATE CHAR(5);
DECLARE v_numRecords INT DEFAULT 1;
DECLARE v_counter INT DEFAULT 0;
DECLARE c1 CURSOR FOR
SELECT CAST(salary AS DOUBLE) FROM employee
WHERE workdept = deptNumber
ORDER BY salary;
DECLARE EXIT HANDLER FOR NOT FOUND
SET medianSalary = 6666;
10
create procedure 문으로 SQL 저장 프로시저를 생성합니다.
$ db2 connect to <데이터베이스명>
$ db2 -td@ -svf <파일명>
11
CALL 문을 이용하여 저장 프로시저를 호출합니다.
$ db2 "call myproc('A00',?)"
Value of output parameters
-------------------------Parameter Name : MEDIANSALARY
Parameter Value : +4.65000000000000E+004
Return Status = 0
SET medianSalary = 0;
SELECT COUNT(*) INTO v_numRecords FROM employee
WHERE workdept = deptNumber;
OPEN c1;
WHILE v_counter < (v_numRecords / 2 + 1) DO
FETCH c1 INTO medianSalary;
SET v_counter = v_counter + 1;
END WHILE;
CLOSE c1;
END @
U D B 개 발 자 기 본 교 육 • UNIT 11 • 프로그램 유형 223
TOPIC
11 06 사용자 정의 함수
01
1
사용자가 작성한 SQL 함수를 사용자 정의 함수라고 하며, 기존의 빌트인 SQL함수와 동일한 방법으로 SQL문에서 사용됩니다. 사용자 정의 함
수의 유형은 작성하는 언어와 반환하는 결과의 유형에 따라 7 가지로 분류됩니다.
유형
설명
외부 스칼라
C, Java 등의 프로그래밍 언어로 작성된 라이브러리를 이용하며, 스칼라 값을 반환합니다.
외부 테이블
C, Java 등의 프로그래밍 언어로 작성된 라이브러리를 이용하며, 테이블을 반환합니다.
OLE DB 외부 테이
블
OLE DB 공급자로부터 데이터를 액세스하기 위한 함수입니다.
소스 함수
기존의 내장, 외부, SQL, 소스 함수를 이용하여 작성된 함수입니다.
SQL 스칼라
SQL/PL 로 작성되며, 스칼라값을 반환합니다.
SQL 행
SQL/PL 로 작성되며, 행을 반환합니다.
SQL 테이블
SQL/PL 로 작성되며, 테이블을 반환합니다.
2
사용자 정의 함수는 SQL/PL, C, Java, OLE 등을 이용하여 생성합니다.
3
사용자 정의 함수에 대한 정보는 SYSCAT.ROUTINES 뷰를 이용해서 확인합니
4
db2look 명령어로 SQL 사용자 정의 함수에 대한 DDL문을 추출할 수 있습니
다.
$ db2 "select * from syscat.routines"
$ db2look –d <DB명> –e -o <출력파일명>
U D B 개 발 자 기 본 교 육 • UNIT 11 • 프로그램 유형 224
TOPIC
11 06 사용자 정의 함수
01
5
SQL 사용자 정의 함수를 위한 로직을 작성하여 임의의 <파일명>으로 저장합니
다.
$ cat <파일명>
6
create function 문으로 SQL 사용자 정의 함수를 생성합니다.
$ db2 connect to <데이터베이스명>
CREATE FUNCTION todate (x varchar(8))
$ db2 -td@ -svf <파일명>
RETURNS date
SPECIFIC TODATE01
LANGUAGE SQL
CONTAINS SQL
NO EXTERNAL ACTION
DETERMINISTIC
RETURN date(SUBSTR(X,1,4)||'-'||SUBSTR(X,5,2)||'-'||SUBSTR(X,7,2))
@
CREATE FUNCTION tan (X DOUBLE)
7
SQL문에서 기존 함수와 동일하게 사용자 정의 함수를 사용합니다
$ db2 –x " values(TODATE('20040101'))"
2004-01-01
$ db2 -x "SELECT id, salary, kes.percent(salary,5)
FROM kes.empl"
1 130 6.00
2 280 14.00
3 330 16.00
4 310 15.00
RETURNS DOUBLE
LANGUAGE SQL
CONTAINS SQL
NO EXTERNAL ACTION
DETERMINISTIC
RETURN SIN(X)/COS(X) @
CREATE FUNCTION kes.percent(number int, rate int)
RETURNS decimal(6,2)
F1: BEGIN ATOMIC
RETURN (number * rate) / 100;
END@
U D B 개 발 자 기 본 교 육 • UNIT 11 • 프로그램 유형 225
TOPIC
11 07 주석문
01
1
현재 주석문은 다음과 같은 수준입니다.
/**
* @Classs Name : CommonCodeServlet.class
* @description : 공통코드 리스트
* @author
이한일 : [email protected]
* @copyright (C) ICAN Corp.
* @date
2005/01/24
*/
2
향후 유지 보수를 위해 각 소스별로 기본 주석문과 변경 이력을 간결하고 정확
하게 표현합니다.
/*****************************************************************************
* 서브시스템
: 공통
*
* 프로그램명
: xx.sqc
*
* 처리 유형
:B
*
* 설명
: INFO 테이블을 읽어서 대상 테이블들을 매일 백업
* 입력 인수
: p_schema : 스키마명, p_table : 테이블명
* 출력 인수
: SUCCESS : 정상, FAILURE : 비정상
* 참고 사항
: DB2 Export API 사용
*
*
*
*
******************************************************************************
* 날짜
성명
함수명
내용
*
* ---------- -------- ----------------- ----------------------------------
*
* 2006-03-02 홍길동
*
신규 작성
*****************************************************************************/
U D B 개 발 자 기 본 교 육 • UNIT 11 • 프로그램 유형 226
TOPIC
11 08 exception 처리
01
1
2
Java 소스에서 일반적인 로직이나 SQL문 처리시 장애가 발생하면 대응하는 EXCEPTION 처리를 반드시 해주어야 합니다.

일반 Exception과 SQLException을 반드시 포함시키도록 합니다.

비정상 종료를 포함하여 프로그램 종료시에는 기존에 사용했던 자원에 대한 해제 작업을 반드시 하도록 합니다.

statment, pstatment, rs 등을 close 하여 사용한 메모리를 해제시킵니다.

rollback / commit 등을 실행하여 DB 자원에 대한 해제 작업을 수행합니다. 필요시에는 connection 도 해제합니다.

해당되는 Java 오류와 SQLCODE / SQLSTATE 등의 정보를 error log로 기록합니다.
현재는 Exception에 대한 처리가 되어 있으며, catch와 finally 에서 error log 기록과 자원 해제가 처리되어 있습니다. SQLException 처리
와 자원 해제가 누락된 소스가 없는지 확인하도록 합니다.
catch (Exception e) {
Logger.err.println("[com.kbstar.cti.svr.common.db.wrapper.CommonCodeDW.selectCommonCodeList()] " + e.toString());
throw e;
} finally {
try {
if (rs != null) rs.close();
} finally {
if (pstatement != null) pstatement.close();
}
}
U D B 개 발 자 기 본 교 육 • UNIT 11 • 프로그램 유형 227
TOPIC
11 09 dynamic SQL
01
1
2
jdbc를 이용하여 실행하는 SQL문은 dynamic SQL문이므로, 다음과 같은 이유로 가급적 prepared statement를 사용하도록 합니다.

조건절에 비교되는 값만 변하는 반복적인 SQL 문에 유리합니다.

statement로 처리하면, SQL문이 달라질 때마다 새롭게 compile을 해야 하므로 성능이 저하됩니다.
현재 java 소스에서는 다음과 같이 parameter marker를 이용한 prepared statement를 사용하고 있습니다.
String sql = "";
sql += " SELECT 정보항목코드, 인스턴스구분, 인스턴스명 ";
sql += " FROM TSCTIE1 ";
sql += " WHERE 정보항목코드 = ? And 사용여부 = '1' ";
try {
pstatement = conn.prepareStatement(sql);
pstatement.setString(1, itemCode.trim());
JDFPreparedStatement jdfStatement = new JDFPreparedStatement(this, sql, pstatement);
rs = jdfStatement.executeQuery();
. . .
U D B 개 발 자 기 본 교 육 • UNIT 11 • 프로그램 유형 228
TOPIC
11 10 WITH UR
01
1
2
정확성이 필요하지 않는 조회 로직에서 SELECT문에 WITH UR 옵션을 추가적으로 이용하면 concurrency가 높아집니다.

기본적으로 SELECT문은 commit 되지 않은 UPDATE/INSERT/DELETE 데이터를 조회할 수 없습니다.

SELECT문이 실행되는 동안에는 S 잠금이 기본적으로 적용되어, 해당 데이터를 UPDATE/DELETE 하려는 application들은 잠금이
해제될 때까지 기다려야 합니다.

WITH UR 옵션을 SELECT문에 추가하면, SELECT문을 실행시에 S 잠금을 적용하지 않으므로, 다른 application 들은 대기 없이
해당 데이터를 access 할 수 있습니다. 또한, 다른 application이 commit이 하지 않은 데이터도 대기하지 않고 조회할 수 있습니다.
WITH UR 옵션은 SELECT문에 개별적으로 추가할 수 있습니다.
String sql = "";
sql += " SELECT 정보항목코드, 인스턴스구분, 인스턴스명 ";
sql += " FROM TSCTIE1 ";
sql += " WHERE 정보항목코드 = ? And 사용여부 = '1' ";
sql += " with ur ";
3
setTransactionIsolation 메소드를 이용하면, connection 단위로 WITH UR을 적용합니다. 해당 connection이 해제되기 전까지 실행되는 개
별적인 SELECT문에는 WITH UR 옵션이 자동적으로 적용됩니다.
con=DriveManager.getConnection(url);
con.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED) ;
String sql = "";
sql += " SELECT 정보항목코드, 인스턴스구분, 인스턴스명 ";
sql += " FROM TSCTIE1 ";
sql += " WHERE 정보항목코드 = ? And 사용여부 = '1' ";
U D B 개 발 자 기 본 교 육 • UNIT 11 • 프로그램 유형 229
TOPIC
11 11 기타 고려 사항
01
1
2
3
인덱스를 효율적으로 사용하도록 SQL문을 표현합니다.

조건절에 표현된 조건절에서 최대한 처리 대상의 범위를 줄이도록 합니다.

조건절을 적용한 후에도 처리 대상의 범위가 너무 넓으면 인덱스 사용은 오히려 성능을 저하시킬 수도 있습니다.

대부분은 복합 인덱스이므로 복합 인덱스의 컬럼 순서대로 조건을 명시하도록 합니다. 예를 들어, (A,B,C) 로 구성된 복합 인덱스에서
조건절에 C 컬럼만 명시하면 인덱스는 사용되지 않습니다.
처리 건수는 가능한 줄여야 합니다.

연산식이 많은 쿼리는 처리하는 데이터 건수가 많을수록 CPU 사용율이 상당히 높아집니다.

조건절에 최대한의 조건을 표현하여 filtering 후에는 최소 건수만 남길 수 있도록 표현합니다.

SQL문 작성시 * 는 절대로 사용하지 말고, 반드시 필요한 컬럼만 선택하도록 합니다. 불필요한 컬럼들을 Sort하거나 Hash 작업에서 Size
가 큰 경우 불필요한 자원을 사용하게 되므로 성능 저하의 원인이 됩니다.
DB를 계산기 용도로 사용하지 않도록 합니다.

단순 연산을 위한 용도로 SQL문을 실행하면, DB의 자원을 사용하게 되어 집중적으로 사용하는 경우 시스템에 부하를 주게 됩니다.

데이터와 무관한 연산인 경우에는 일반적인 연산식으로 처리하는 것이 성능에 도움이 됩니다.
SELECT 100.0 + 200.0 FROM sysibm.sysdummy1;
SELECT 123 45.0
FROM sysibm.sysdummy1;
U D B 개 발 자 기 본 교 육 • UNIT 11 • 프로그램 유형 230
TOPIC
12
01
UNIT12
SQLPL
UDB개발자기본교육
SP 기본 구조
SP 예제 코드
주석문
SP 이름과 매개 변수 선언
SPECIFIC 옵션
RESULT SETS 옵션
LANGUAGE 옵션
COMPOUND SQL 블록
NOT ATOMIC 옵션
ATOMIC 옵션
COMMIT, ROLLBACK, SAVEPOINT 문
변수 선언, 초기화, 값 할당
SQLCODE, SQLSTATE, 반환용 변수 선언
CURSOR 선언
오류 CONDITION 선언
오류 HANDLER 처리 로직 정의
LOGIC FLOW CONTROL 문
DYNAMIC SQL 문
GET DIAGNOSTICS 문
SIGNAL 문
실행 권한 제어
U D B 개 발 자 기 본 교 육 • UNIT 12 • S Q L P L 231
TOPIC
1201 SP 기본 구조
01
------------------------------------ 주석문
------------------------------------ 프로그램ID : INST01.SP01
-- 업 무 명 : 계약정보관리
------------------------------------ SP 및 매개 변수 선언
----------------------------------CREATE PROCEDURE inst01.sp01
( IN
p_deptno
CHAR(3),
OUT p_message
VARCHAR(100) )
------------------------------------ SPECIFIC NAME 설정
----------------------------------SPECIFIC DELETE_DEPT
------------------------------------ RESULT SET 개수 설정
----------------------------------DYNAMIC RESULT SETS 1
------------------------------------ SP 작성 언어 설정
----------------------------------LANGUAGE SQL
------------------------------------ 본문 시작
----------------------------------BEGIN --첫번째 BEGIN
------------------------------------ 반환용 변수 선언 및 초기화
----------------------------------DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
DECLARE SQLCODE INT DEFAULT 0;
DECLARE v_ret_value INT DEFAULT 0;
------------------------------------ CONDITION 선언
-----------------------------------------------------DECLARE c_emp_child_rows_exist CONDITION FOR SQLSTATE '99001';
------------------------------------ CURSOR 선언
----------------------------------DECLARE C1 CURSOR FOR SELECT문;
------------------------------------ HANDLER 선언
----------------------------------DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
SET p_message = 'Unknown error, SQLSTATE: "' || SQLSTATE ||
'", SQLCODE=' || CHAR(SQLCODE);
SET v_ret_value = -1;
END;
------------------------------------ 로직 구현 (SQL구성 및 실행)
------------------------------------ Logic 처리
END --첫번째 END
------------------------------------ 로컬 변수 선언 및 초기화
----------------------------------DECLARE v_num_rows INT DEFAULT 0;
------------------------------------ 명령 종료 문자
----------------------------------@
U D B 개 발 자 기 본 교 육 • UNIT 12 • S Q L P L 232
TOPIC
1202 SP 예제 코드
01
-- 이것은 SP 샘플 코드입니다.
CREATE PROCEDURE inst01.sp01
( IN p_deptno
OUT p_message
-- 사용자 정의 핸들러 선언
DECLARE EXIT HANDLER FOR c_emp_child_rows_exist
BEGIN
SET p_message = ‘child EMPLOYEE rows exist.';
SET v_ret_value = -1;
END;
CHAR(3),
VARCHAR(100) )
SPECIFIC delete_dept
DYNAMIC RESULT SET 1
LANGUAGE SQL
-- Child table: EMPLOYEE
SELECT COUNT(1) INTO v_num_rows
FROM employee
WHERE workdept = p_deptno;
BEGIN
-- SQLCODE, SQLSTATE, 반환용 변수 선언
DECLARE SQLCODE INT DEFAULT 0;
DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
DECLARE v_ret_value INT DEFAULT 0;
-- EMPLOYEE 에 데이터 존재하는 경우, SIGNAL 발생
IF v_num_rows <> 0 THEN
SIGNAL c_emp_child_rows_exist;
END IF;
-- MAIN 시작
body:BEGIN
-- DEPARTMENT 데이터 삭제
DELETE FROM department WHERE deptno = p_deptno;
-- 삭제된 ROW_COUNT 검사
GET DIAGNOSTICS v_num_rows = ROW_COUNT;
-- 지역 변수 선언
DECLARE v_num_rows INT DEFAULT 0;
-- CONDITION 선언
DECLARE c_emp_child_rows_exist CONDITION FOR
SQLSTATE '99001';
-- CURSOR 선언
DECLARE c1 CURSOR FOR
SELECT * FROM department WHERE deptno = p_deptno;
-- 시스템 핸들러 선언
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
SET p_message = ‘오류 : SQLSTATE: ‘ ||
SQLSTATE ||’,’|| CHAR(SQLCODE);
SET v_ret_value = -1;
END;
-- 반환 메시지 지정
IF v_num_rows = 0 THEN
BEGIN
SET v_ret_value = 1;
SET p_message = ‘데이터가 없습니다 : ‘ || p_deptno;
END;
ELSE
SET p_message = p_deptno || ‘가 삭제되었습니다.’ ;
END IF;
END body;
OPEN c1;
RETURN v_ret_value;
END
U D B 개 발 자 기 본 교 육 • UNIT 12 • S Q L P L 233
TOPIC
1203 주석문
01
여러 행에 걸친 주석문은 /* -- */ 를 이용하며, 한 행에 해당하는 주석문은 –- 를 이용하여 지정해도 됩니다.
/*********************************************************************************************************************************
** 프로그램ID
: inst01_sp01
** 업무명
: Sample Stored Procedure
** 프로그램명
: inst01_sp01.db2
** 최초 작성일 : 2004-06-08
** 최종 작성일 : 2004-06-08
** 최종 수정일 : 2004-06-08
** 개발자
: Kim Eun Sook
** 수정자
: Kim Eun Sook
** 입력값
: p_deptno (부서 코드)
** 출력값
: p_message (오류 메시지)
** 참고사항
: 없음
** 변경이력
: 없음
** 실행예제
: call inst01,sp01(‘E01’,?)
********************************************************************************************************************************/
CREATE PROCEDURE inst01.sp01 ( IN p_deptno
OUT p_message
SPECIFIC delete_dept
DYNAMIC RESULT SET 1
LANGUAGE SQL
CHAR(3),
VARCHAR(100) )
BEGIN
-- SQLCODE, SQLSTATE, 반환용 변수 선언
DECLARE SQLCODE INT DEFAULT 0;
DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
DECLARE v_return INT DEFAULT 0;
-- SQLCODE 변수
-- SQLSTATE 변수
-- SP 실행 상태 변수
body:BEGIN
-- 지역 변수 선언
DECLARE v_num_rows INT DEFAULT 0;
U D B 개 발 자 기 본 교 육 • UNIT 12 • S Q L P L 234
TOPIC
1204 SP 이름과 매개 변수 선언
01
SP 이름을 지정할 때는 스키마명을 명시하도록 합니다.
CREATE PROCEDURE TEST.SP01
(IN
IN
P_EMPID
INTEGER,
P_PERCENTINCR
DECIMAL(4,2),
OUT P_UPDATED_SALARY
INT )
스키마명이 생략된 경우 기본 스키마명은 레지스터리 변수인 "CURRENT SCHEMA" 에 의해 결정됩니다. CURRENT SCHEMA 가 지정되어
있지 않은 경우에는 현재 접속한 사용자의 ID 를 기본값으로 제공합니다. 사용자명이 INST01 이라면 다음의 경우에 INST01.SP01 로 해석
됩니다.
CREATE PROCEDURE SP01
(IN
IN
P_EMPID
INTEGER,
P_PERCENTINCR
DECIMAL(4,2),
OUT P_UPDATED_SALARY
INT )
매개 변수는 모드, 변수 이름, 데이터 유형 등의 세 가지 부분으로 구성됩니다. 매개 변수의 모드에는 IN, OUT, INOUT의 세 가지가 있습니다.
CREATE PROCEDURE TEST.SP01
(IN
IN
P_EMPID
INTEGER,
P_PERCENTINCR
DECIMAL(4,2),
OUT P_UPDATED_SALARY
INT )
매개 변수가 없는 경우에는 () 만 입력하면 됩니다.
CREATE PROCEDURE TEST.SP02 ()
U D B 개 발 자 기 본 교 육 • UNIT 12 • S Q L P L 235
TOPIC
1205 SPECIFIC 옵션
01
동일한 SP 이름을 가지고 있으나, 매개 변수의 개수가 다른 SP를 여러 개 생성할 수 있습니다. 이를 "PROCEDURE OVERLOADING"이라 합
니다.
이 경우에는 SPECIFIC절을 지정하며, 이 이름을 이용하여 SP를 DROP 합니다. 지정되는 이름은 한 데이터베이스내에서 고유해야 합니다.
 매개 변수가 3개인 SP
CREATE PROCEDURE sum(IN p_a INTEGER, IN p_b INTEGER, OUT p_s INTEGER)
SPECIFIC sum_ab
LANGUAGE SQL
BEGIN
SET p_s = p_a + p_b;
END
 매개 변수가 4개인 SP
CREATE PROCEDURE sum(IN p_a INTEGER,IN p_b INTEGER, IN p_c INTEGER, OUT p_s INTEGER)
SPECIFIC sum_abc
LANGUAGE SQL
BEGIN
SET p_s = p_a + p_b + p_c;
END
CLP 를 이용하는 경우 다음과 같이 호출합니
다.
CALL sum(100,200,?)
CALL sum(100,200,300,?)
CLP 를 이용하는 경우 다음과 같이 SPECIFIC NAME 을 이용하여 DROP 합니
다.
DROP PROCEDURE sum(INTEGER,INTEGER,INTEGER)
DROP PROCEDURE SPECIFIC sum_abc
U D B 개 발 자 기 본 교 육 • UNIT 12 • S Q L P L 236
TOPIC
1206 RESULT SETS 옵션
01
다음과 같은 방법으로 한 개 이상의 Result Set을 반환할 수 있습니다. SP, CLP, java 등을 이용하여 반환된 결과 집합을 처리할 수 있습니다.
 CREATE PROCEDURE문장 내에 DYNAMIC RESULT SETS 절을 기술합니다.
 WITH RETURN절과 함께 커서를 선언합니다.
 커서를 오픈한 채로 SP를 종료합니다.
CREATE PROCEDURE emp_multi()
SPECIFIC emp_multi
DYNAMIC RESULT SETS 2
LANGUAGE SQL
re: BEGIN
DECLARE v_comm DEC(9,2) DEFALUT 0.0;
DECLARE c_salary CURSOR WITH RETURN FOR
SELECT salary FROM employee;
DECLARE c_bonus CURSOR WITH RETURN FOR
SELECT bonus FROM employee;
DECLARE c_comm CURSOR
SELECT comm FROM employee;
CREATE PROCEDURE receive_multi (IN
p_dept CHAR(3),
OUT
p_names VARCHAR(100),
OUT
p_total
DECIMAL(9,2) )
SPECIFIC receive_multi
LANGUAGE SQL
rm: BEGIN
DECLARE v_fname VARCHAR(12) DEFAULT '';
DECLARE v_lname VARCHAR(15) DEFAULT '';
DECLARE v_salary DECIMAL(9,2) DEFAULT 0.0;
DECLARE v_rs1, v_rs2, v_rs3 RESULT_SET_LOCATOR VARYING;
DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
CALL emp_multi();
ASSOCIATE RESULT SET LOCATOR (v_rs1, v_rs2) WITH PROCEDURE emp_multi;
ALLOCATE v_rsCur1 CURSOR FOR RESULT SET v_rs1;
ALLOCATE v_rsCur2 CURSOR FOR RESULT SET v_rs2;
SET p_names = 'The employees are:';
OPEN c_comm;
FETCH c_comm INTO v_comm;
WHILE ( SQLSTATE = '00000' ) DO
SET p_total = p_total + v_comm;
FETCH c_comm INTO v_comm;
END WHILE;
OPEN c_salary;
OPEN c_bonus;
RETURN p_total;
END re
WHILE (SQLSTATE = '00000') DO
SET p_names = p_names || v_fname || ' ' || v_lname || ' ';
FETCH FROM v_rsCur1 INTO v_fname;
FETCH FROM v_rsCur2 INTO v_lname;
END WHILE;
SET p_total = 0;
WHILE ( SQLSTATE = '00000' ) DO
SET p_total = p_total + v_salary;
FETCH FROM v_rsCur3 INTO v_salary;
END WHILE;
END rm
U D B 개 발 자 기 본 교 육 • UNIT 12 • S Q L P L 237
TOPIC
1207 LANGUAGE 옵션
01
SP 를 작성하는 방법은 여러 가지가 있습니다.
 SQL/PL
 C, COBOL, FOTRAN, …
 JAVA
 OLE
SQL/PL 을 이용하여 SP를 개발하는 경우에는 LANGUAGE SQL 이라고 명시합니다.
CREATE PROCEDURE inst01.sp01
( IN p_deptno
OUT p_message
CHAR(3),
VARCHAR(100) )
SPECIFIC delete_dept
DYNAMIC RESULT SET 1
LANGUAGE SQL
BEGIN
-- SQLCODE, SQLSTATE, 반환용 변수 선언
DECLARE SQLCODE INT DEFAULT 0;
DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
DECLARE v_return INT DEFAULT 0;
-- MAIN 시작
body:BEGIN
-- 지역 변수 선언
DECLARE v_num_rows INT DEFAULT 0;
-- CONDITION 선언
DECLARE c_emp_child_rows_exist CONDITION FOR SQLSTATE '99001';
-- CURSOR 선언
DECLARE c1 CURSOR FOR SELECT * FROM department WHERE deptno = p_deptno;
U D B 개 발 자 기 본 교 육 • UNIT 12 • S Q L P L 238
TOPIC
1208 COMPOUND SQL 블럭
01
SP의 본문은 한 개 이상의 COMPOUND SQL 블럭으로 구성됩니다. 각 블록의 형식은 다음과 같습니다. 연관된 SQL 문들은 한 블럭안에 코
딩합니다. 블록 내부에 변수, CURSOR, CONDITION, HANDLER, Flow Control 등을 코딩할 수 있습니다. 한 블록 내에서의 코딩 순서는 아
래와 같습니다.
한 개 이상의 Compound SQL 블럭을 중첩하여 정의할 수 있습니다. 외부 블록에서는 내부 블럭에 선언된 변수를 사용할 수 없지만, 내부
블록에서는 외부 블럭에 선언된 변수를 사용할 수 있습니다.
-- 외부 블록
레이블명: BEGIN
변수 선언
컨디션 선언
반환용 변수 선언
커서 선언
핸들러 선언
SQL문 및 각종 로직 구현 문장
-- 내부 블록 1
레이블명: BEGIN
변수 선언
컨디션 선언
반환용 변수 선언
커서 선언
핸들러 선언
SQL문 및 각종 로직 구현 문장
END 레이블명
-- 내부 블록 2
레이블명: BEGIN
변수 선언
컨디션 선언
반환용 변수 선언
커서 선언
핸들러 선언
SQL문 및 각종 로직 구현 문장
END 레이블명
END 레이블명
-- 외부 블록 시작
BEGIN
-- 외부 블록 변수
DECLARE v_outer1 INT;
DECLARE v_outer2 INT;
DECLARE v_outer3 INT;
-- 내부 블록 시작
BEGIN
-- 내부 블럭 변수
DECLARE v_inner1 INT;
DECLARE v_inner2 INT;
DECLARE v_inner3 INT;
-- 변수 값 할당
SET v_outer1 = 100;
SET v_inner1 = 200;
-- 외부 블록 변수 참조
-- 내부 블록 종료
END;
-- 변수 값 할당
SET v_outer2 = 300;
SET v_inner2 = 400;
-- 내부 블록 변수 참조 (오류 발생)
-- 외부 블록 종료
END
U D B 개 발 자 기 본 교 육 • UNIT 12 • S Q L P L 239
TOPIC
1209 NOT ATOMIC 옵션
01
Compound 블록에 ATOMIC 옵션을 기술하지 않으면 기본적으로 NOT AUTOMIC 모드로 정의됩니다. NOT AUTOMIC 절은 선택적으로
사용할 수 있으나, SQL 코드의 모호성을 피하기 위해 명시적으로 사용하는 것이 권장됩니다. NOT ATOMIC 옵션을 지정하면, 블록 내의 모
든 SQL문은 독립적으로 간주되므로, 오류가 발생한 SQL문은 무시됩니다. COMMIT / ROLLBACK 을 이용하여 제어할 수 있습니다.
CREATE PROCEDURE not_atomic_proc ()
SPECIFIC not_atomic_proc
LANGUAGE SQL
첫 번째 insert 문이 commit 된 후, 오류가
발생하였으므로 atomic_test 테이블에는 한
BEGIN NOT ATOMIC
건의 데이터가 이미 입력되었습니다.
DECLARE v_job VARCHAR(8);
INSERT INTO atomic_test(proc, res)
VALUES ('Not_Atomic_Proc','Before error test');
COMMIT;
$ db2 "delete from atomic_test"
SIGNAL SQLSTATE '70000';
PROC
RES
-------------------- --------------------
INSERT INTO atomic_test(proc, res)
VALUES ('Not_Atomic_Proc','After error test');
END
$ db2 "select * from atomic_test"
0 레코드가 선택됨.
$ db2 "call not_atomic_proc()"
SQL0438N 응용프로그램이 진단 텍스트 ""과(와) 함께 오류를 표시했습니다.
SQLSTATE=70000
CREATE TABLE ATOMIC_TEST
( PROC VARCHAR(20),
RES VARCHAR(20) )
$ db2 "select * from atomic_test"
PROC
RES
-------------------- -------------------Not_Atomic_Proc
Before error test
1 레코드가 선택됨.
U D B 개 발 자 기 본 교 육 • UNIT 12 • S Q L P L 240
TOPIC
1210 ATOMIC 옵션
01
ATOMIC 옵션을 사용하면 Compound 블록 내의 문장들이 단일 문장으로 처리됩니다. 만약 블록 내의 임의의 문장을 실행하다가 오류가
발생하면 블록 내에서 이미 실행된 모든 문장들이 롤백 처리됩니다. ATOMIC 옵션을 가진 Compound 블록 내에서는 COMMIT,
ROLLBACK, SAVEPOINTS 문장과 중첩된 ATOMIC Compound 블럭을 기술 할 수 없습니다.
CREATE PROCEDURE atomic_proc ()
SPECIFIC atomic_proc
LANGUAGE SQL
BEGIN ATOMIC
DECLARE v_job VARCHAR(8);
두 개의 insert 문이 모두 rollback 되므로
atomic_test 테이블에는 데이터가 한 건도 없
습니다.
INSERT INTO atomic_test(proc, res)
VALUES ('Atomic_Proc','Before error test');
$ db2 "delete from atomic_test"
SIGNAL SQLSTATE '70000';
$ db2 "select * from atomic_test"
INSERT INTO atomic_test(proc, res)
VALUES ('Atomic_Proc','After error test');
PROC
RES
-------------------- --------------------
END
0 레코드가 선택됨.
$ db2 "call atomic_proc()"
SQL0438N 응용프로그램이 진단 텍스트 ""과(와) 함께 오류를 표시했습니다.
SQLSTATE=70000
$ db2 "select * from atomic_test"
PROC
RES
-------------------- -------------------0 레코드가 선택됨
U D B 개 발 자 기 본 교 육 • UNIT 12 • S Q L P L 241
TOPIC
1211 COMMIT, ROLLBACK, SAVEPOINT 문
01
ROLLBACK문은 실행 중에 오류가 발생하면 한 UOW 단위로 그 실행을 취소하게 합니다. ROLLBACK TO SAVEPOINT 문을 이용하면 한
UOW 내에서 SAVEPOINT가 지정된 시점부터 ROLLBACK 이 요청된 시간 사이의 변경 부분만 실행을 취소할 수 있습니다. ROLLBACK 과
COMMIT 문은 ATOMIC Compound 블럭내에서는 사용할 수 없습니다. SAVEPOINT문, ROLLBACK TO SAVEPOINT문, RELESE
SAVEPOINT 문 등을 이용합니다
CREATE PROCEDURE bonus_incr ()
SPECIFIC bonus_incr
LANGUAGE SQL
bi: BEGIN
DECLARE
DECLARE
DECLARE
DECLARE
DECLARE
DECLARE
v_dept, v_actdept CHAR(3);
v_bonus DECIMAL(9,2);
v_deptbonus DECIMAL(9,2);
v_newbonus DECIMAL(9,2);
v_empno CHAR(6);
v_atend SMALLINT DEFAULT 0;
DECLARE c_sales CURSOR WITH HOLD FOR
SELECT workdept, bonus, empno
FROM employee
ORDER BY workdept;
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET v_atend=1;
IF v_atend = 0 THEN
SAVEPOINT svpt_bonus_incr ON ROLLBACK RETAIN CURSORS;
SET v_actdept = v_dept;
SET v_deptbonus = 0;
WHILE ( v_actdept = v_dept ) AND ( v_atend = 0 ) DO
SET v_newbonus = v_bonus * 1.1;
UPDATE employee
SET bonus = v_newbonus
WHERE empno = v_empno;
SET v_deptbonus = v_deptbonus + v_newbonus;
FETCH c_sales INTO v_dept, v_bonus, v_empno;
END WHILE;
IF v_deptbonus <= 3000.00 THEN
COMMIT;
ELSE
ROLLBACK TO SAVEPOINT svpt_bonus_incr;
RELEASE SAVEPOINT svpt_bonus_incr;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
SET v_atend=1;
END IF;
OPEN c_sales;
GOTO nextdept;
FETCH c_sales INTO v_dept, v_bonus, v_empno;
nextdept:BEGIN
END IF;
END nextdept;
END bi
U D B 개 발 자 기 본 교 육 • UNIT 12 • S Q L P L 242
TOPIC
1212
01
변수 선언, 초기화, 값
할당
DECLARE 문을 사용하여 변수를 정의할 수 있습니다. 각 변수의 정의는 변수 이름, 데이터 유형 및 기본값으로 구성됩니다. 변수는 반드시
BEGIN~END사이의 블록에서 첫 부분에 선언되어야 합니다. 변수 이름은 SP에 사용된 테이블의 컬럼명과 구별되는 것이 좋습니다. 다음과
같이 접두어를 구별하여 매개 변수인지 일반 변수인지를 구별하는 것도 좋습니다.
 v_ : 일반 변수 접두어
 p_ : 매개 변수 접두어
변수가 선언되면 NULL로 초기화 되며, DEFAULT절을 이용하여 특정 값으로 초기화할 수 있습니다.
CREATE PROCEDURE proc_with_variables
(IN p_empno CHAR(4),
OUT p_msg VARCHAR(100))
SPECIFIC proc_with_vars
LANGUAGE SQL
BEGIN
DECLARE
DECLARE
DECLARE
DECLARE
v_rcount INTEGER;
v_name CHAR(10) DEFAULT ‘’;
v_adate,v_another DATE;
v_total INTEGER DEFAULT 0;
-- Default값을 이용
SET v_total = v_total + 1;
SET v_name = ‘KIM’;
-- SET을 이용
SELECT MAX(EMPNO) INTO v_max FROM PLAYERS;
-- Select를 이용
VALUES CURRENT DATE INTO v_adate;
-- VALUES를 이용
VALUES CURRENT DATE, CURRENT DATE INTO v_adate,v_another;
-- 레지스터를 이용
DELETE FROM EMPLOYEE WHERE EMPNO = ‘000100’;
GET DIAGNOSTICS rcount = ROW_COUNT;
-- GET DIAGNOSTICS을 이용
U D B 개 발 자 기 본 교 육 • UNIT 12 • S Q L P L 243
TOPIC
1213 SQLCODE, SQLSTATE, 반환용 변수 선언
01
SQLCODE와 SQLSTATE는 SQL문이 실행될 때마다 변경되는 값입니다. SQL문의 실행 결과의 성공 여부를 확인하기 위해 SQLCODE,
SQLSTATE를 이용하려면 그 값을 저장할 로컬 변수를 선언합니다.
SQLSTATE : ISO/ANSI SQL92 표준의 5자리 문자를 반환합니다.
00000, 00 : Successful completion
01
: Warning
02
: not found condition
SQLCODE : Database Product별 CODE 를 반환합니다.
0
+
-
: Executed successfully
: Successful completion but warning message
: Error Occurred
RETURN문장을 만나면 SP는 종료됩니다. OUT 모드로 선언된 매개 변수를 이용하여 값을 반환하려면 RETURN 문이 실행되기 전에 출력용
변수에 값을 할당해야 합니다. OUT 모드의 변수가 없어도 RETURN 문을 이용하여 기본적으로 한 개의 값을 반환할 수 있습니다. 명시적인
RETURN 문을 사용하지 않고, SP가 정상적으로 종료되면 0 이 반환됩니다. RETURN 문과 함께 반환될 변수를 선언합니다.
CREATE PROCEDURE simple_error
(IN p_empno CHAR(6),
OUT p_msg
VARCHAR(100))
SPECIFIC simple_error
LANGUAGE SQL
se: BEGIN
DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
DECLARE SQLCODE INT DEFAULT 0;
CREATE PROCEDURE return_test ( IN p_empno
CHAR(6),
IN p_emplastname VARCHAR(15) )
SPECIFIC return_test
LANGUAGE SQL
rt: BEGIN
DECLARE v_lastname VARCHAR(15);
DECLARE v_ret INTEGER DEFAULT 1;
UPDATE employee SET midinit = ‘xx’
WHERE empno = p_empno;
SELECT lastname INTO v_lastname FROM EMPLOYEE
WHERE empno = p_empno;
IF (SQLCODE <> 0) THEN
SET p_msg = "update 오류";
END IF;
SET p_msg = "update 성공";
IF v_lastname = p_emplastname THEN
SET v_ret = 2;
END IF;
END se
RETURN v_ret ;
END rt
U D B 개 발 자 기 본 교 육 • UNIT 12 • S Q L P L 244
TOPIC
1214 CURSOR 선언
01
한 건 이상의 데이터를 조회한 결과를 보관하기 위해 커서를 선언합니다. COMMIT 이후에도 커서의 포인터를 유지하려면 WITH HOLD 옵션
을 이용하면 됩니다. POSITIONED UPDATE와 DELETE 를 지원합니다.
CURSOR 선언문에 CURRENT DATE, CURRENT TIME, CURRENT TIMESTAMP 레지스터를 포함한 경우, 모든 FETCH문에 동일한 값을 반환합
니다. 레레지스터의 값은 OPEN CURSOR 에서 결정됩니다.
CREATE PROCEDURE total_raise
(
IN
p_min
DEC(4,2),
IN
p_max
DEC(4,2),
OUT
p_total
DEC(9,2) )
SPECIFIC total_raise
LANGUAGE SQL
tr: BEGIN
DECLARE v_salary DEC(9,2);
DECLARE v_bonus DEC(9,2);
DECLARE v_comm DEC(9,2);
DECLARE v_raise DEC(4,2);
DECLARE v_job VARCHAR(15) DEFAULT 'PRES';
DECLARE SQLSTATE CHAR(5);
DECLARE c_emp CURSOR FOR
SELECT salary, bonus, comm
FROM employee
WHERE job != v_job;
OPEN c_emp;
SET p_total = 0;
FETCH FROM c_emp INTO v_salary, v_bonus, v_comm;
WHILE ( SQLSTATE = '00000' ) DO
SET v_raise = p_min;
IF ( v_comm < 2000 ) THEN
SET v_raise = v_raise + 0.03;
ELSEIF ( v_comm < 3000 ) THEN
SET v_raise = v_raise + 0.02;
ELSE
SET v_raise = v_raise + 0.01;
END IF;
IF ( v_raise > p_max ) THEN
SET v_raise = p_max;
END IF;
SET p_total = p_total + v_salary * v_raise;
FETCH FROM c_emp INTO v_salary, v_bonus, v_comm;
END WHILE;
CLOSE c_emp;
END tr
하나 이상의 행을 반환하는 경우에는 반드시 커서를 이용해야 합니다. 다음의 문장은 오류를 발생시킵니다. 첫 번째 한 건만 원하는 경우
에는 커서를 정의하지 말고, FETCH FIRST 옵션을 이용하여 SELECT 하는 것이 좋습니다.
SET v_c1 = (SELECT c1 FROM t1); -- 한 건 이상인 경우 오류 발생.
SET v_c1 = (SELECT c1 FROM t1 FETCH FIRST 1 ROW ONLY); -- 한 건만 FETCH 하는 경우 효율적.
U D B 개 발 자 기 본 교 육 • UNIT 12 • S Q L P L 245
TOPIC
1215 Logic Flow Control 문
01
SP 본문의 로직을 구현하기 위해 사용되는 IF, CASE, GO TO, RETURN, WHILE, FOR, LOOP, ITERATE, LEAVE 문의 기본적인 사용 예는 다음과
같습니다.
-- IF 문
IF rating = 1 THEN
SET salary = salary * 1.10;
ELSEIF rating = 2 THEN
SET salary = salary * 1.05;
ELSE
SET salary = salary * 1.03;
END IF;
-- CASE 문
CASE rating
WHEN 1 THEN
SET SALARY = SALARY *1.10;
WHEN 2 THEN
SET SALARY = SALARY *1.05;
ELSE
SET SALARY = SALARY *1.03;
END CASE;
-- GO TO 문
IF v_service > (CURRENT DATE - 1 year) THEN
GOTO exit;
END IF;
SET v_new_salary = v_new_salary + 10;
exit:
SET p_adjusted_salary = v_new_salary;
-- WHILE 문
WHILE (v_current <= p_end) DO
SET v_temp = v_temp + v_current;
SET v_current = v_current + 1;
END WHILE;
-- LOOP 문
L1: LOOP
SELECT 1 INTO v_tmp FROM employee WHERE empno = v_current_id;
SET v_salary = p_salary * 2
IF (SQLCODE <> 0) THEN
LEAVE L1;
END IF;
END LOOP L1;
-- FOR 문
SET fullname=‘’;
FOR vl AS SELECT firstnme, midinit, lastname FROM employee DO
SET fullname = lastname || ',' || firstnme ||' ' || midinit;
INSERT INTO tnames VALUE (fullname);
END FOR
-- ITERATE / LEAVE 문
ins_loop: LOOP
FETCH c1 INTO v_dept, v_deptname, v_admdept;
IF at_end = 1 THEN
LEAVE ins_loop;
ELSEIF v_dept = 'D11' THEN
ITERATE ins_loop;
END IF;
INSERT INTO department VALUES ('NEW', v_deptname, v_admdept);
END LOOP ins_loop;
-- RETURN 문
SELECT manager INTO v_manager FROM org WHERE empno = p_empno;
IF v_manager = p_manager THEN
RETURN 1;
ELSE
RETURN -1;
END IF;
U D B 개 발 자 기 본 교 육 • UNIT 12 • S Q L P L 246
TOPIC
1216
01
오류 CONDITION
선언
오류 처리를 위해 SP에서 사용할 수 있는 미리 정의된 시스템 Condition은 다음의 세 가지가 있습니다.
 SQLEXCEPTION
: SQLSTATE의 첫번째 두 자리가 00,01,02가 아닌 경우
 SQLWARNING
: SQLSTATE의 첫번째 두 자리가 01 또는 SQLCODE가 양수인 경우( +100 제외)
 NOT FOUND
: SQLSTATE의 첫번째 두 자리가 02 또는 SQLCODE가 +100인 경우
DECLARE ~ CONDITION 문을 이용하여 사용자가 특정 SQLSTATE 에 대한 Condition을 정의할 수도 있습니다.
 시스템 사용 SQLSTATE : ‘0’ ~ ‘6’ or ‘A’ ~ ‘H’ 로 시작하는 Class code와 subclass code
 사용자 정의 SQLSTATE : ‘7’ ~ ‘9’ or ‘I’ ~ ‘Z’ 로 시작하는 Class code와 subclass code
시스템에 정의 Condition 또는 사용자 정의 Condition은 DECLARE~HANDLER문, SIGNAL문 등과 함께 사용되어 오류 발생시 처리 내역
을 지정합니다,
CREATE PROCEDURE insert_update_department ()
SPECIFIC ins_upd_dept
LANGUAGE SQL
iud: BEGIN
DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
DECLARE SQLCODE INT DEFAULT 0;
DECLARE v_duplicate INT DEFAULT 0;
DECLARE v_num_rows INT DEFAULT 0;
DECLARE c_duplicate CONDITION FOR SQLSTATE '23505';
DECLARE c_too_many_rows CONDITION FOR SQLSTATE '99001';
DECLARE EXIT HANDLER FOR SQLEXCEPTION
SELECT SQLSTATE,SQLCODE INTO p_sqlstate_out,p_sqlcode_out FROM sysibm.sysdummy1;
DECLARE CONTINUE HANDLER FOR c_duplicate
SET v_duplicate = 1;
U D B 개 발 자 기 본 교 육 • UNIT 12 • S Q L P L 247
TOPIC
1217 오류 HANDLER 처리 로직 정의
01
SP 내부에 SQL문을 실행하면서 발생되는 예외 사항에 대한 처리를 명시하는 방법입니다. 시스템에 미리 정의된 Condition 및 사용자가 정의
한 Condition에 대해 Handler 유형을 지정하고, 상황에 대한 처리 방법을 정의할 수 있습니다. Handler 로직을 다중 문장으로 처리하는 경우
에는 BEGIN ~ END 로 표시되는 Compound 블록을 사용합니다. Handler의 유형으로는 다음의 세 가지가 있습니다.
 EXIT
: Handler 내부의 SQL문을 실행하고, Compound 블럭의 끝부분을 실행합니다.
 CONTINUE : Handler 내부의 SQL문을 실행하고, Exception이 발생한 다음 문장부터 실행을 계속합니다.
 UNDO
: Handler 내부의 SQL문을 실행하고, Compound 블럭내에서 실행된 모든 문장을 롤백한 후, Compound 블럭의 끝부분을
실행합니다.
CREATE PROCEDURE simple_error (IN p_midinit CHAR, IN p_empno CHAR(6), OUT p_sqlstate_out CHAR(5), OUT p_sqlcode_out INT )
SPECIFIC simple_error
LANGUAGE SQL
se: BEGIN
DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
DECLARE SQLCODE INT DEFAULT 0;
DECLARE v_duplicate INT DEFAULT 0;
DECLARE c_duplicate CONDITION FOR SQLSTATE '23505';
DECLARE c_too_many_rows CONDITION FOR SQLSTATE '99001';
DECLARE EXIT HANDLER FOR SQLEXCEPTION
SELECT SQLSTATE,SQLCODE INTO p_sqlstate_out,p_sqlcode_out FROM sysibm.sysdummy1;
DECLARE CONTINUE HANDLER FOR c_duplicate
SET v_duplicate = 1;
VALUES (SQLSTATE, SQLCODE) INTO p_sqlstate_out, p_sqlcode_out;
UPDATE employee SET midinit = p_midinit WHERE empno = p_empno;
END se
U D B 개 발 자 기 본 교 육 • UNIT 12 • S Q L P L 248
TOPIC
1218 DYNAMIC SQL문
01
EXECUTE IMMEDIATE, PREPARE ~ EXECUTE 등의 동적 SQL문을 사용할 수 있습니다. 매개 변수 표시 문자인 ? 를 이용하여 PREPPARE와
EXECUTE를 분리시키면 동일한 SQL문을 다시 PREPARE 하지 않으므로 성능을 향상시킬 수 있습니다.
동적 SQL에 대한 보안 및 인증 관계는 실행시에 평가됩니다. 동적 SQL을 사용하기 위해 적절한 권한이 필요합니다.
CREATE PROCEDURE change_mgr_bonus (IN p_bonus_increase DECIMAL, OUT p_num_changes INT )
SPECIFIC change_mgr_bonus
LANGUAGE SQL
cmb: BEGIN
DECLARE v_dynSQL VARCHAR(200);
DECLARE v_new_bonus DECIMAL;
DECLARE v_no_data SMALLINT DEFAULT 0;
DECLARE v_mgrno CHAR(6);
DECLARE v_bonus DECIMAL;
DECLARE v_stmt1 STATEMENT;
DECLARE c_managers CURSOR FOR SELECT e.empno, e.bonus FROM EMPLOYEE e, DEPARTMENT d WHERE e.empno=d.mgrno;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_no_data=1;
SET v_dynSQL = 'UPDATE EMPLOYEE SET BONUS=? WHERE EMPNO=?';
SET p_num_changes=0;
PREPARE v_stmt1 FROM v_dynSQL;
OPEN c_managers;
FETCH c_managers INTO v_mgrno, v_bonus;
WHILE (v_no_data=0) DO
SET p_num_changes = p_num_changes + 1;
SET v_new_bonus = v_bonus + p_bonus_increase;
EXECUTE v_stmt1 USING v_new_bonus, v_mgrno;
FETCH c_managers INTO v_mgrno, v_bonus;
END WHILE;
CLOSE c_managers;
END cmb
U D B 개 발 자 기 본 교 육 • UNIT 12 • S Q L P L 249
TOPIC
1219 GET DIAGNOSTICS 문
01
GET DIAGNOSTICS 문은 실행한 SQL 문장과 연관된 정보를 수집하는데 사용합니다. ROW_COUNT 변수는 SELECT,INSERT,UPDATE,DELETE
등의 실행 후 관련된 레코드 건수를 반환하며, MESSAGE_TEXT는 오류 메시지를 반환합니다. RETURN_STATUS 를 이용하면 SP를 실행한 후
의 반환 코드를 확인할 수 있습니다.
CREATE PROCEDURE get_diag (IN p_empno CHAR(6))
SPECIFIC get_diag
LANGUAGE SQL
gd: BEGIN
DECLARE v_rows INT DEFAULT -1;
DELETE FROM employee WHERE empno like p_empno || '%';
GET DIAGNOSTICS v_rows = ROW_COUNT;
RETURN v_rows;
END gd
CREATE PROCEDURE simple_error_message
( IN
IN
OUT
SPECIFIC simple_error_msg
LANGUAGE SQL
sem: BEGIN
CREATE PROCEDURE TESTIT (IN p_empno VARCHAR(6))
LANGUAGE SQL
BEGIN
DECLARE v_retval INTEGER DEFAULT 0;
DECLARE v_note VARCHAR(20);
CALL get_diag (p_empno);
GET DIAGNOSTICS v_retval = RETURN_STATUS;
SET v_note = EMPNO || ':[' || CHAR(v_retval) || ']';
INSERT INTO NOTE VALUES (v_note);
END
p_midinit
CHAR(10),
p_empno
CHAR(6),
p_error_message VARCHAR(300) )
DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING
GET DIAGNOSTICS EXCEPTION 1 p_error_message = MESSAGE_TEXT;
SET p_error_message = '';
UPDATE employee
SET midinit = p_midinit
WHERE empno = p_empno;
END sem
SQL0727N An error occurred during
implicit system action type "1".
Information returned for the error
includes SQLCODE "-204", SQLSTATE
"42704" and message tokens
"DB2ADMIN.EMPLOYEE".
SQLSTATE=56098
U D B 개 발 자 기 본 교 육 • UNIT 12 • S Q L P L 250
TOPIC
1220 SIGNAL 문
01
시스템이 제공하는 SQL 오류 이외에 프로그램에서 사용자가 정의한 오류 Condition에 대한 Handler를 실행해야 하는 경우가 있습니다.
SIGNAL 문을 이용하여 사용자가 정의한 Condition 또는 SQLSTATE에 해당하는 처리 내역을 지정할 수 있습니다.
CREATE PROCEDURE insert_update_department (
IN
p_deptno
CHAR(3),
IN
p_deptname
VARCHAR(29),
IN
p_mgrno
CHAR(6),
IN
p_admrdept
CHAR(3),
IN
p_location
CHAR(16),
OUT p_sqlstate_out CHAR(5),
OUT p_sqlcode_out INT )
SPECIFIC ins_upd_dept
LANGUAGE SQL
iud: BEGIN
-- Declare variables
DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
DECLARE SQLCODE INT DEFAULT 0;
DECLARE v_duplicate INT DEFAULT 0;
DECLARE v_num_rows INT DEFAULT 0;
-- Declare condition
DECLARE c_duplicate CONDITION FOR
SQLSTATE '23505';
DECLARE c_too_many_rows CONDITION FOR
SQLSTATE '99001';
-- Declare handlers
DECLARE EXIT HANDLER FOR SQLEXCEPTION
SELECT SQLSTATE,SQLCODE
INTO p_sqlstate_out,p_sqlcode_out
FROM sysibm.sysdummy1;
DECLARE CONTINUE HANDLER FOR c_duplicate
SET v_duplicate = 1;
-- Initialize output parms
VALUES (SQLSTATE, SQLCODE)
INTO p_sqlstate_out,p_sqlcode_out;
-- See how many rows are already in the DEPARTMENT table
SELECT COUNT(1) INTO v_num_rows
FROM department;
-- Signal an error if more than 10 rows exist
IF v_num_rows > 10 THEN
SIGNAL c_too_many_rows
SET MESSAGE_TEXT = 'DEPARTMENT 에 데이터가 너무 많습니다.';
END IF;
-- Try insert, if duplicate, then update
INSERT INTO department
( deptno,deptname,mgrno,admrdept,location )
VALUES
( p_deptno,p_deptname,p_mgrno,p_admrdept,p_location);
IF v_duplicate = 1 THEN
-- only update if non-null value provided as input parameter
UPDATE department
SET deptname = coalesce(p_deptname, deptname)
,mgrno = coalesce(p_mgrno, mgrno)
,admrdept = coalesce(p_admrdept, admrdept)
,location = coalesce(p_location, location)
WHERE deptno = p_deptno;
END IF;
END iud
U D B 개 발 자 기 본 교 육 • UNIT 12 • S Q L P L 251
TOPIC
12 21 실행 권한 제어
01
특정 SP에 대한 제거 및 실행 권한은 기본적으로 SP를 생성한 사용자, DBADM, SYSADM 에게 있습니다. 다른 사용자가 해당 SP를 실행하게
하려면 그 ROUTINE 에 대한 EXECUTE 권한을 사용자 또는 그룹별로 부여해야 합니다.
$ db2 connect to smaple user inst01 using inst01
$ db2 "call inst01.sp01('000340')"
리턴 상태 = 1
$ db2 connect to smaple user user01 using user01
$ db2 "call inst01.sp01('000340')"
SQL0551N "USER01"에는 오브젝트 "INST01.SP01"에서 조작 "EXECUTE"을(를) 수행할 수 있는 특권이 없습니다. SQLSTATE=42501
$ db2 "select grantor, grantee, executeauth from syscat.routineauth where specificname = 'SP01'"
GRANTOR
GRANTEE
EXECUTEAUTH
---------------------------------------------------------------------------SYSIBM
YURIMAMA
G
$ db2 connect to smaple user inst01 using inst01
$ db2 grant execute on procedure inst01.sp01 to user01
$ db2 "select grantor, grantee, executeauth from syscat.routineauth where specificname = 'SP01'"
GRANTOR
GRANTEE
EXECUTEAUTH
---------------------------------------------------------------------------SYSIBM
INST01
G
INST01
USER01
Y
$ db2 connect to smaple user user01 using user01
$ db2 "call inst01.sp01('000340')"
리턴 상태 = 1
U D B 개 발 자 기 본 교 육 • UNIT 12 • S Q L P L 252
TOPIC
13
01
UNIT13
ESQL
UDB개발자기본교육
기본 구조
헤더 파일
SQL 구분자
호스트 변수
널 지시자 (Null Indicator)
db2dclgn 유틸리티
주요 SQL문
커서 처리
Positioned UPDATE / DELETE
복합 SQL (Compound SQL)
SQLCA
WHENEVER 문
정적 SQL
동적 SQL
매개 변수 표시 문자 (Parameter Marker)
생성 과정
프리컴파일
PREP 명령어
바인드 / BIND 명령어
컴파일과 링크 / xlc 명령어
팩키지
리바인딩
U D B 개 발 자 기 본 교 육 • UNIT 13 • E S Q L 253
TOPIC
13 01 기본 구조
01
 ESQL은 Embedded SQL의 약자로 소스 파일에는 특정 프로그래밍 언어와 SQL문이 혼합되어 있습니다.
 소스 파일에서 응용프로그램의 로직을 구현하는데 사용된 프로그래밍 언어를 호스트 언어라고 합니다.
 C, C++, COBOL, Java 등이 호스트 언어로 사용되며, C언어를 호스트 언어로 사용하면 ESQL/C 라고 부릅니다.
 소스 파일에서 데이터베이스 액세스 로직은 SQL문을 이용하여 구현됩니다.
 소스 파일의 SQL문은 프리컴파일과 바인드 과정을 통해 데이터베이스 API로 변환되어 실행시에 해당 팩키지를 호출하게 됩니다.
/* ESQL의 기본 구조입니다. */
시스템 헤더 파일과 사용자가 정의
한 헤더 파일을 포함시킵니다.
석문을 추가합니다.
#include <stdio.h>
#include "myapp.h"
EXEC SQL INCLUDE SQLCA;
호스트 변수를 선언합니다.
/* … */ 를 이용하여 원하는 위치에 주
EXEC SQL BEGIN DECLARE SECTION;
오류 처리를 위해 SQLCA 구조체를 포
함시킵니다.
char dbname[8+1];
EXEC SQL END DECLARE SECTION;
WHENEVER 문을 이용하여 오류 처리
일반 변수를 선언합니다.
short i=0;
루틴을 지정합니다.
EXEC SQL WHENEVER SQLERROR GOTO errchk;
COMMIT 또는 ROLLBACK문으로
main() {
EXEC SQL CONNECT TO :dbname;
한 트랜잭션이 종료되며, 새로운
트랜잭션이 시작되기 전에 데이터베이
스의 접속이 요구됩니다.
한 개 이상의 트랜잭션
SQL문이 시작되면 다시 새로운 트
랜잭션이 시작됩니다.
EXEC SQL CONNECT RESET;
return;
데이터베이스에 대한 접속을 해제하고,
응용프로그램을 종료합니다.
errchk : 오류 처리 로직
오류 처리 로직을 구현합니다.
}
U D B 개 발 자 기 본 교 육 • UNIT 13 • E S Q L 254
TOPIC
13 02 헤더 파일
01
 C 언어의 include 디렉티브를 이용하여 C와 UDB가 제공하는 시스템 헤더 파일을 포함시킵니다.
 사용자가 정의한 헤더 파일도 동일한 방법으로 포함시키면 됩니다.
 SQLCA 구조체를 포함시키려면, sqlca.h 파일을 직접 이용하지 않고 INCLUDE문을 사용하는 것이 일반적입니다.
 별도의 헤더 파일로 관리하는 호스트 변수들도 INCLUDE문을 사용하여 선언할 수 있습니다.
C 가 제공하는 헤더 파일입니다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
UDB 가 제공하는 헤더 파일입니다.
#include <sqlenv.h>
SQLCA 구조체를 include 합니다.
SQLCODE 또는 SQLSTATE를
확인하기 위해서 반드시 필요합니다.
#include <sqlutil.h>
사용자 정의 헤더 파일입니다.
#include "utilemb.h"
EXEC SQL INCLUDE SQLCA;
$ cat staff.h
struct
int main() {
EXEC SQL BEGIN DECLARE SECTION;
EXEC SQL INCLUDE 'staff.h';
{
short id;
EXEC SQL END DECLARE SECTION;
char name[10];
short i = 0;
short years;
} staff;
short ind_staff[3];
db2dclgn 유틸리티에 의해
생성된 structure 변수 파일을
include 합니다.
EXEC SQL CONNECT TO sample;
$ cat sqlca.h
…
SQL_STRUCTURE sqlca
{
_SQLOLDCHAR sqlcaid[8];
sqlint32
sqlcabc;
sqlint32
sqlcode;
short
sqlerrml;
_SQLOLDCHAR sqlerrmc[70];
_SQLOLDCHAR sqlerrp[8];
sqlint32
sqlerrd[6];
_SQLOLDCHAR sqlwarn[11];
_SQLOLDCHAR sqlstate[5];
};
…
U D B 개 발 자 기 본 교 육 • UNIT 13 • E S Q L 255
TOPIC
13 03 SQL 구분자
01
 ESQL 형식에서 C 또는 COBOL과 같이 로직을 표현하는 용도로 사용되는 기본 언어를 호스트 언어라고 합니다.
 ESQL 소스에서 SQL문을 호스트 언어와 구별하기 위해 사용되는 것을 SQL 구분자 (SQL Delimiter) 라고 합니다.
 SQL 구분자는 호스트 언어에 따라 다릅니다.
 ESQL/C 의 경우에는 EXEC SQL과 세미콜론(; 부호)이 사용됩니다.
/* ESQL의 기본 구조입니다. */
#include <stdio.h>
#include "myapp.h"
SQL문의 시작을 표시하기
위해 EXEC SQL 이라는 시
EXEC SQL INCLUDE SQLCA ;
EXEC SQL BEGIN DECLARE SECTION ;
char dbname[8+1];
작 구분자가 사용됩니다.
SQL문을 종료를 표시하기 위해
세미콜론 부호가 종료 구분자로
사용됩니다.
EXEC SQL END DECLARE SECTION ;
short i=0;
EXEC SQL WHENEVER SQLERROR GOTO errchk ;
main() {
EXEC SQL CONNECT TO :dbname ;
한 개 이상의 트랜잭션
EXEC SQL CONNECT RESET ;
return;
errchk : 오류 처리 로직
}
U D B 개 발 자 기 본 교 육 • UNIT 13 • E S Q L 256
TOPIC
13 04 호스트 변수
01
 ESQL 소스의 SQL문에서 참조되는 변수를 호스트 변수라고 합니다.
 프로그램의 로직을 구현하는 용도로만 사용되는 변수는 호스트 변수와 구별하여 일반 변수 또는 변수라고 부릅니다.
 호스트 변수는 데이터베이스 서버와 응용프로그램 사이에서 데이터를 전달하는 역할을 합니다.
 호스트 변수명은 소스 파일내에서 고유해야 합니다.
 호스트 변수의 선언은 BEGIN DECLARE SECTION문과 END DECLARE SECTION문을 사용합니다.
 SQL문에서 호스트 변수를 사용할 때는 컬럼명과의 구별을 위해 반드시 콜론(: 부호)과 함께 사용해야 합니다.
 호스트 변수가 SQL문이 아닌 호스트 언어로 구현된 로직에서 사용될 때는 콜론을 사용하지 않습니다.
 ESQL/C 언어를 사용할 때, 컬럼의 유형과 대응되는 호스트 변수의 대표적인 유형은 다음과 같습니다.
분
류
숫
자
문
자
날
짜
UDB
C 언어
바이트
salary SMALLINT
short salary
2 바이트
salary INT
sqlint32 salary
4 바이트
salary BIGINT
double salary
8 바이트
salary DEC(p,s)
double salary
31 자리
name CHAR(N)
char name[N+1]
254 바이트
name GRAPHIC(N)
char name[N+1]
127 바이트
name VARCHAR(N)
char name[N+1]
32672 바이
트
name VARGRAPHIC(N)
char name[N+1]
12336 바이
트
vdate DATE
char vdate[10+1]
10 바이트
vtime TIME
char vtime[8+1]
8 바이트
vts TIMESTAMP
char vts[26+1]
26 바이트
…
lastname을 호스트
EXEC SQL BEGIN DECLARE SECTION ;
char lastname[10+1];
short salary;
EXEC SQL END DECLARE SECTION ;
short i=0;
변수로 선언합니다.
lastname은 컬럼명
입니다.
EXEC SQL CONNECT TO sample;
EXEC SQL SELECT lastname,
salary
INTO :lastname,
:salary
FROM empl
WHERE empno=‘000300’;
printf("LASTNAME=%s\n", lastname );
…
lastname 은 호스트
변수이므로 콜론을
붙여서 표시합니다.
호스트 변수가 일반
로직에 사용되는 경
우에는 콜론을 붙붙
이지 않습니다.
U D B 개 발 자 기 본 교 육 • UNIT 13 • E S Q L 257
TOPIC
13 05 널 지시자 (Null Indicator)
01
 데이터베이스를 액세스할 때, NULL 값을 처리하는 경우가 있습니다.
 NULL(널)값은 공백 문자 (blank 또는 space) 또는 0 이 아닌 알 수 없는 값으로 데이터베이스는 NULL을 유효한 값으로 인식하지 않
습니다.
 SELECT 문을 사용하여 조회할 때, 특정 컬럼이나 표현식의 값으로 NULL이 반환된다면 대응되는 호스트 변수에는 NULL이 할당됩니
다.
 데이터베이스는 호스트 변수에 NULL을 반환된 것을 표시하기 위해 널 지시자(NULL Indicator) 값을 추가적으로 반환합니다.
 널 지시자의 데이터 유형은 smallint이며, 호스트 변수로 선언되어야 합니다.
 호스트 변수의 값이 NULL이 아닌 경우에는 널 지시자의 값으로 0 이 반환됩니다.
 NULL이 할당된 호스트 변수는 연산식에 사용될 수 없으므로, SELECT문을 실행한 이후에 호스트 변수의 NULL 여부를 확인하는 것이
…
좋습니다.
널 지시자인 ind_comm도
호스트
선언합니다.
 NULL은 값이 아니므로 호스트 변수의 값의 NULL
여부를
확인하기
위해 직접
비교할
대신변수로
비교합니다.
EXEC
SQL BEGIN
DECLARE
SECTION
; 수 없으며, 널 지시자의 값을
short
comm;
 SELECT문이널NULL을
반환하지 않게 하려면 VALUE
또는
COALEASE 함수를 사용합니다.
지시자의 값이 0 이 아
닌 음수가 반환되면 호스
트 변수에 NULL이 반환되
short ind_comm;
EXEC SQL END DECLARE SECTION ;
short i=0;
었다는 의미입니다.
호스트 변수인 comm의
바로 뒤에 콜론과 함꼐 널
EXEC SQL CONNECT TO sample;
EXEC SQL SELECT comm
INTO :comm :ind_comm
FROM empl
WHERE empno=‘000300’;
If (ind_comm < 0)
printf("Commission is NULL\n");
printf("Commission is NOT NULL : %f\n", cm);
…
지시자를 표시합니다.
호스트 변수인 comm에
NULL이 반환되었을 때,
널 지시자 변수가 지정되
어 있지 않았다면,
SQLCODE -305 가 반환
됩니다.
U D B 개 발 자 기 본 교 육 • UNIT 13 • E S Q L 258
TOPIC
13 06 db2dclgn 유틸리티
01
 DB2 DeCLaration GeNerator 의 약자로 데이타베이스 테이블의 구조에 대응하는 변수 선언문을 생성하는 유틸리티입니다.
 SELECT문에서 언급되는 호스트 변수는 수동적인 방법으로 SQL문에서 참조되기 전에 미리 선언되어야 합니다.
 호스트 변수는 특정 테이블의 컬럼들에 대응되는 유형이므로 유틸리티를 이용하여 자동적으로 생성하면 편리합니다.
 자동적으로 생성된 변수들은 C 언어의 구조체(STRUCT) 유형으로 h 라는 확장자를 가진 별도의 헤더 파일에 생성됩니다.
 BEGIN DECLARE SECTION문과 END DECLARE SECTION문 사이에서 해당하는 헤더 파일을 INCLUDE 하면 됩니다.
 생성된 헤더 파일을 이용하지 않고, 단순히 생성된 구조체 변수를 복사해서 사용해도 무방합니다.
db2dclgn -d sample -t staff -l C -i
$ cat staff.h
struct
{
short
id;
struct
{
short length ;
char
data[9];
} name;
short dept ;
char
job[5];
short
years;
double salary;
double comm;
} staff;
short ind_staff[7];
db2dclgn 유틸리티에 의해
생성된 structure 변수 파일을
include 합니다.
…
EXEC SQL BEGIN DECLARE SECTION;
EXEC SQL INCLUDE 'staff.h';
EXEC SQL END DECLARE SECTION;
short i = 0;
호스트 변수 대신에 구조
EXEC SQL CONNECT TO sample;
체 변수를 지정합니다.
EXEC SQL SELECT *
INTO :staff :ind_staff
FROM staff
WHERE id=100;
U D B 개 발 자 기 본 교 육 • UNIT 13 • E S Q L 259
TOPIC
13 07 주요 SQL문
01
 대표적으로 다음과 같은 SQL문이 지원됩니다.
분류
DDL
SQL문
CREATE
CREATE
CREATE
CREATE
/
/
/
/
ALTER / DROP TABLE
DROP INDEX
DROP VIEW
DROP TRIGGER
설명
테이블을 생성 / 변경 / 제거합니다.
인덱스를 생성 / 제거합니다.
뷰를 생성 / 제거합니다.
트리거를 생성 / 제거합니다.
DECLARE CURSOR / OPEN / FETCH INTO / CLOSE
커서를 처리합니다.
SELECT INTO / UPDATE / INSERT / DELETE
자료를 조회 / 변경 / 추가 / 삭제합니다.
GRANT / REVOKE
특정 오브젝트에 대한 권한을 부여 / 제거합니다.
EXECUTE IMMEDIATE
SELECT문과 Parameter Marker 가 있는 문장은 사용될 수
없습니다.
PREPARE
DESCRIBE, EXECUTE 등의 문장 이전에 사용됩니다.
EXECUTE
동일 UOW 내에서 여러번 사용될 수 있으며, ROLLBACK,
COMMIT 등이 실행되면 실행 코드가 소멸됩니다.
DML
DCL
Dynamic SQL
DESCRIBE
컬럼의 갯수와 데이터 유형 등을 기술하여 실행시에 호스트 변수를
가변적으로 할당합니다.
INCLUDE
헤더 파일을 포함시킵니다.
BEGIN DECLARE SECTION / END DECLARE
SECTION
호스트 변수를 선언합니다.
에러 제어
WHENEVER SQLERROR
WHENEVER SQLWARNING
WHENEVER NOT FOUND
SQLCODE가 음수 : SQL 오류 발생시 처리를 지시합니다.
SQLCODE가 양수 : SQL 경고 발생시 처리를 지시합니다.
SQLCODE가 +100 : 조건에 맞는 데이터가 부재 처리를
지시합니다.
UOW
트랜잭션
COMMIT
ROLLBACK
처리 내용을 데이터베이스에 반영하고 UOW를 종료합니다.
처리 내용을 데이터베이스에 반영하지 않고 UOW를 종료합니다.
연결
CONNECT TO / CONNECT RESET
데이터베이스에 접속 / 접속 해제합니다.
선언
U D B 개 발 자 기 본 교 육 • UNIT 13 • E S Q L 260
TOPIC
13 08 커서 처리
01
 응용 프로그램이 결과 집합 (Result Set)을 검색하기 위해 사용되는 메커니즘을 커서라고 합니다.
 SELECT문의 실행 결과가 한 건의 데이터를 반환하는 경우에는 SELECT ~ INTO 라는 구문이 사용됩니다.
 SELECT문이 두 건 이상의 데이터를 반환하는 경우에 SELECT ~ INTO 구문을 사용하면 오류가 발생됩니다.
 SELECT문이 여러 건의 데이터를 반환하는 경우에는 CURSOR를 사용해야 합니다.
 오픈된 커서의 포인터는 COMMIT 또는 ROLLBACK 문에 의한 UOW 종료시에 소멸됩니다.
 UOW 종료 후에도 커서의 포인터를 유지하려면 WITH HOLD 옵션을 이용합니다.
 커서의 유형에는 읽기 전용의 READ ONLY 커서와 갱신이 가능한 UPDATEABLE 커서가 있습니다.
 FOR 옵션으로 커서의 용도를 분명하게 명시한 커서를 UNAMBIGUOUS 커서라고 하며, FOR 옵션이 없는 커서를 AMBIGUOUS 커서
라고 합니다.
FOR READ ONLY
EXEC SQL DECLARE c4 CURSOR WITH HOLD FOR
EXEC
SQL블럭킹
DECLARE
CURSOR
FOR LOCK의
 커서의 유형에
따라
가능c1여부와
적용되는
종류가 달라지게 됩니다.
SELECT projno, prstdate, prendate
FROM
project
WHERE deptno = ‘D11’
FOR READ ONLY;
EXEC SQL DECLARE c2 CURSOR FOR
SELECT projno, prstdate, prendate
FROM
project
옵션을 이용하였으
므로, READ ONLY
커서이며,
UNAMBIGUOUS
커서입니다.
FOR 옵션이 없으
므로 AMBIGUOUS
커서입니다.
WHERE deptno = ‘D11’;
EXEC SQL DECLARE c3 CURSOR FOR
SELECT projno, prstdate, prendate
FROM
project
WHERE deptno = ‘D11’
FOR UDATE OF prstdate, prendate;
EXEC SQL OPEN c1;
FOR UPDATE OF
옵션을 이용하였으
므로 UPDATABLE,
UNAMBIGUOUS 커
서입니다.
SELECT projno, prstdate, prendate
FROM project
WHERE deptno = ‘D11’;
WITH HOLD 옵션을 이용하였
으므로 UOW 종료 후에도 포인
EXEC SQL OPEN c1;
터가 유지됩니다.
I = 0;
do {
EXEC SQL FETCH c1 INTO :v1, :v2. :v3;
if (SQLCODE != 0) break;
EXEC SQL UPDATE project
SET prenddate = CURRENT DATE
WHERE projno = :v1;
i++;
if (i == 500) {
OPEN, FETCH, CLOSE
EXEC SQL COMMIT;
i = 0;
문으로 처리합니다.
}
} while ( 1 );
EXEC SQL CLOSE c1;
EXEC SQL COMMIT;
U D B 개 발 자 기 본 교 육 • UNIT 13 • E S Q L 261
TOPIC
13 09 Positioned UPDATE / DELETE
01
 CURSOR를 이용하여 특정 데이터를 FETCH 한 후에, 동일한 데이터를 UPDATE하거나 DELETE 하는 경우가 있습니다.
 CURSOR가 이미 FETCH한 데이터의 커서 포인터를 이용하여 UPDATE 또는 DELETE 하는 것을 POSITIONED UPDATE / DELETE 라고
합니다.
 POSITIONED UPDATE / DELETE 에서는 WHERE 절에서 조건문 대신에 CURSOR의 이름을 이용하게 됩니다.
 커서 선언에서 FOR UPDATE 옵션을 이용하여 POSITIONED UPDATE가 가능한 커서를 선언합니다.
 조회되는 테이블의 모든 컬럼을 변경하려면 FOR UPDATE 옵션을, 일부 컬럼만 변경하기를 원하면 FOR UPDATE OF 옵션을 이용합
니다.
 POSITIONED DELETE는 FOR UPDATE 옵션이 필요하지 않습니다.
 일반적인 UPDATE / DELETE 문을 이용하면, 이미 FETCH된 데이터와 동일한 데이터라도 다시 검색해야 하므로 비효율적입니다.
 일반적인 UPDATE / DELETE 를 이용하여 이런 로직의 응용프로그램을 동시에 실행하게 되면, DELADLOCK이 발생되기 쉽습니다.
EXEC SQL DECLARE c1 CURSOR FOR
EXEC SQL DECLARE c1 CURSOR FOR
 UPDATABLE
커서는
FETCH하는
데이터에
LOCK이
적용되어
방지할
수 있습니다.
SELECT
projno,
prstdate,
prendateS 모드 대신에 U 모드의
FOR
UPDATE
OF 옵 DEADLOCK을
SELECT
projno,
prstdate, prendate
FROM
project
WHERE deptno = ‘D11’;
션을 이용하여 커서를
FROM
선언합니다.
WHERE deptno = ‘D11’
project
FOR UDATE OF prstdate, prendate;
EXEC SQL OPEN c1;
do {
EXEC SQL FETCH c1 INTO :v1, :v2. :v3;
if (SQLCODE != 0) break;
EXEC SQL UPDATE project
EXEC SQL OPEN c1;
do {
조건에 맞는 데이터를
다시 조회하므로 비효
EXEC SQL FETCH c1 INTO :v1, :v2. :v3;
율적입니다.
if (SQLCODE != 0) break;
EXEC SQL UPDATE project
SET prenddate = CURRENT DATE
WHERE projno = :v1;
} while ( 1 );
EXEC SQL CLOSE c1;
SET prenddate = CURRENT DATE
WHERE 절에 조건문
} while ( 1 );
대신에 커서의 이름을
WHERE CURRENT OF c1;
명시합니다.
EXEC SQL CLOSE c1;
U D B 개 발 자 기 본 교 육 • UNIT 13 • E S Q L 262
TOPIC
13 10 복합 SQL (Compound SQL)
01
 클라이언트 응용프로그램에서 요청한 SQL문은 네트웤을 통해 데이터베이스 서버에 전달되어 조건에 맞는 데이터는 네트웤을 통해
다시 클라이언트 응용프로그램으로 반환됩니다. SQL문의 실행 결과와 함께 SQLCA 영역도 반환됩니다.
 많은 양의 데이터에 대해 반복적인 UPDATE, INSERT, DELETE를 한 건씩 요청하면 성능이 저하되는 경우가 있습니다.
 성능 향상을 위하여 N 건의 요청을 한 개의 SQL 블록으로 묶어서 처리하는 것을 복합 SQL (Compound SQL)이라고 합니다.
 SELECT, UPDATE, INSERT, DELETE문이 혼합된 SQL 블록을 구성하는 것도 가능합니다.
 SQL 블록 안에서 SELECT문의 실행 결과로 나온 값은 일반 연산문의 대상이 되지 않으므로 주의합니다.
 SQL 블록 안에 있는 SQL문들은 개별적으로 서버에 전달되지 않고, 블록 단위로 전달됩니다.
 단순한 UPDATE, INSERT, DELETE 요청인 경우에는 네트웤 요청을 1/N 로 줄일 수 있으므로 성능에 도움이 됩니다.
 SQL 블록은 BEGIN COMPOUND ~ END COMPOUND 라는 구문으로 표현됩니다.
 복합 SQL로 표현된 SQL문을 실행하는 모드에는 ATOMIC 과 NOT ATOMIC 이 있습니다.
 ATOMIC 모드는 SQL 블록의 중간에서 오류가 발생되면 그 시점에서 실행을 멈추고, 클라이언트로 오류를 반환합니다.
 NOT ATOMIC 모드는 SQL 블록의 중간에서 오류가 발생되면 그 SQL을 무시하고 다음 SQL을 실행합니다.
 SQLCA는 COMPOUND SQL을 실행한 후에 한 번만 반환되며, 블록 내의 모든 SQL이 실행한 결과의 누적값을 반영합니다.
EXEC SQL BEGIN COMPOUND ATOMIC STATIC
EXEC SQL DELETE FROM t1 WHERE deptno like 'Z%';
SELECT COUNT(*) INTO :emps FROM empl;
printf("Enter the iteration count (1 ~ 5) : ");
SELECT COUNT(*) INTO :deps FROM dept;
scanf("%d",&number);
SELECT AVG(salary) INTO :avg_sal FROM empl;
EXEC SQL BEGIN COMPOUND ATOMIC STATIC STOP
STOP FIRST :number STATEMENTS
COMMIT;
END COMPOUND;
printf("EMP table : %d\n", emps);
ATOMIC 모드의
printf("DEP table : %d\n", deps);
SQL 블록입니다.
printf("Average : %.2f\n", avg_sal);
SQLCA의 필드에
INSERT INTO t1 values ('Z01','dept Z01','A00');
는 SQL문들의 실
INSERT INTO t1 values ('Z02','dept Z02','A00');
행 결과의 합계가
INSERT INTO t1 values ('Z03','dept Z03','A00');
number 변수의
INSERT INTO t1 values ('Z04','dept Z04','A00');
값이 지정하는 개
저장됩니다.
INSERT INTO t1 values ('Z05','dept Z05','A00');
COMMIT;
printf("TOTAL rows %d\n\n", sqlca.sqlerrd[2]);
수의 SQL문만 실
행한 후에 블록을
END COMPOUND;
printf("%d rows are inserted.\n", number);
종료합니다.
U D B 개 발 자 기 본 교 육 • UNIT 13 • E S Q L 263
TOPIC
13 11 SQLCA
01
 SQL Communication Area 의 약자입니다.
 SQL문의 실행 직후에는 항상 해당 SQL문의 실행과 관련된 정보를 응용프로그램에게 반환합니다.
 기본적인 오류 판별 방법은 각 SQL문의 실행 직후에 IF 문을 이용하여 SQLCA의 필드인 SQLCODE 또는 SQLSTATE를 비교하는 것입니다.
SQL_STRUCTURE
printf("Enter the lastname : ");
sqlca
gets(lname);
{
_SQLOLDCHAR sqlcaid[8];
sqlint32 sqlcabc;
#ifdef DB2_SQL92E
sqlint32 sqlcade;
숫자형 SQL 리턴 코드입니다.
0은 성공, 100은 자료 부재,
양수는 경고, 음수는 오류를
의미합니다.
EXEC SQL SELECT FIRSTNME INTO :fname
FROM employee
WHERE LASTNAME = :lname;
#else
sqlint32 sqlcode;
오류 메시지를 저장합니다.
#endif
short sqlerrml;
_SQLOLDCHAR sqlerrmc[70];
_SQLOLDCHAR sqlerrp[8];
printf("First name = %s\n", fname);
진단 정보를 제공하는 6개의
INTEGER 변수값을
나타냅니다.
else if (SQLCODE == 100)
else {
printf("Select Error : SQLCODE = %ld\n", SQLCODE);
EXEC SQL ROLLBACK;
공백 또는 W를 저장하는
일련의 경고 표시기 값입니다.
EXEC SQL CONNECT RESET;
}
_SQLOLDCHAR sqlstat[5];
_SQLOLDCHAR sqlstate[5];
#endif
};
SQL 오류가 발생하였으므로
SQLCODE를 확인한 후,
ROLLBACK을 실행합니다.
return (-1);
#ifdef DB2_SQL92E
#else
조건에 맞는 데이터의 부
재 여부를 점검합니다.
printf("Data is not found\n");
sqlint32 sqlerrd[6];
_SQLOLDCHAR sqlwarn[11];
SQL문의 성공 여부
를 점검합니다.
if (SQLCODE == 0)
SQL문의 결과를 나타내는
5자리의 문자형 리턴 코드
값입니다.
EXEC SQL UPDATE empl
SET firstnme = ‘EunSook’
WHERE LASTNAME = :lname;
U D B 개 발 자 기 본 교 육 • UNIT 13 • E S Q L 264
TOPIC
13 12 WHENEVER 문
01
 WHENEVER 구문을 이용하면 오류 또는 경고가 발생할 때마다 자동적으로 처리되는 루틴을 구현할 수 있습니다.
 IF문으로 SQLCODE를 일일이 점검하지 않고, SQL문이 성공하지 못한 경우에 자동적으로 오류 처리 루틴으로 분기할 수 있습니다.
 WHENEVER 문은 SQLERROR, SQLWARNING, NOT FOUND 의 발생을 처리할 수 있습니다.
 지정한 상황이 발생하면 GOTO 옵션을 이용하여 사용자가 정의한 오류 처리 루틴의 레이블(LABEL)로 이동할 수 있습니다.
 CONTINUE 옵션을 이용하면 상황의 발생을 무시하고 다음 SQL문을 실행하게 됩니다.
EXEC SQL INCLUDE SQLCA;
…
SQLCODE가 음수인 경우에 errchk 레이블로 분기합니다.
WHENEVER SQLERROR GO TO errchk;
WHENEVER SQLWARNING CONTINUE;
WHENEVER NOT FOUND CONTINUE;
SQLWARN(0)이 " W" 이거나 SQLCODE가 100이 아닌
양수인 경우에는 무시하고 다음 SQL문을 계속
실행합니다.
…
strcpy(newfname,"EunSook");
EXEC SQL UPDATE empl
SET firstnme = :newfname
WHERE LASTNAME = :lname;
SQLCODE가 100 인 경우에도 무시하고 다음 SQL문을
계속 실행합니다.
…
errchk:
printf("Select Error : SQLCODE = %ld\n", SQLCODE);
EXEC SQL ROLLBACK;
EXEC SQL CONNECT RESET;
SQL 오류가 발생하면 SQLCODE를 확인하고, UOW를
ROLLBACK 시킵니다. 최종적으로 데이터베이스의
접속을 해제하고, 응용프로스램을 종료합니다.
return (-1);
}
…
U D B 개 발 자 기 본 교 육 • UNIT 13 • E S Q L 265
TOPIC
13 13 정적 SQL (Static SQL)
01
 프리컴파일시 엔진이 SQL문의 구조를 완전히 파악할 수 있도록 표현되어야 합니다.
 참조되는 테이블 및 컬럼 이름이 프리컴파일시에 모두 지정되어야 합니다.
 프리컴파일 또는 바인드시에 SQL문의 실행 가능한 형태가 패키지로 작성되어 시스템 카탈로그에 저장됩니다.
 응용프로그램을 바인드하는 사용자는 소스 파일의 각 SQL문에 대한 실행 Privilege는 가지고 있어야 합니다.
 옵티마이저는 바인드시의 데이타베이스 통계 자료와 구성 매개 변수를 이용하여 쿼리의 최적화합니다.
 옵티마이저는 SELECT 문에서 사용되는 호스트 변수의 값을 실행시까지 알 수 없으므로 DEFAULT FILTERING FACTOR를 이용합니다.
 정적 SQL문은 일반적으로 동적 SQL문보다 실행 속도가 빠릅니다.
U D B 개 발 자 기 본 교 육 • UNIT 13 • E S Q L 266
TOPIC
13 14 동적 SQL (Dynamic SQL)
01
 응용프로그램 실행 중에 SQL문 전체 또는 일부를 생성해야 하는 SQL문을 동적 SQL문이라고 합니다.
 SQL문에 의해 참조되는 오브젝트가 프리컴파일될 때 확인되지 않습니다.
 옵티마이저는 응용프로그램의 실행시에 액세스 플랜을 작성하므로 처음 실행시에 속도가 저하될 수 있습니다.
 SQL문이 항상 최근의 데이타베이스 통계에 기초하여 최적의 액세스 경로를 사용하기를 원하는 경우에 적합합니다.
 시스템 레지스터리 등의 컴파일 환경을 동적으로 변경하려는 경우에 적합합니다.
 정적 SQL보다 가변적이고 복잡한 로직을 구현할 수 있습니다.
 EXECUTE IMMEDIATE
• 변수를 포함하지 않는 SQL문을 PREPARE하고 실행합니다.
• 응용프로그램의 모든 EXECUTE IMMEDIATE 문은 실행시 같은 위치에 캐쉬되므로 최종 명령문만 남게 됩니다.
 PREPARE
• 문자열 형식의 SQL문을 실행 가능한 형식으로 변환하고 그 이름을 지정합니다.
• 선택적으로 SQLDA 구조에 SQL문에 대한 정보를 저장합니다.
 EXECUTE
• 이전에 PREPARE된 SQL문을 실행합니다.
• 한 데이타베이스 접속내에서 반복적으로 실행할 수 있습니다.
 DESCRIBE
• PREPARE된 명령문에 대한 정보를 SQLDA와 연결합니다.
U D B 개 발 자 기 본 교 육 • UNIT 13 • E S Q L 267
TOPIC
13 15 매개 변수 표시 문자 (Parameter Marker)
01
 DYNAMIC SQL문에서 SQL문은 실행 직전까지 문자열로 처리됩니다.
 STATIC SQL문에서 사용하던 호스트 변수는 사용할 수 없습니다.
 호스트 변수가 표현되어야 하는 위치에 물음표(? 부호) 표시를 사용하는데, 이것을 PARAMETER MARKER 라고 합니다.
 PARAMETER MARKER를 이용하면, 변수 값만 치환하면서 DYNAMIC SQL을 반복적으로 실행할 수 있으므로 성능에 도움이 됩니다.
strcpy(stmt,"UPDATE employee SET ");
printf("Enter the Column (Salary or Comm) : ");
scanf("%s",colname);
UPDATE 구문에서 사용될 컬럼명이 실행시에
결정되므로 static SQL로 표현할 수 없습니다.
strcat(stmt,colname);
strcat(stmt," = ");
strcat(stmt,colname);
strcat(stmt," + ");
strcat(stmt," ? WHERE empno = ?");
입력된 사번과 증가값을 이용하여 salary 또는 comm
컬럼의 값을 변경하려고 합니다. 두 가지 값은 static
printf("Enter the empno : ");
SQL에서는 호스트 변수로 처리할 수 있지만, dynamic
scanf("%s",empno);
SQL 에서는 parameter marker로 처리해야 합니다.
printf("Enter the incresement (1~10) : ");
scanf("%d",&increse);
EXEC SQL PREPARE s1 FROM :stmt;
EXEC SQL EXECUTE s1 USING :increse, :empno;
EXECUTE 문을 실행할 때, 두 개의 parameter marker 가
필요합니다. 입력된 사번과 증가값을 저장한 호스트
if (SQLCODE != 0) {
변수인 increase와 empno를 이용합니다.
printf("Fail : SQLCODE = %ld\n", SQLCODE);
EXEC SQL ROLLBACK;
}
U D B 개 발 자 기 본 교 육 • UNIT 13 • E S Q L 268
TOPIC
13 16 동적 SQL 문의 유형
01
 동적 SQL문의 유형은 다음과 같이 분류됩니다.
 "유형 5" 의 구현시에는 SQLDA가 필요합니다.
유형 5 : COMPLETE Varying List SELECT
유형 4 : PARAMETERIZED SELECT
유형 3 : PARAMETERIZED NON-SELECT
유형 2 : COMPLETE Fixed List SELECT
C
O
M
P
L
E
X
I
T
Y
유형 1 : COMPLETE NON-SELECT
U D B 개 발 자 기 본 교 육 • UNIT 13 • E S Q L 269
TOPIC
13 17 생성 과정
01
 ESQL/C 로 구현된 응용프로그램을 빌드하는 과정은 다음과 같습니다.
 프리컴파일러와 헤더 파일, 라이브러리를 제공하려면 개발 머신에 DB2 Application Development Client 모듈 이상을 설치해야 합니다.
 실행 모듈을 생성하려면 호스트 언어인 C 컴파일러가 필요합니다.
② 바인드
$ db2 bind myapp.bnd
① 프리컴파일
$ db2 prep myapp.sqc BINDFILE
③ 컴파일
$ xlc –c myapp.c …
④ 링크
$ xlc –o myapp …
U D B 개 발 자 기 본 교 육 • UNIT 13 • E S Q L 270
TOPIC
13 18 프리컴파일
01
 ESQL/C 로 구현된 응용프로그램의 원본 소스의 확장자는 sqc 입니다.
 sqc 소스 파일은 C 언어로 구현된 로직 부분과 SQL 문이 혼합되어 있습니다.
 프리컴파일러는 sqc 소스에서 C 언어와 SQL문을 분리하는 작업을 수행합니다.
 프리컴파일러는 sqc 소스에서 SQL문을 주석문으로 처리합니다.
 SQL문이 주석문으로 처리된 부분에는 실행시에 대응되는 팩키지와 섹션을 호출할 수 있는 정보를 가진 API가 삽입됩니다.
 sqc 소스 파일에서 SQL문이 제거되고, API가 삽입된 새로운 소스는 c 확장자를 가진 C 언어 소스 파일이 됩니다.
 제거된 SQL문은 옵티마이저에 의해 팩키지로 생성되어 시스템 카탈로그에 저장됩니다.
 BINDFILE이라는 옵션을 이용하면, 팩키지를 생성하지 않고 제거한 SQL문을 bnd 라는 확장자를 가진 별도의 파일에 저장합니다.
 프리컴파일러는 DBMS 벤더마다 고유합니다.
BINDFILE 옵션이 있는 경우
ESQL 소스 파일 :
C 언어와 SQL문이
BINDFILE 옵션이 없는 경우
myapp.sqc
혼합되어 있습니다.
myapp.sqc
프리컴파일
수정된 소스 파일 :
SQL문을 DB2 API를
프리컴파일
포함하고 있습니다.
CT : 시간 소인
CT : 시간 소인
myapp.bnd
myapp.c
myapp.c
myapp
CT : 시간소인
CT : 시간소인
CT : 시간소인
CT : 시간소인
바인드 파일 :
BINDFILE 옵션을 사용하면, 팩키지를 생성하는데 필요
한 데이터가 포함된 바인드 파일을 생성합니다.
팩키지 :
PACKAGE 옵션을 사용하거나 BINDFILE 을 지정하지 않
으면 패키지가 생성되어 데이타베이스에 저장됩니다.
U D B 개 발 자 기 본 교 육 • UNIT 13 • E S Q L 271
TOPIC
13 19 PREP 명령어
01
 UDB에서 프리컴파일을 실행하는 명령어는 prep 입니다.
 prep 명령어의 옵션은 다음과 같습니다.
U D B 개 발 자 기 본 교 육 • UNIT 13 • E S Q L 272
TOPIC
13 20 바인드
01
 프리컴파일 과정에서 제거된 SQL문에 대한 팩키지를 생성하고 저장하는 과정을 바인드라고 합니다.
 프리컴파일 과정에서 BINDFILE이라는 옵션이 지정되지 않았다면, 바인드 과정은 프리컴파일 과정에 포함됩니다.
 프리컴파일 과정에서 BINDFILE이라는 옵션을 사용하면, SQL문은 팩키지로 생성되지 않고 bnd 라는 확장자를 가진 바인드 파일에
추출됩니다.
 바인드 파일은 텍스트 형식이 아니므로 내용을 확인하거나 편집할 수 없습니다.
 bnd 파일에 저장된 SQL문은 SQL 옵티마이저에 의해 팩키지로 생성됩니다.
 SQL 옵티마이저가 SQL문을 분석하여 액세스플랜(ACCESS PLAN)을 생성하는 과정을 SQL 컴파일이라고 합니다.
 SQL 옵티마이저는 bnd 파일에 저장된 SQL문을 한 개씩 컴파일하여 개별적인 섹션에 액세스 플랜을 저장합니다.
 한 개의 bnd 파일은 한 개의 팩키지가 되고, SQL문 개수만큼의 섹션을 포함하게 됩니다.
 생성된 팩키지와 섹션은 시스템 카탈로그에 저장됩니다.
 프리컴파일 과정에서 PACKAGE옵션이 지정되지 않으면 팩키지명은 sqc 소스 파일의 첫 8자와 동일하게 됩니다.
 새로 작성된 패키지 이름이 데이타베이스에 있는 패키지와 같은 경우 새 패키지는 이전의 패키지를 대체합니다.
myapp.bnd
바인드 파일 :
바인드 파일을 바인드하면 데이터
베이스 서버에 팩키지가 저장됩니
다. 여러 개의 클라이언트 머신에
서 동일한 펙키지를 사용한다면,
한 개의 클라이언트에서만 바인드
하면 됩니다.
CT : 시간 소인
바인드
팩키지 :
한 개의 바인드 파일은 한 개의 팩
키지를 생성합니다. 각각의 SQL문
은 개별적인 섹션으로서 팩키지 안
에 포함됩니다.
myapp
CT : 시간소인
U D B 개 발 자 기 본 교 육 • UNIT 13 • E S Q L 273
TOPIC
13 21 BIND 명령어
01
 바인드는 BIND 라는 명령어을 이용합니다.
 BIND 명령어의 옵션은 다음과 같습니다.
U D B 개 발 자 기 본 교 육 • UNIT 13 • E S Q L 274
TOPIC
13 22 컴파일과 링크
01
 프리컴파일 과정이 완료되면, SQL문이 제거된 새로운 C 언어 소스가 생성됩니다.
 C 소스 파일은 적합한 C 컴파일러에 의해 처리되어야 합니다.
 컴파일 옵션에서 UDB가 제공하는 헤더 파일이 있는 디렉토리를 지정해야 합니다.
 사용자가 공용으로 사용하는 헤더 파일이 있다면, 그 경로명을 지정해야 합니다.
 오브젝트 파일이 생성되면 시스템 라이브러리를 링크합니다.
 링크 옵션에서 UDB가 제공하는 라이브러리 파일을 포함시켜야 합니다.
 사용자가 공용으로 사용하는 라이브러리 파일이 있다면 같이 링크시킵니다.
 컴파일과 링크 과정을 한꺼번에 하는 것도 가능합니다.
 컴파일러 사용시 64 비트 옵션을 사용하려면 인스턴스가 64비트 모드로 생성되어야 합니다.
 UDB가 제공하는 라이브러리 디렉토리에 대한 링크는 인스턴스 생성시 32 또는 64 비트로 결정됩니다.
 필요시 db2iupdt 명령어를 이용하여 32비트와 64비트 모드를 전환할 수 있습니다.
수정된 소스 파일 :
시스템, UDB, 사용자
정의 헤더 파일들을 모
두 참조하여 컴파일이
완료되면 오브젝트 파
일이 생성됩니다.
컴파일
myapp.c
헤더 파일
CT : 시간 소인
오브젝트 파일 :
시스템, UDB, 사용자
정의 라이브러리 파일
들을 모두 링크하여 실
행 모듈을 생성합니다.
myapp.o
카탈로그 테이블에 팩키지가 존재
하지 않으면 SQLCODE –805 가
반환됩니다.
CT : 시간 소인
링크
라이브러리
실행 모듈 :
최초의 SQL문이 실행될 때, 카탈
로그 테이블에 저장된 팩키지와 해
당 섹션이 참조됩니다.
myapp
카탙로그에 저장된 팩키지와 실행
모듈의 버전이 일치하지 않으면
SQLCODE –818 이 반환됩니다.
CT : 시간소인
실행 모듈은 모든 클라이언트 머신
에 배포되어야 합니다.
U D B 개 발 자 기 본 교 육 • UNIT 13 • E S Q L 275
TOPIC
13 23 xlc 명령어
01
 AIX 에서 확장자 c 를 가진 C 소스 파일을 xlc 명령어의 –q64, –c, -I 등의 옵션을 이용하여 컴파일합니다.
 -c 옵션을 이용했다면 확장자 o 를 가진 오브젝트 파일이 생성됩니다.
 확장자 o 를 가진 C 오브젝트 파일을 xlc 명령어의 –q64, -L, -l 등의 옵션을 이용하여 링크하여 실행 모듈을 생성합니다.
 프리컴파일, 바인드, C 컴파일, C 링크의 모든 과정은 makefile을 이용해서 실행합니다.
 xlc 명령어를 이용한 makefile의 예는 다음과 같습니다.
CC= xlc -q64
xlc 명령어의 옵션으로 UDB
헤더 파일,
사용자 정의 헤더 파일, UDB
라이브러리,
사용자 정의 라이브러리를
지정합니다.
DB2PATH = /data/post01/sqllib
BINPATH = /post01/com/bin
LINK= -L${DB2PATH}/lib -I${DB2PATH}/include -ldb2 -lc
USERLIBS= /post01/com/lib/comcmlib.a
INCL= /post01/com/include
SOURCE= post001b
all
프리컴파일을 실행하기 위해
prep 명령어를 실행합니다.
xlc 컴파일러를 64비트 모드로 사용
합니다.
인스턴스 사용자의 홈디렉토리에
있는 sqllib 디렉토리를 지정합니다.
: $(SOURCE)
$(SOURCE)
:
db2 connect to sample
db2 "prep [email protected] bindfile sqlwarn no isolation ur"
db2 "bind [email protected] blocking all grant public"
db2 connect reset
$(CC) -O -o $@ [email protected] $(LINK) $(USERLIBS) -I$(INCL)
rm [email protected] [email protected]
mv $@ $(BINPATH)
바인드를 실행하기 위해
bind 명령어를 실행합니다.
clean:
rm -fr $(SOURCE)
xlc 명령어를 이용하여 컴파일과 링
크를 한꺼번에 실행합니다.
U D B 개 발 자 기 본 교 육 • UNIT 13 • E S Q L 276
TOPIC
13 24 팩키지
01
 프리컴파일 과정에서 C 언어와 SQL문이 분리될 때 Consistency Token이 생성됩니다.
 분리된 C언어 소스로부터 생성된 실행 모듈과 바인드 파일에서 생성된 팩키지는 Consistency Token을 이용해서 버전을 식별합니
다.
 sqc 소스가 수정되어 프리컴파일을 다시 했다면, C의 실행 모듈과 팩키지는 모두 다시 생성되어야 합니다.
 프리컴파일이 다시 실행된 후, C 실행 모듈 또는 SQL 팩키지만 다시 생성하게 되면 버전이 맞지 않으므로 실행시 –818 오류가 반환
됩니다.
 실행 모듈만 존재하고, SQL 팩키지가 존재하지 않는 경우에는 –805 오류가 반환됩니다.
 프리컴파일시에 팩키지의 이름을 변경하는 옵션을 주지 않으면, 기본적으로 sqc 파일명과 동일한 이름의 팩키지가 생성됩니다.
 팩키지 이름의 최대 길이는 8자이므로, sqc 파일명의 최대 길이를 8자로 하는 것이 바람직합니다.
 팩키지에 대한 정보는 list packages 명령어를 이용해서 확인합니다.
 응용 프로그램이 정적 SQL을 사용할 때는 다음의 조건이 만족되어야 합니다.
• 바인드하는 사용자는 BINDADD 특권(Privilege)과 응용 프로그램의 모든 SQL문을 수행하는데 필요한 개별적인 특권이 있어
야 합니다.
• VALIDATE RUN 옵션을 줄 경우에는 SQL문에 대한 특권이 없어도 BIND는 실패하지 않지만, 실행시에 다시 권한 점검이 수행
됩니다.
• 응용프로그램을 수행하는 사용자는 그 패키지에 대해 EXECUTE 특권만 필요합니다.
 응용 프로그램이 동적 SQL을 사용할 때는 다음의 사항이 필요합니다.
• 바인드하는 사용자는 데이타베이스에 BINDADD 특권만 있으면 됩니다.
• 응용 프로그램을 수행할 때 수행되는 특권 점검에 사용되는 사용자명은 바인드할 때 주는 DYNAMICRULES 옵션에 따라 다릅
니다.
• DYNAMICRULES RUN (기본값) 으로 바인드할 경우에는 응용 프로그램을 실행시키는 사용자는 U각DSQL문을
B 개 발 자실행하는데
기 본 교 육 •필요
UNIT 13 • E S Q L 277
한 특권 및 해당 패키지에 대한 EXECUTE 특권이 있어야 합니다.
TOPIC
13 25 리바인딩
01
 이전에 바인드된 응용프로그램에 대한 패키지를 재작성하는 과정을 리바인딩이라고 합니다.
 팩키지의 상태는 Normal(Y), Invalid(N), Inoperative(X) 중에 한 가지입니다.
 팩키지의 상태가 Invalid(N) 또는 Inoperative(X) 인 경우에는 리바인딩이 필요합니다.
 Inoperative 패키지는 명시적으로 BIND 명령이나 REBIND 명령을 실행해야 리바인딩됩니다.
 Invalid 패키지는 다음 번에 실행될 때 데이터베이스 엔진에 의해 자동적으로 리바인딩됩니다.
 RUNSTATS 명령을 수행한 후 갱신된 통계 자료를 사용하거나 새로 작성된 색인을 이용하고자 할 경우에도 리바인딩이 요구됩니다.
 bnd 파일이 존재한다면, bind 명령어를 이용하여 리바인드할 수 있습니다.
 bnd 파일이 없는 경우에는 rebind 명령어를 사용하여 현재의 팩키지를 갱신합니다.
 db2rbind 유틸리티를 이용하면, 특정 데이터베이스에 존재하는 모든 팩키지를 한 번에 리바인딩할 수 있습니다.
U D B 개 발 자 기 본 교 육 • UNIT 13 • E S Q L 278