1.데이터와 비즈니스 어플리케이션을 잘 알아야 한다.
동일한 정보는 다른 비즈니스 데이터 원천으로부터 검색될 수 있다. 이러한 원천에 익숙해야 한다.
당신은 당신의 데이터베이스 안의 데이터의 크기와 분포를 반드시 알아야 한다.
또한 SQL을 작성하기 전에 비즈니스 개체 안의 관계와 같은 데이터 모델을 전체적으로 이해해야
한다. 이러한 이해는 당신이 여러 테이블에서 정보를 검색하는데 있어서 보다 좋은 쿼리를 작성할
수 있다. DESIGNER/2000과 같은 CASE TOOLS은 다른 비즈니스와 데이터베이스 객체사이의 관계
를 문서화 하는데 좋은 역할을 한다.

2.실제 데이터를 가지고 당신의 쿼리를 검사하라.
대부분의 조직은 개발, 검사, 제품의 3가지 데이터베이스 환경을 가진다. 프로그래머는
어플리케이션을 만들고 검사하는데 개발 데이터베이스 환경을 사용하는데, 이 어플리케이션이
제품 환경으로 전환되기 전에 프로그래머와 사용자에 의해 검사 환경하에서 보다 엄격하게 검토되어
야 한다.
SQL이 검사 환경하에서 테스트될 때, 검사 데이터베이스가 가지고 있는 데이터는 제품 데이터베이스
를 반영해야 한다. 비실제적인 데이터를 가지고 테스트된 SQL문은 제품 안에서는 다르게 작동할 수
있다. 엄격한 테스트를 보장하기 위해서는, 검사 환경하에서의 데이터 분포는 반드시 제품 환경에서
의 분포와 밀접하게 닮아야 한다.

3.동일한 SQL을 사용하라.
가능한한 BIND VARIABLE, STORED PROCEDURE, PACKAGE의 이점을 활용하라. IDENTICAL SQL문
의 이점은 PARSING이 불필요하기에 데이터베이스 서버안에서 메모리 사용의 축소와 빠른 수행을
포함한다. 예로서 아래의 SQL 문은 IDENTICAL하지 않다.

SELECT * FROM EMPLOYEE WHERE EMPID = 10;
SELECT * FROM EMPLOYEE WHERE EMPID = 10;
SELECT * FROM EMPLOYEE WHERE EMPID = 20;

그러나 I_EMPID라고 이름 주어진 BIND VARIABLE을 사용하면 SQL 문은 이렇게 된다.
SELECT * FROM EMPLOYEE WHERE EMPID = :I_EMPID;

4.주의 깊게 인덱스를 사용하라.
테이블상에 모든 필요한 인덱스는 생성되어야 한다. 하지만 너무 많은 인덱스는 성능을 떨어뜨릴
수 있다. 그러면 어떻게 인덱스를 만들 칼럼을 선택해야 하는가?

*최종 사용자에 의해 사용되는 어플리케이션 SQL과 쿼리의 WHERE 절에서 빈번하게 사용되는 칼럼
에 인덱스를 만들어야 한다.

*SQL 문에서 자주 테이블을 JOIN하는데 사용되는 칼럼은 인덱스되어야 한다.

*같은 값을 가지는 ROW가 적은 비율을 가지는 칼럼에 인덱스를 사용하라.

*쿼리의 WHERE 절에서 오직 함수와 OPERATOR로 사용되는 칼럼에는 인덱스를 만들면 안된다.

*자주 변경되거나 인덱스를 만들때 얻는 효율성보다 삽입, 갱신, 삭제로 인해 잃는 효율성이 더 큰
칼럼에는 인덱스를 만들면 안된다. 이러한 OPERATION은 인덱스를 유지하기 위한 필요 때문에 느려
진다.

*UNIQUE 인덱스는 더 나은 선택성 때문에 NONUNIQUE 인덱스보다 좋다. PRIMARY KEY 칼럼에
UNIQUE 인덱스를 사용한다. 그리고 FOREIGN KEY 칼럼과 WHERE 절에서 자주 사용되는 칼럼에는
NONUNIQUE 인덱스를 사용한다.

5.가용한 인덱스 PATH를 만들어라
인덱스를 사용하기 위해서는 기술한 SQL문을 이용할 수 있는 식으로 SQL을 작성하라. OPTIMIZER는
인덱스가 존재하기 때문에 인덱스를 사용하는 ACESS PATH를 사용할 수 없다. 따라서 ACCESS PATH
는 반드시 SQL이 사용할 수 있게 만들어 져야 한다. SQL HINT를 사용하는 것은 인덱스 사용을
보증해주는 방법중 하나이다. 특정 ACCESS PATH를 선택하기 위한 다음의 힌트를 참고 하라

6.가능하면 EXPLAIN과 TKPROF를 사용하라
만약 SQL문이 잘 다듬어지지 않았다면 비록 오라클 데이터베이스가 잘 짜여져 있어도 효율성이 떨어
질 것이다. 이럴 경우 EXPLAIN TKPROF에 능숙해져야 한다. EXPALIN PLAN은 SQL이 사용하는
ACCESS PATH를 발견할 수 있게 해주고 TKPROF는 실제 PERFORMANEC의 통계치를 보여준다.
이 TOOL은 오라클 서버 소프트웨어에 포함되어 있고 SQL의 성능을 향상시켜 준다.

7.OPTIMIZER를 이해하라.
SQL은 RULE-BASED나 COST-BASED중 하나를 이용해서 기동된다.기존의 소프트웨어는 RULE BASED
방식을 채택하고 있다. 그리고 많은 오라클 소프트웨어가 이러한 방식을 오랫동안 사용해 왔다.
그러나 새로 출시된 소프트웨어에 대해서는 COST BASED 방식의 OPTIMIZER를 고려해야 한다.
오라클은 새로 출시되는 프로그램을 COST BASED방식으로 업그레이드 시켜왔으며 이러한 방식은
시스템을 훨씬 더 안정적으로 만들었다. 만약 COST BASED방식의 OPTIMIZER를 사용한다면 반드시
ANALYZE 스키마를 정기적으로 사용해야 한다. ANALYZE스키마는 데이터베이스 통계를 데이터 사전
테이블에 기록하는 역할을 수행하며 그렇게 되면 COST BASED OPTIMIZER가 그것을 사용하게
된다. SQL은 COST BASED OPTIMIZER를 사용할 때만 잘 조정될 수 있다. 만약 RULE BASED에서
COST BASED로 바꾸고 싶다면 데이터베이스를 사용하는 모든 소프트웨어의 모든 SQL문의 성능을
평가해 보아야 한다.

8.지엽적으로 동작하더라도 전역적으로 생각하라
항상 주의할 것은 하나의 SQL문을 조정하기 위해 생긴 데이터베이스안의 변화는 다른 응용프로그램
이나 다른 사용자가 이용하는 다른 명령문에 영향을 미친다는 사실이다.

9.WHERE절은 매우 중요하다.
비록 인덱스가 가용하다고 해도 다음의 WHERE 절은 그 인덱스 ACCESS PATH 를 사용하지 않는다.
(즉 COL1 과 COL2는 같은 테이블에 있으며 인덱스는 COL1에 만들어진다.)

COL1 > COL2
COL1 < COL2
COL1 > = COL2
COL1 <= COL2
COL1 IS NULL
COL1 IS NOT NULL.

인덱스는 NULL값을 갖는 칼럼에는 ROWID를 저장하지 않는다. 따라서 NULL값을 갖는 ROW를 검색할
때는 인덱스를 사용하지 못한다.

COL1 NOT IN (VALUE1, VALUE2 )
COL1 != EXPRESSION
COL1 LIKE '%PATTERN'.

이럴 경우 THE LEADING EDGE OF THE INDEX(?) 는 작동되지 않고 인덱스가 사용되지 못하게 한
다. 한편 COL1 LIKE 'PATTERN %'이나 COL1 LIKE 'PATTERN % PATTERN%' 는 한정된 인덱스
스캔을 수행하기 때문에 인덱스를 사용할 수 있다.

NOT EXISTS SUBQUERY
EXPRESSION1 = EXPRESSION2.

인덱스된 컬럼을 포함하는 표현(EXPRESSION), 함수, 계산(CALCULATIONS)은 인덱스를 사용하지
못한다. 다음의 예에서 보면 UPPER SQL 함수를 사용하면 인덱스 스캔을 사용할 수 없고
FULL TABLE SCAN으로 끝나고 만다.

SELECT DEPT_NAME
FROM DEPARTMENT
WHERE UPPER(DEPT_NAME) LIKE 'SALES%';

10.레코드 필터링을 위해서는 HAVING보다는 WHERE를 사용하라
인덱스가 걸려있는 칼럼에는 GROUP BY와 같이 HAVING절을 사용하지 마라. 이 경우 인덱스는 사용
되지 않는다. 또한 WHERE절로 된 ROW를 사용하지 마라. 만약 EMP테이블이 DEPTID컬럼에 인덱스
를 가지고 있다면 다음 질의는 HAVING 절을 이용하지 못한다.

SELECT DEPTID,
SUM(SALARY)
FROM EMP
GROUP BY DEPTID
HAVING DEPTID = 100;

그러나 같은 질의가 인덱스를 사용하기 위해 다시 씌여질 수 있다.

SELECT DEPTID,
SUM(SALARY)
FROM EMP
WHERE DEPTID = 100
GROUP BY DEPTID;

11. WHERE 절에 선행 INDEX 칼럼을 명시하라.
복합 인덱스의 경우, 선행 인덱스가 WHERE절에 명시되어 있다면 쿼리는 그 인덱스 를 사용할 것이
다. 다음의 질의는 PART_NUM과 PRODUCT_ID 칼럼에 있는 PRIMARY KEY CONSTRAINT에 기초한
복합 인덱스를 이용할 것이다.

SELECT *
FROM PARTS
WHERE PART_NUM = 100;

반면, 다음의 쿼리는 복합인덱스를 사용하지 않는다.

SELECT *
FROM PARTS
WHERE PRODUCT_ID = 5555;

같은 요청(REQUEST)이 인덱스를 이용하기 위해 다시 씌어 질 수 있다. 다음 질의의 경우,
PART_NUM컬럼은 항상 0 보다 큰 값을 가질것이다.

SELECT *
FROM PARTS
WHERE PART_NUM > 0
AND PRODUCT_ID = 5555;

12.인덱스 SCAN과 FULL TABLE SCAN을 평가하라.
한 행(ROW)의 15% 이상을 검색하는 경우에는 FULL TABLE SCAN이 INDEX ACESS PATH보다 빠르
다. 이런 경우, SQL이 FULL TABLE SCAN을 이용할 수 있도록 여러분 스스로 SQL을 작성하라.
다음의 명령문은 비록 인덱스가 SALARY COLUMN에 만들어져 있어도 인덱스 SCAN을 사용하지 않을
것이다. 첫 번째 SQL에서, FULL HINT를 사용한다면 오라클은 FULL TABLE SCAN을 수행할 것이
다. 인덱스의 사용이 나쁜 점이 더 많다면 아래의 기술을 이용해서 인덱스 수행을 막을수 있다.

SELECT * --+FULL
FROM EMP
WHERE SALARY = 50000;

SELECT *
FROM EMP
WHERE SALARY+0 = 50000;

다음의 명령문은 비록 인덱스가 SS# COLUMN에 있어도 인덱스 SCAN을 사용하지 않을 것이다.

SELECT *
FROM EMP
WHERE SS# || ' ' = '111-22-333';

오라클이 불분명한 데이터 변환을 수행해야 하는 경우 인덱스가 항상 사용되지않는 것은 아니다.
다음의 예를 보면, EMP 칼럼에 있는 SALARY는 숫자형 칼럼이고 문자형이 숫자값으로 변환된다.

SELECT *
FROM EMP
WHERE SALARY = '50000';

테이블의 행이 15%이거나 그보다 작을 경우 인덱스 스캔은 보다 잘 수행 될 것이다. 왜냐 하면 인덱
스 스캔은 검색된 행(ROW)하나 하나 마다 다중의 논리적인 읽기 검색(READ)을 할 것이기 때문이
다. 그러나 FULL TABLE SCAN은 하나의 논리적 인 읽기 검색 영역 안의 BLOCK에 있는 모든 행들을
읽을 수 있다. 그래서 테이블의 많은 행들에 접근해야 하는 경우에는 FULL TABLE SCAN이 낫다.
예로 다음의 경우를 보자. 만약 EMP TABLE과 그 테이블의 모든 인덱스에 대해 ANALYZE라는 명령어
가 수행된다면, 오라클은 데이터 사전인 USER_TABLES와 USER_INDEXES에 다음과 같은 통계치를
산출해 낸다.

TABLE STATISTICS:
NUM_ROWS = 1000
BLOCKS = 100

INDEX STATISTICS:

BLEVEL = 2
AVG_LEAF_BLOCKS_PER_KEY = 1
AVG_DATA_BLOCKS_PER_KEY = 1

이러한 통계치에 근거해서, 아래에 보이는 것이 각각의 다른 SCAN에 대한 논리적인 읽기(READ)-즉
ACESS된 BLOCK이 될 것이다.

USE OF INDEX TO RETURN ONE ROW = 3

(BLEVEL+(AVG_LEAF_BLOCKS_PER_KEY - 1) +
AVG_DATA_PER_KEY

FULL TABLE SCAN = 100
(BLOCKS)

USE OF INDEX TO RETURN ALL ROWS = 3000
(NUM_ROWS * BLOCKS ACCESSED TO RETURN ONE ROW USING INDEX)

13. 인덱스 스캔에 ORDER BY를 사용하라
오라클의 OPTIMIZER는 , 만약 ORDER BY라는 절이 인덱스된 칼럼에 있다면 인덱스 스캔을 사용할
것이다. 아래의 질의는 이러한 점을 보여 주는 것인데 이 질의는 비록 그 칼럼이 WHERE 절에 명시
되어 있지 않다고 해도 EMPID컬럼에 있는 가용한 인덱스를 사용할 것이다. 이 질의는 인덱스로부
터 각각의 ROWID를 검색하고 그 ROWID를 사용하는 테이블에 접근한다.

SELECT SALARY
FROM EMP
ORDER BY EMPID;

만약 이 질의가 제대로 작동하지 않는다면, 당신은 위에서 명시되었던 FULL HINT를 사용하는 같은 질의를 다시 작성함으로써 다른 대안들을 이용해 볼 수 있다.


14. 자신의 데이터를 알아라
내가 이미 설명한 것처럼, 당신은 당신의 데이터를 상세하게 알고 있어야 한다.예를 들어 당신이
BOXER라는 테이블을 가지고 있고 그 테이블이 유일하지 않은 인덱스를 가진 SEX라는 컬럼과
BOXER_NAME이라는 두 개의 테이블을 가지고 있다고 가정해 보자. 만약 그 테이블에 같은 수의
남자, 여자 복서가 있다면 오라클이 FULL TABLE SCAN을 수행하는 경우 다음의 질의가 훨씬 빠를
것이다.

SELECT BOXER_NAME
FROM BOXER
WHERE SEX = 'F';

당신은 다음과 같이 기술함으로써 질의가 FULL TABLE SCAN을 수행하는지를 확실하게 해둘수 있다.

SELECT BOXER_NAME --+ FULL
FROM BOXER
WHERE SEX = 'F';

만약 테이블에 980 명의 남성 복서 데이터가 있다면, 질의는 인덱스 SCAN으로 끝나기 때문에
아래형식의 질의가 더 빠를 것이다.

SELECT BOXER_NAME --+ INDEX (BOXER BOXER_SEX)
FROM BOXER
WHERE SEX = 'F';

이 예는 데이터의 분포에 대해 잘 알고 있는 것이 얼마나 중요한 가를 예시해 준다. 데이터가 많아지고(GROW) 데이터 분포가 변화하는 것처럼 SQL 도 매우 다양할 것이다. 오라클은 OPTIMIZER 가 테이블에 있는 데이터의 분포를 잘 인식하고 적절한 실행 계획을 선택하도록 하기 위해 오라클 7.3 에 HISTOGRAMS라는 기능을 추가했다.

15. KNOW WHEN TO USE LARGE-TABLE SCANS.
작거나 큰 테이블에서 행들을 추출할 때, 전체 테이블의 검색은 인텍스를 사용한 검색보다 성능이
더 좋을 수도 있다. 매우 큰 테이블의 인덱스 검색은 수많은 인덱스와 테이블 블록의 검색이 필요할
수도 있다. 이러한 블록들이 데이터베이 스 버퍼 캐쉬에 이동되면 가능한한 오래도록 그곳에 머무른
다. 그래서 이러한 블록들이 다른 질의등에 필요하지 않을 수도 있기 때문에, 데이터베이스 버퍼
히트 비율이 감소하며 다중 사용자 시스템의 성능도 저하되기도 한다. 그러나 전체 테이블 검색에
의해서 읽혀진 블록들은 데이터베이스 버퍼 캐쉬에서 일찍 제거가 되므로 데이터베이스 버퍼 캐쉬
히트 비율은 영향을 받지 않게 된다.

16. MINIMIZE TABLE PASSES.
보통, SQL질의시 참조하는 테이블의 숫자를 줄임으로 성능을 향상시킨다. 참조되는 테이블의 숫자
가 적을수록 질의는 빨라진다. 예를 들면 NAME, STATUS, PARENT_INCOME, SELF_INCOME의 네개
의 컬럼으로 이루어진 학생 테이블 에서 부모님에 의존하는 학생과 독립한 학생의 이름과 수입에
대해서 질의시, 이 학생 테이블을 두번 참조하여 질의하게 된다..
SELECT NAME, PARENT_INCOME
FROM STUDENT
WHERE STATUS = 1
UNION
SELECT NAME, SELF_INCOME
FROM STUDENT
WHERE STATUS = 0;
( NAME이 프라이머리 키이며, STATUS는 독립한 학생의 경우는 1, 부모님에 의존적인 학생은 0으로
표시한다)
위의 같은 결과를 테이블을 두번 참조하지 않고도 질의 할 수 있다.

SELECT NAME,PARENT_INCOME*STATUS + SELF_INCOME(1-STATUS)
FROM STUDENT;

17. JOIN TABLES IN THE PROPER ORDER.
다수의 테이블 조인시 테이블들의 조인되는 순서는 매우 중요하다. 전반적으로, 올바른 순서로 테이
블이 조인되었다면 적은 수의 행들이 질의시 참조된다. 언제나 다수의 조인된 테이블들을 질의시
우선 엄격하게 조사하여 행들의 숫자를 최대한으로 줄인다. 이러한 방법으로 옵티마이저는 조인의
차후 단계에서 적은 행들을 조사하게 된다. 뿐만 아니라, 여러 조인을 포함하는 LOOP JOIN에서는
가장 먼저 참조되는 테이블(DRIVING TABLE)이 행들을 최소한으로 리턴하도록 해야한다. 그리고,
마스터와 상세 테이블 조인시에는(예를 들면 ORDER & ORDER LINE ITEM TABLES) 마스터 테이블
을 먼저 연결 시켜야 한다. 규칙에 근거한 옵티마이저의 경우에는 FROM CLAUSE의 마지막 테이블
이 NESTED LOOP JOIN의 DRIVING TABLE이 된다. NESTED LOOP JOIN이 필요한 경우에는 LOOP
의 안쪽의 테이블에는 인텍스를 이용하는 것을 고려할 만하다. EXPLAIN PLAN과 TKPROF는 조인
타입, 조인 테이블 순서, 조인의 단계별 처리된 행들의 숫자들을 나타낸다.
비용에 근거한 옵티마이저의 경우에는 WHERE CLAUSE에 보여지는 테이블의 순서는 옵티마이저가
가장 최적의 실행 계획을 찾으려고 하는 것과 상관 없다. 조인되는 테이블의 순서를 통제하기 위해
서 ORDERED HINT를 사용하는 것이 낫다.

SELECT ORDERS.CUSTID, ORDERS.ORDERNO,
ORDER_LINE_ITEMS.PRODUCTNO --+ORDERED
FROM ORDERS, ORDER_LINE_ITEMS
WHERE ORDERS.ORDERNO = ORDER_LINE_ITEMS.ORDERNO;

18. USE INDEX-ONLY SEARCHES WHEN POSSIBLE.
가능하다면, 인덱스만을 이용하여 질의를 사용하라. 옵티마이저는 오직 인덱스만을 찾을 것이다.
옵티마이저는 SQL을 만족시키는 모든 정보를 인덱스에서 찾을수 있을때,인덱스만을 이용할 것이다.
예를들면, EMP테이블이 LANME과 FNAME의 열에 복합 인덱스를 가지고 있다면 다음의 질의는
인덱스만은 이용할 것이다.

SELECT FNAME
FROM EMP
WHERE LNAME = 'SMITH';

반면에 다음의 질의는 인덱스와 테이블을 모두 참조한다.

SELECT FNAME , SALARY
FROM EMP
WHERE LNAME = 'SMITH';

19. REDUNDANCY IS GOOD.

WHERE CLAUSE에 가능한한 많은 정보를 제공하라. 예를 들면 WHERE COL1 = COL2 AND COL1 = 10
이라면 옵티마이저는 COL2=10이라고 추론하지만, WHERE COL1 = COL2 AND COL2 = COL3이면
COL1=COL3이라고 초론하지는 않는다.

20. KEEP IT SIMPLE, STUPID.
가능하면 SQL문을 간단하게 만들라. 매우 복잡한 SQL문은 옵티마이저를 무력화시킬 수도 있다.
때로는 다수의 간단한 SQL문이 단일의 복잡한 SQL문보다 성능이 좋을 수도 있다.
오라클의 비용에 근거한 옵티마이저는 아직은 완벽하지않다. 그래서 EXPLAIN PLAN에 주의를
기울여야 한다. 여기서 비용이란 상대적인 개념이기에 정확히 그것이 무엇을 의미하는지 알지
목한다. 하지만 분명한 것은 적은 비용이 보다 좋은 성능을 의미한다는 것이다.
종종 임시 테이블을 사용하여 많은 테이블들을 포함하는 복잡한 SQL 조인을 쪼개는 것이 효율적일
수도 있다. 예를 들면, 조인이 대량의 데이터가 있는 8개의 테이블을 포함할 때, 복잡한 SQL을 두
세개의 SQL로 쪼개는 것이 낫을 수 있다. 각각의 질의는 많아야 네개정도의 테이블들을 포함하며
중간 값을 저장 하는 것이 낫을 수 있다.

21. YOU CAN REACH THE SAME DESTINATION IN DIFFERENT WAYS.
많은 경우에, 하나 이상의 SQL문은 의도한 같은 결과를 줄 수 있다. 각각의 SQL은 다른 접근 경로
를 사용하며 다르게 수행한다. 예를들면, MINUS(-) 산술자는 WHERE NOT IN (SELECT ) OR
ERE NOT EXISTS 보다 더 빠르다.
예를들면, STATE와 AREA_CODE에 각각 다른 인덱스가 걸려 있다. 인덱스에도 불구하고 다음의 질의
는 NOT IN의 사용으로 인해 테이블 전체를 조사하게된다.
SELECT CUSTOMER_ID
FROM CUSTOMERS
WHERE STATE IN ('VA', 'DC', 'MD')
AND AREA_CODE NOT IN (804, 410);

그러나 같은 질의가 다음 처럼 쓰여진다면 인덱스를 사용하게 된다
SELECT CUSTOMER_ID
FROM CUSTOMERS
WHERE STATE IN ('VA', 'DC', 'MD')
MINUS
SELECT CUSTOMER_ID
FROM CUSTOMERS
WHERE AREA_CODE IN (804, 410);

WHERE절에 OR을 포함한다면 OR대신에 UNION을 사용할 수 있다. 그래서, SQL 질의를 수행하기
전에 먼저 실행계획을 조심스럽게 평가해야 한다. 이러한 평가는 EXPLAIN PLAN AND TKPROF를 이
용하여 할 수 있다.

22. USE THE SPECIAL COLUMNS.
ROWID AND ROWNUM 열을 이용하라. ROWID를 이용하는 것이 가장 빠르다.
예를들면, ROWID를 이용한 UPDATE는 다음과 같다.

SELECT ROWID, SALARY
INTO TEMP_ROWID, TEMP_SALARY
FROM EMPLOYEE;

UPDATE EMPLOYEE
SET SALARY = TEMP_SALARY * 1.5
WHERE ROWID = TEMP_ROWID;

ROWID값은 데이터베이스에서 언제나 같지는 않다. 그래서, SQL이나 응용 프로그램이용시 ROWID값
을 절대화 시키지 말라. 리턴되는 행들의 숫자를 제한 시키기위해 ROWNUM을 이용하라. 만약에 리턴
되는 행들을 정확히 모른다면 리턴되는 행들의 숫자를 제한하기위해 ROWNUM을 사용하라
다음의 질의는 100개 이상의 행들을 리턴하지는 않는다.
SELECT EMPLOYE.SS#, DEPARTMENT.DEPT_NAME
FROM EMPLOYEE, DEPENDENT
WHERE EMPLOYEE.DEPT_ID = DEPARTMENT.DEPT_ID
AND ROWNUM < 100;

23.함축적인 커서대신 명시적인 커서를 사용하라.
함축적 커서는 여분의 FETCH를 발생시킨다. 명시적 커서는 DECLARE, OPEN, FETCH와 CLOSE
CURSOR문을 사용하여 개발자에 의해서 생성된다. 함축 커서는 DELETE, UPDATE, INSERT와
SELECT문을 사용하면 오라클에 의해서 생성된다.

24.오라클 병렬 쿼리 옵션을 찾아서 이용하라.
병렬 쿼리 옵션을 사용하면, 보다 빠른 성능으로 SQL을 병렬로 실행할 수 있다.
오라클 7에서는, 오직 FULL TABLE SCAN에 기반한 쿼리만이 병렬로 수행될 수 있다.
오라클 8에서는, 인덱스가 분할되어있다면 INDEXED RANGE SCANS에 기반한 쿼리도 병렬로 처리될
수 있다. 병렬 쿼리 옵션은 다수의 디스크 드라이버를 포함하는 SMP와 MPP SYSTEM에서만 사용될
수 있다.

오라클 서버는 많은 우수한 특성을 가지고 있지만, 이러한 특성의 존재만으로는 빠른 성능을 보장하
지 않는다. 이러한 특성을 위해서 데이터베이스를 조정해야하며 특성을 이용하기 위해 특별하게 SQL
을 작성해야 한다. 예를 들면, 다음의 SQL은 병렬로 수행될 수 있다.

SELECT * --+PARALLEL(ORDERS,6)
FROM ORDERS;

25.네트웍 소통량을 줄이고 한번에 처리되는 작업량을 늘려라.
ARRAY PROCESSING과 PL/SQL BLOCK을 사용하면 보다 나은 성능을 얻을 수 있고 네트웍 소통량을
줄인다. ARRAY PROCESSING은 하나의 SQL문으로 많은 ROW를 처리할 수 있게 한다. 예를 들면,
INSERT문에서 배열을 사용하면 테이블내의 1,000 ROW를 삽입할 수 있다. 이러한 기술을 사용하면
주요한 성능 향상을 클라이언트/서버와 배치시스템에서 얻어질 수 있다.

복합 SQL문은 과도한 네트웍 소통을 유발할 수 있다. 그러나 만일 SQL문이 단일 PL/SQL 블록안에
있다면, 전체 블록은 오라클 서버에 보내져서 그곳에서 수행되고, 결과는 클라이언트의
APPLICATION에게 돌아온다.

개발자와 사용자는 종종 SQL을 데이터베이스에서 데이터를 검색하고 전송하는 간단한 방법으로 사용
한다. 때때로 직접적으로 SQL을 작성하지 않고 코드 발생기를 사용하여 작성한 APPLICATION은 심
각한 성능 문제를 일으킨다. 이러한 성능감퇴는 데이터베이스가 커지면서 증가한다.

SQL은 유연하기 때문에, 다양한 SQL문으로 같은 결과를 얻을 수 있다. 그러나 어떤 문은 다른 것보
다 더 효율적이다. 여기에 기술된 팁과 기법을 사용하면 빠르게 사용자에게 정보를 제공할 수 있는
APPLICATION과 리포트를 얻을 수 있다.

'컴퓨터 > DB' 카테고리의 다른 글

데이터베이스(DB) 옵티마이져의 기본원리  (0) 2009.01.15
Function 과 Procedures의 차이점  (0) 2009.01.15
데이터베이스의 DDL, DML, DCL  (0) 2009.01.15
페이징 방법 중 하나..  (0) 2009.01.15
오라클 함수 모음  (0) 2009.01.15
      
Posted by k_ben


오라클 옵티마이저의 기본 원리

이상원 | (주)엑셈 연구소장 겸 성균관대학교 교수

현재 모든 관계형 DBMS에서는 사용자의 SQL 질의를 효율적으로 처리하기 위해 옵티마이저를 사용하고 있다. 개발자나 관리자들이 이 옵티마이저의 기본 동작 원리를 이해한다면, 여러 면에서 도움이 되리라는 생각에 이 글을 쓰게 되었다. 먼저, 옵티마이저에 대한 기본적인 이해를 구한 다음, 오라클 옵티마이저에 대해 알아보도록 한다.
본론에 앞서, 이 글은 관계형 데이타베이스 개념에 일정 정도 익숙한 독자들을 대상으로 작성되었기 때문에, 초보자는 이해하기가 난해할 수도 있다는 점과 오라클 옵티마이저가 워낙 광범위한 기술이라 모든 세부적인 내용을 다 다룰 수는 없으며, 필자도 오라클 옵티마이저의 모든 내부 동작 원리를 완전히 이해하고 있지는 못하다는 점에 양해를 바란다. 미진하고 잘못된 부분은 모두 필자의 책임임을 밝혀 둔다.

관계형 DBMS와 옵티마이저

21세기에 들어서도 여전히 관계형 DBMS가 데이타베이스 시장을 지배하고 있다.
그리고, 관계형 DBMS에서 사용되는 핵심 언어는 SQL(Structured Query Language)이다. 이 SQL 언어의 가장 큰 특징은 사용자가 데이타베이스에서 자신이 원하는 데이타(What)만 지정하면, 그 데이타를 어떻게 구하는가(How)는 DBMS가 자동적으로 결정해서 처리해 준다는 점이다.
이런 면에서 SQL을 선언적(declarative) 언어(주 1)라고 부르며, 사용자는 데이타베이스의 물리적 구조의 변경에 상관 없이 항상 원하는 정확한 결과 데이타를 구할 수 있다. 이러한 물리적 데이타 독립성(physical data independence)이 관계형 DBMS를 상업적 성공으로 이끈 가장 큰 이유 중의 하나이다.
아무리 SQL이 이와 같은 장점을 갖고 있더라도, DBMS가 내부적으로 질의를 처리하는 방식이 비효율적이라면 관계형 DBMS는 누구도 사용하지 않을 것이다. 다행히도 현재의 모든 관계형 DBMS는 사용자의 SQL 질의를 효율적으로 수행하는 방법을 찾아내는 옵티마이저(Query Optimizer : 혹자는‘질의 최적화기’라고도 부르는데 이 글에서는‘옵티마이저’라 부르겠다.)를 제공하고 있다. 예를 들어, 다음과 같은 간단한 SQL 문을 보자.



emp와 dept는 각각 deptno와 loc 칼럼에 대해 B 트리 인덱스가 있다고 가정한다. 이 같은 단순한 질의 Q1의 경우에도 질의 결과를 구하는 방법, 즉 실행 계획 (execution plan)은 다양할 수 있다.
<그림 1>은 두 가지 실행 계획 P1과 P2를 보여주고 있다. P1은 우선 loc =‘SEOUL’조건을 만족하는 dept 레코드를 인덱스를 이용해서 찾고, 각 dept 레코드에 대해 eptno 값이 일치하는 emp의 레코드를 인덱스를 이용해서 찾아 값을 출력한다(Nested Loop 조인 방법 이용).



한편, P2는 emp/dept 테이블을 Full Table Scan해서 이들을 Sort Merge 조인방식으로 조인해서 질의 처리를 수행한다. 주목할 점은, 이 두 실행 계획 모두 정확한 질의 결과를 구하지만, 두 방식의 수행 시간에는 차이가 많이 날 수도 있다는 점이다. 예를 들어, P1 방식은 1초에 원하는 결과를 구하는 반면, P2 방식은 1시간이걸릴 수도 있다.
P1, P2 이외에도 질의 Q1을 수행할 수 있는 많은 실행 계획이 있을 수 있다. 실행 계획이란, 여러 개 테이블들의 조인에 대해, 특정한 1) 조인 순서(join ordering), 2) 조인 방법(join method), 그리고 3) 테이블 액세스 방법(access method)을 선 택하는 것이다.
옵티마이저는 가능한 실행 계획들을 모두 검토하고, 이 중에서 가장 효과적으로, 즉 가장 빨리, Q1의 결과를 구할 수 있는 실행 계획을 결정한다. 이 글에서는, 옵티마 이저가 최적의 실행 계획을 찾는 과정을‘질의 최적화(Query Optimization)’또 는 단순히‘최적화’라고 부르겠다.

관계형 DBMS 옵티마이저의 핵심 기능

관계형 DBMS 옵티마이저의 핵심 기능은 다음과 같다.

• 실행 계획 탐색(Search Space Enumeration) : 주어진 SQL 질의를 처리할 수 있는 실행 계획들을 나열(P1, .., Pn) ?
• 비용 산정(Cost Estimation) : 각 실행 계획의 예상 비용을 계산 많은 실행 계획들 중에서 최종적으로 가장 비용이 적게 드는 실행 계획 Pi를 선택해서 SQL을 실행하고 결과를 사용자에게 보여 준다. 다.

실행 계획 탐색

예를 들어, 3개의 테이블, T1, T2, T3에 대해 조인을 수행하는 SQL 문이 있다고 가정하자. 그럼 이 질의를 수행할 수 있는 가능한 실행 계획은 몇 가지일까? 우리는 앞에서 조인 순서, 조인 방법, 그리고 테이블 액세스 방법에 따라 서로 다른 실행계획이 만들어진다고 했다. 그렇다면, 3개의 테이블 T1, T2, T3에 대한 조인 순서는 3!, 즉 6개의 조인 순서가 있다.

(T1§_T2)§_T3, (T1§_T3)§_T2, (T2§_T1)§_T3, (T2§_T3)§_T1, (T3§_T1)§_T2, (T3§_T2)§_T1

그리고, 하나의 조인 순서에는 2개의 조인을 포함하는데, 이용 가능한 조인 방법이 Nested Loop, Sort Merge, Hash Join의 세 가지가 있다면, 각 조인 순서에 대해 총 32, 즉 9개의 조합이 가능하다. 그리고, 이 각각의 경우 테이블을 접근하는 액세스 방법이 Full Table Scan과 Index Scan의 두 가지가 있다면 23, 즉 8개의 서로 다른 조합이 가능하다.
따라서, 3! x 32 x 23 = 432가지의 실행 계획이 가능하다. 그런데, 옵티마이저가 고려해야 할 실행 계획의 개수는 SQL에 포함된 테이블의 개수가 증가함에 따라 기하급수적으로 늘어나게 된다. 만일 from 절의 테이블의 개수가 5개인 경우, 5! x 35 x 25 = 933,120개가 가능해진다.
그리고, 여기서 각 실행 계획의 예상 비용을 계산하는 데 걸리는 시간이 0.01초라고 가정했을 때, 모든 실행 계획의 예상 비용을 구하는 데 약 9,300초(약 2시간 36분)이 걸린다. 만일 테이블의 개수가 10개라고 가정하면, 아마도 모든 실행 계획의 예상 비용을 계산하는 데만도 몇 년이 걸릴지도 모른다.
21세기 IT 환경에서는 하나의 SQL 문에 5 ~ 10개 정도의 테이블이 포함되는 경우가 일반적이다. 그런데, 옵티마이저가 실행 계획을 선정하는 데 걸리는 시간이 이와같다면, 옵티마이저는 차라리 없는 것이 더 나을지도 모른다.
따라서, 옵티마이저는 모든 가능한 실행 계획을 다 고려할 수는 없다. 즉, 질의 최적화에 걸리는 시간을 줄이기 위해 어떤 실행 계획들은 아예 비용 계산에서 제외해야 할 필요도 있다. 옵티마이저는 모든 가능한 실행 계획 조합들을 탐색하는 방법 - 즉 어떤 실행 계획을 먼저 고려하고, 어떤 순서로 다음 실행 계획을 찾고, 어떤 실행 계획은 제외할 것인가? - 을 갖고 있어야 한다.

비용 산정

앞의 실행 계획 탐색 단계에서 만들어내는 각각의 실행 계획에 대해, 그 실행 계획을 실제로 수행할 때 비용 - 단순하게는 시간이 얼마나 걸릴지? - 을 예측해서, 가장 비용이 적은 실행 계획을 선택해야 한다.
이를 위해서 옵티마이저는 데이타베이스 내의 데이타들에 대해 갖고 있는 통계정보와 비용을 예측하는 다양한 모델을 사용해서 각 실행 계획의 비용을 계산할 수 있어야 한다.
여기서 주목할 점은, 옵티마이저가 실행 계획들을 비교할 때 사용하는 기준은‘예상비용’이라는 점이다. 앞의 예에서 P1과 P2 방법을 실제로 수행해 보고 더 좋은 방법을 결정하는 것이 아니라, 옵티마이저가 갖고 있는 통계정보를 활용해서 P1과 P2로 수행했을 때 어느 실행 계획의 예상 비용이 작은가를 보고서 이를 실제로 수행하게 되는 것이다.

Selinger 스타일의 옵티마이저

필자가 아는 한에서, 현재의 모든 상용 관계형 DBMS의 옵티마이저는 IBM DB2의 모태인 System-R 프로토타입 시스템을 개발할 당시에 고안된 아키텍처에 기반하고 있다<참고자료 4>. 이 아키텍처를 주도적으로 제안한 IBM의 여성 전산학자 Pat. Selinger의 이름을 따서, ‘Selinger 스타일 옵티마이저’라 부른다.
참고로 Pat. Selinger의 논문은 아직까지도 데이타베이스 분야에서 가장 많이 인용되는 논문 중의 하나이고, Pat. Selinger는 이 한 편의 논문으로 데이타베이스 연구 분야에서 슈퍼스타의 반열에 올라섰다.
이 Selinger 스타일 옵티마이저 아키텍처의 가장 큰 두 가지 특징은 1) 동적 프로그래밍 기반에 의한 실행 계획 탐색(Search Space Pruning based on Dynamic Programming)과 2) 비용 기반 최적화(Cost-Based Optimization)인데, 각각 위에서 나열한 옵티마이저 핵심 기능의 첫째, 둘째 기능에 해당된다.

옵티마이저의 이상과 현실

가장 이상적인 옵티마이저는, 모든 질의에 대해 옵티마이저가 선택한 실행 계획이 실제로 수행될 때도 가장 좋은 수행 속도를 보장하는 경우이다.
그러나, 현재의 옵티마이저는 비록 대부분의 경우에 상대적으로 아주 좋은 실행 계획<주 2>을 선택하지만, 실제로는 아주 나쁜 실행 계획을 선택하는 경우도 있다. 현재의 옵티마이저의 한계, 원인 그리고 앞으로의 개선 방향에 대해서는 뒤에서 자세히 설명하겠다.
옵티마이저는 30년 이상 축적된 기술을 포함하고 있는, 인간의 지능이 가장 많이 녹아 있는 복잡한 소프트웨어이다. 이 세상의 어떤 누구도 상용 관계형 DBMS 옵티마이저의 복잡한 내부 동작 원리를 완전히 이해하고 있는 사람은 없다고 단언할 수 있다.
실제로 필자도 이 글에서 주로 설명할 오라클 옵티마이저에 대해서 어쩌면 기본적인 지식밖에 없다고 할 것이다. 다만, 많은 오라클 개발자나 관리자들이 현대의 옵티마이저의 가장 기본적인 동작 원리를 쉽게 이해했으면 하는 마음으로 이 글을 썼다.

옵티마이저의 아키텍쳐

이제까지는 현재 보편적으로 사용되고 있는 관계형 DBMS 옵티마이저의 기능, 간단한 역사적 배경, 그리고 동작 원리에 대해 간략히 알아보았다. 이제부터는 이러한 배경 지식을 바탕으로 Oracle DBMS의 옵티마이저의 기본 구조와 동작 원리에 대해 알아보겠다.
오라클은 RBO(Rule-Based Optimization : 규칙기반 최적화)와 CBO(Cost-Based Optimization : 비용기반 최적화)를 모두 지원하고 있다. CBO의 경우, 1992년 Oracle 버전 7부터 도입되었는데, 향후 이 글에서 오라클 옵티마이저라 함은 CBO를 지칭하는 것이다. RBO는 간단한 규칙 위주로 최적화를 수행하는 방법으로, 앞으로는 널리 사용되지 않을 것이며, 오라클도 공식적으로 CBO 사용을 권장하고 있다.
<그림 2>는 오라클 옵티마이저의 아키텍처를 보여주고 있는데, 사용자의 SQL 질 의는 크게 다음 4단계를 거쳐서 수행된다.

1. 파싱(Parser)
2. 옵티마이저(Query Optimizer)
3. 로우소스 생성(Row Source Generator)
4. SQL 실행(SQL Execution Engine)

파싱(Parser) 단계는 SQL은 구문(syntax)과 의미(semantics) 검사를 수행한다.
예를 들어, SQL 구문이 정확한지를 검사하고, 참조된 테이블에 대해 사용자의 접근 권한 등을 검사한다. 이 단계가 끝나면, SQL 문은 파싱 트리(parsed tree) 형태로 변형되어 옵티마이저에게 넘겨진다.
옵티마이저(Query Optimizer) 단계는 앞에서 넘겨받은 파싱 트리를 이용해서 최적의 실행 계획을 고른다.
<그림 2>에서 점선 형태의 사각형으로 표시된 부분이 옵티마이저의 주요 구성 요 소를 보여주고 있는데, 뒤에서 각 구성 요소의 역할에 대해 자세히 설명하겠다.



로우소스 생성(Row Source Generator) 단계는 옵티마이저에서 넘겨받은 실행 계획을 내부적으로 처리하는 자세한 방법을 생성하는 단계이다. ‘로우 소스’란 실행 계획을 실제로 구현하는 인터페이스 각각을 지칭하는 말로, 테이블 액세스 방법, 조인 방법, 그리고 정렬(sorting) 등을 위한 다양한 로우 소스가 제공된다. 따라서, 이 단계에서는 실행 계획에 해당하는 트리 구조의 로우 소스들이 생성된다.
마지막으로, SQL 실행(SQL Execution Engine) 단계는 위에서 생성된 로우 소스를 SQL 수행 엔진에서 수행해서 결과를 사용자에게 돌려주는 과정이다.
여기서 한 가지 주목할 점은, 소프트 파싱(soft parsing)과 하드 파싱(hard parsing)은 크게 옵티마이저 단계의 포함 여부에 따른 차이이다. 즉, 소프트 파싱은 이미 최적화를 한 번 수행한 SQL 질의에 대해 옵티마이저 단계와 로우 소스 생성 단계를 생략하는 것이고, 하드 파싱은 이 두 단계를 새로 수행하는 것이다. 따라서, 하드 파싱은 통계정보 접근과 실행 계획 탐색 때문에 시간이 많이 걸린다. 이 차이가 주로 SQL 튜닝 전문가들이 가급적이면 하드 파싱을 피하라고 권하는 이유이다.

오라클 옵티마이저의 동작 원리

이제부터는 오라클 옵티마이저의 각 구성 요소의 기능에 대해 좀 더 자세히 알아 보자. <그림 2>에서 보듯이, 오라클 옵티마이저는 크게 다음 3가지 모듈로 구 성된다.

• 질의 변환(Query Rewriter)
• 실행 계획 생성(Plan Generator)
• 비용 산정(Estimator)

질의 변환 모듈

질의 변환(Query Rewriter 또는 Transformer) 단계는 파싱 트리(parsed tree) 를 받아들여서 질의 변환을 수행한다. 이 변환 과정을 통해서 의미적으로 같은 결과 를 수행하지만, 더 나은 실행 계획을 찾을 수 있는 SQL 문으로 변환함으로써 질의 의 수행 처리 속도를 높이는 데 그 목적이 있다. 오라클 옵티마이저가 수행하는 질 의 변환은 크게 다음 두 종류로 구분할 수 있다.

• 휴리스틱(Heuristic based) 질의 변환 : 이 변환의 종류로는 크게 View Merging, Subquery Unnesting, Predicate Push Down, Partition Pruning 등이 있는데, 이들 변환은 가능한 경우에 항상 질의 변환을 수행 한다. 왜냐하면, 이와 같은 변환은 경험적으로 거의 항상 원래 질의보다 더 빠른 수행 속도를 보장하기 때문이다.

• 비용 기반(Cost based) 질의 변환 : 이 변환의 예로는, MV Rewrite, Star Query Transformation, OR-expansion 등을 들 수 있다. 그런 데, 이 방법을 사용해서 변환된 SQL 문이 원래 SQL 문보다 속도가 더 빠르다는 보장이 없다. 따라서, 변환 전/후의 두 SQL 문에 대해 각각 최 선의 실행 계획을 구하고, 이들의 비용을 비교해서 더 효율적인 실행 계획 을 최종적으로 선택한다.

오라클의 질의 변환 모듈에서 지원하는 다양한 변환의 종류와 내용에 대해서는 <참고자료 2, 3>을 참고하기 바란다.
질의 변환 단계가 끝나면, 오라클 옵티마이저는 실행 계획 생성과 비용 산정 모듈을 수행하기 앞서, 질의에서 사용된 모든 테이블들과 각 테이블에 정의된 인덱스들에 관한 기본적인 통계정보들(예를 들어, 테이블의 블록 개수, 로우 평균 길이, 인덱스 의 높이, 인덱스 리프 블록의 개수 등)과 각 테이블에 대한 다양한 액세스 경로(예 를 들어, Full Table Scan, Index Scan 등)에 대한 비용 정보를 미리 구해 둔다.

옵티마이저의 아키텍쳐

실행 계획 생성 모듈

이 모듈은 옵티마이저가 새로운 실행 계획을 만드는 것이다. 오라클 옵티마이저는 제일 먼저 각 테이블의 레코드 수를 기준으로 오름차순으로 결정한다. 예를 들어, SQL 질의의 from 절에서 T1, T2, T3 순서로 참조한 경우, 각 테이블의 카디널러 티(cardinality : 테이블의 튜플 수)가 T1 > T2 > T3 순이라면 제일 처음 고려하 는 조인 순서는 (T3§_T2)§_T1 이 된다. 이 조인 순서에 대해서 다음 단계인 비용 산정 모듈을 호출해서 이 조인 순서에 따르는 실행 계획들과 각 실행 계획의 비용을 구한다.
그리고, 더 이상의 새로운 조인 순서가 없을 때까지 계속 새로운 조인 순서를 만들 어서 비용을 계산한다. 이 모듈은 지금까지 찾아낸 가장 좋은 실행 계획과 그 비용 을 저장하고 있다. 이 단계는 최종적으로 구해진 최적의 실행 계획을 | 그림 2 |의 로우 소스 생성 단계에 넘겨준다.
오라클의 실행 계획 생성 모듈은 테이블 개수가 정해진 값(디폴트 5)보다 작은 경우 에는 모든 조인 순서에 대해 고려하지만, 테이블 개수가 이 값을 넘어서면 where 절에 명시적으로 조인 조건이 테이블들을 앞에 포함하는 조인 순서만 고려한다. 예 를 들어, 6개의 테이블 T1, T2, ... , T6에 대한 조인을 수행하는 SQL 문에서 조 인 조건이 T1, T2, T5, T6에 대해서만 주어졌다면, T1, T2, T5, T6가 먼저 조인 되고, T3, T4는 항상 나중에 조인되는 조인 순서만 고려한다.
그런데, 이런 경우에도, 앞에서 언급한 것처럼, 테이블의 개수가 많으면 가능한 조 인 순서의 조합이 기하급수적으로 늘어나게 된다. 이렇게 되면 옵티마이저 시간이 너무 많이 걸리기 때문에, 옵티마이저는 일정한 수(디폴트로는 최대 80,000)의 조인 순서에 대해서만 비용을 계산하고, 이 중에서 가장 최선의 실행 계획을 찾게 된다. 즉, 모든 가능한 조인 순서 조합들 중에서 일부분만 비용을 계산하고, 나머지는 고 려하지 않는 것이다. 이를 실행 계획 탐색에 대한‘가지치기(pruning)’또는‘컷오 프(cutoff)’라 부른다.
그런데, 고려되지 않은 조인 순서 중에서 실제로 최선의 실행 계획이 포함되어 있을 수 있다. 옵티마이저가 제일 처음 고려하는 조인 순서를 테이블의 레코드 수의 오름 차순 순서로 정하는 이유는 경험적으로 이 순서 근처에 실제로 최적의 실행 계획이 존재하기 때문이다. 이와 같이 초기 조인 순서를 선택하는 휴리스틱(heuristic)을 사용함으로써 임의로 조인 순서를 시작했을 때 최적의 좋은 실행 계획이 컷오프되는 것을 막을 수 있다.
오라클 옵티마이저 실행 계획 생성 모듈(Oracle9i부터 도입된)의 또 다른 특징은, 조인 순서를 바꾸어가면서 지금까지 구한 최적의 실행 계획의 예상 비용이 그리 크 지 않은 경우, 최적화 단계를 일찍 끝내버린다.
예를 들어, 어떤 질의에 대해 10초 동안 최적화를 수행해서 찾은 최적 실행 계획의 예상 수행 시간이 1분이면, 남은 조인 순서가 더 있더라도 옵티마이저 단계를 종료 한다. 반면에, 지금까지 구한 최적 예상 수행 시간이 2시간이면, 더 나은 실행 계획 을 찾기 위해 새로운 조인 순서에 대해 계속 탐색할 필요가 있다. 이를‘적응적 탐 색 전략(adaptive search strategy)’이라 부른다.

비용 산정 모듈

자, 그럼 다음으로 비용 산정 모듈에 대해 알아보자. 실행 계획 생성 모듈에서 넘겨 받은 특정 조인 순서의 각 조인에 대해 Nested Loop, Sort Merge, Hash Join 방식과 각 테이블의 다양한 액세스 방법을 반복 적용하면서 각 단계별로 비용을 계 산해서 궁극적으로 해당 조인 순서에서 찾을 수 있는 최선의 실행 계획과 그 예상 비용을 구해서 실행 계획 생성 모듈에게 넘겨 준다.
현재의 조인 순서에 대해 중간 단계까지의 수행 비용이 실행 계획 생성 모듈에서 지 금까지 구한 최선의 예상 비용보다 더 크다면, 해당 조인 순서에 대해서는 더 이상 비용 산정을 수행하지 않고 끝낸다. 예를 들어, T1, T2, T3에 대해 (T1§_T2)§_T3 순서에 대해 비용이 1000이었는데, (T§_T3)§_T2 순서의 (T1§_T3) 비용이 1200이 었다면 더 이상 비용을 계산할 필요가 없다.
<그림 2>에 나와 있는 것처럼, 옵티마이저는 실행 계획의 비용을 계산하기 위한 비용 모델(Cost Model)을 갖고 있고, 이 비용 모델은 Oracle Data Dictionary에 서 관리하는 다양한 통계정보를 기반으로 크게 다음과 같은 세 가지 값(measure)의 예상치를 계산한다.

• 선택도(Selectivity) : Where 절에 있는 다양한 조건들의 선택도 계산
• 카디널러티(Cardinality) : 실행 계획상의 각각의 연산의 결과 카디널러 티 수 계산
• 비용(Cost) : 실행 계획상의 각각의 연산을 수행하는 데 소요되는 시간 비 용 계산

이 비용 산정을 위한 통계정보를 저장하는 Data Dictionary 테이블들은 DBA_TABLES, DBA_INDEXES, DBA_TAB_COL_STATISTICS, DBA_ HISTOGRAMS 등이다. 이 통계정보는 앞에서 언급한 테이블의 액세스 경로의 비 용 정보를 결정하는 데도 사용된다.
이들 테이블의 정보는 사용자가 ANALYZE 명령어나 DBMS_STATS 패키지를 이 용해서 관리하게 되는데, 이들 테이블에서 관리하는 통계정보의 종류와 통계정보를 수집/관리하고, 통계정보를 확인하는 자세한 방법은 이 글에서는 설명하지 않겠다< 참고자료 5>.
만일에 테이블과 인덱스에 대한 통계정보가 존재하지 않는 경우, 옵티마이저는 해당 테이블과 인덱스에 대해 디폴트로 가정하는 값들이 있다<참고자료 5>.

선택도
우선 선택도(selectivity)의 개념을 예로 들자. 앞에서 예로 든 질의 Q1에서 d.loc = ‘SEOUL’이라는 조건의 선택도는 dept 테이블 전체 중에서 loc의 값이 ‘SEOUL’인 레코드의 비율을 일컫는다. 옵티마이저는 선택도 계산을 통해서 해당 조건을 만족하는 레코드가 몇 건 정도가 되는지를 예측하게 된다.
옵티마이저는 만일 DBA_TABLES에 dept 테이블의 loc 칼럼의 distinct column values가 10이라면 옵티마이저는 선택도가 0.1이라고 판단하게 된다. 이때 선택도 를 이와 같이 정하는 이유는 dept 테이블이 loc 칼럼들에 골고루 분포되어 있다고 가정할 때 성립한다. 그러나, 실제로 loc 칼럼의 값들이 skew되어서 분포할 수도 있다.
예를 들어, 전체 레코드의 50%가 loc 값으로‘SEOUL’을 갖는다면 잘못된 선택도 값을 얻게 된다. 이와 같이 데이타 분포가 skew되어 있는 경우, 해당 칼럼에 대한 히스토그램 정보를 DBA_HISTOGRAM 테이블에 만들어 주어야 정확한 선택도 값 을 계산할 수 있다(이 경우는 0.5). 오라클 옵티마이저는 다양한 조건식의 종류에 대해 선택도를 통계정보에 기반해서 계산하는 수식을 내부적으로 갖고 있다. 그렇지만, 만일 dept 테이블이 아직 분석되지 않아서 통계정보가 없는 경우, 옵티마 이저는 내부적으로 갖고 있는 디폴트 값을 선택도로 지정한다(예를 들어, 0.01).

카디널러티
앞의 dept 테이블의 전체 레코드 건수가 1000일 때, 앞에서 설명한 loc = ‘SEOUL’의 선택도가 0.1로 계산되었을 때, 조건을 만족하는 레코드 건수는 1000 x 0.1, 즉 100개로 예상할 수 있다. 이와 같이 어떤 연산을 수행한 결과로 나오는 레코드 건수를‘카디널러티(cardinality)’라 하는데, 정확한 카디널러티를 계산하는 것은 좋은 실행 계획을 만드는 데 굉장히 중요하다.
예를 들어, (T1§_T2)§_T3 순서로 테이블을 조인할 때 (T1§_T2)의 결과와 T3를 조 인할 때 어떤 조인 방법을 선택하는 것이 좋을지를 결정하기 위해서는 (T1§_T2)의 크기를 정확하게 알아야 한다. 이를 위해서는 (T1§_T2) 조인의 결과 레코드가 몇 개인지를 예상할 수 있어야 한다.
이를 위해 오라클 옵티마이저는 다양한 연산의 결과 레코드의 카디널러티를 통계정 보와 수식에 의해서 계산한다. T1과 T2의 조인 조건이 T1.c1 = T2.c2(이를‘P’라 표기)라 했을 때, 앞에서 설명한 선택도 계산 공식에 의해 이 조건식의 선택도 Sel(P)를 먼저 계산한 후, 이 조인의 결과 카디널러티는 Card(T1) x Card(T2) x Sel(P)가 된다.
예를 들어, T1, T2의 튜플 수가 각각 1000, 5000이고 Sel(P)가 0.01이면, 조인의 결과로 생기는 튜플 수는 1000 x 5000 x 0.01 = 5000이 된다. 그런데, Sel(P)가 조금이라도 틀리면 이후의 전체적인 비용 산정이 잘못되게 된다. 오라클 옵티마이저 는 다양한 종류의 연산에 대해 내부 공식을 사용해 카디널러티를 계산한다.

비용
비용(cost)은 테이블 액세스, 조인 등을 수행하는 데 걸리는 시간을 의미하는데, 시 간은 주로 디스크 I/O 수와 CPU 사용시간을 고려한다. 비용은 앞에서 계산한 통계 정보와 내부 계산식에 의해 계산된다.
예를 들어, T1§_T2를 Nested Loop 방식으로 조인할 경우 조인비용은 (T1의 데이 타 블록수) + ((T1의 레코드 건수)*(T2의 액세스 비용))이 된다. 이처럼 오라클 옵 티마이저는 모든 연산에 대해 소요되는 비용을 계산하는 수식을 갖고 있다. 오라클 옵티마이저는 이 세 가지 예상 값(measure)을 기반으로, 현재의 실행 계획 의 예상 비용을 구한다.

오라클 옵티마이저와 관련한 몇 가지 유용한 기능

이상에서 오라클 옵티마이저의 내부 동작 원리를 살펴보았다. 옵티마이저와 관련해 서 오라클에서 제공하는 몇 가지 유용한 기능들에 대해서 간단히 알아보자(이들 기 능에 대한 자세한 설명은 <참고자료 3>을 보기 바란다).
이 기능들은 크게 두 가지 - 즉, 옵티마이저가 사용할 통계정보를 수집/관리하는 기 능과 옵티마이저의 활동을 자세히 추적할 수 있는 기능 - 로 구분할 수 있다.
먼저, 통계정보 수집/관리 기능으로는 ANALYZE 명령과 DBMS_ STATS 패키지 를 들 수 있다. 비용 계산이 최적의 실행 계획을 구하는 데 중요한 역할을 하기 때 문에, 이 기능을 사용해서 1) 어떤 테이블이나 칼럼에 변경사항이 많이 발생해서 새 로 통계정보를 분석해야 하는지, 2) 어떤 칼럼에 대해 히스토그램을 만들어야 하는 지에 대한 도움을 받을 수 있다.
다음으로 옵티마이저의 활동 추적과 관련해서, 1) 주어진 질의에 대해서 어떠한 최 적화 과정을 거쳤는지, 2) 최종적으로 어떤 실행 계획을 선택했는지, 그리고, 선택 된 실행 계획대로 수행했을 때 걸리는 시간과 자원이 얼마나 소요되었는지를 확인하 는 기능들이 제공된다. 우선 옵티마이저의 최적화 과정을 확인하려면, ‘Event 10053’을 이용하면 된다. 이를 위해서는 SQL*Plus에서 다음 alter 명령을 수행하 면 된다.

SQL> alter session set events ‘10053 trace name context
forever’;

,P> 이 명령을 수행하고 나면, 현재 세션에서 수행하는 모든 질의에 대해 옵티마이저의 최적화 과정의 모든 정보가 $ora_home/admin/udump /xxx.trc 파일에 기록된 다. 이 트레이스 파일은 오라클 옵티마이저가 고려한 모든 조인 순서, 조인 방법, 테이블 액세스 방법, 선택도, 카디널러티, 비용 정보 등을 포함하고 있다.
다음으로, 단순히 옵티마이저가 최종적으로 선택한 실행 계획만 확인하고 싶으면, EXPLAIN 명령어나 SQL*Plus에서 제공되는 Autotrace 기능을 이용하면 된다. 그리고, 옵티마이저가 선택해서 수행한 실행 계획의 자세한 성능 정보를 알고 싶으 면, SQL Trace, TKPROF 등의 기능을 이용하면 된다.

오라클 옵티마이저의 한계와 그 원인

오라클 옵티마이저를 포함한 현재의 관계형 DBMS의 옵티마이저는 항상 최적의 실 행 계획을 고르지는 못한다. 옵티마이저의 한계는 실행 계획 생성 모듈과 비용 산정 모듈의 동작 원리에 그 원인이 숨어 있다.

실행 계획 생성 모듈의 제약
우선, 실행 계획 생성 모듈에서 최적화를 위해 사용할 수 있는 시간이 제한적이라는 점이다. 앞서 살펴보았지만, 10개 이상의 테이블 조인을 포함하는 질의의 경우 최적 의 실행 계획을 구하기 위해 옵티마이저가 고려해야 할 탐색 공간이 너무 많기 때문 에 다양한 형태의 컷오프를 수행한다. 이 과정에서 실제로 최적의 실행 계획이 고려 되지 않고 잘려나갈 수 있다.

비용 산정 모듈의 불완전성
비용 산정 모듈에서는 특정 실행 계획의 비용을 통계정보와 내부적인 비용 산정 모 델을 사용해서 계산한다. 그런데, 옵티마이저에서 사용하는 통계정보와 비용 산정 모델이 불완전하다. 따라서, 옵티마이저는 불완전한 정보를 바탕으로 일종의 추측 (또는 가정)을 하는 것이다.
예를 들어, d.loc = ‘SEOUL’의 선택도를 구하는 과정을 보자. d.loc에 대한 히스 토그램 통계정보가 없으면, 옵티마이저는‘모든 값들이 골고루 분포되어 있다’는 가 정하에 d.loc 칼럼의 distinct value 개수(이를 NDV라 하자)를 기준으로 해당 조 건의 선택도를 1/NDV로 계산한다. 그러나, 실제로는 d.loc에 대해 skew된 분포를 보이면 옵티마이저의 실행 계획 비용 산정이 틀려지게 된다.
비용 산정 모듈이 한계를 갖게 되는 또 다른 예로, SQL에서 바인드 변수(bind variables)의 사용을 들 수 있다. 질의 Q1에서 d.loc = ‘SEOUL’대신에 d.loc = :loc_name 조건이 사용되었으면, 데이타베이스에 loc 칼럼에 아무리 정확한 통계치 를 갖고 있어도 선택도에 대해서는 일정한 비율을 가정할 수밖에 없다. 다른 예로서, 다음 질의를 살펴보자.



데이타베이스에는 job_title, salary 칼럼 모두에 대해 정확한 히스토그램 정보를 유 지하고 있고, job_title = ‘vice_president’의 선택도가 0.05이고, salary < 40000 의 선택도는 0.4였다. 이때 옵티마이저는 emp 테이블에서 where 절의 조건의 전 체 선택도를 0.05 x 0.4, 즉 0.02로 계산한다. 이는‘각 칼럼의 값들의 분포는 서 로 독립적이다’는 가정에 기반하다.
그러나, 부사장이면서 연봉이 40,000 이하인 경우는 거의 없기 때문에 실제 선택도 는 0에 가까울 것이다. 결국 앞의 가정은 이와 같이 서로 밀접한 상관관계가 있는 두 칼럼에 대한 선택도를 구할 때 문제가 되는 것이다.
마지막 예로, 조인 연산에 대한 비용을 예측할 때, 이 조인을 수행할 수 있는 메모 리 공간을 고정 크기로 가정하고, Nested Loop, Sort Merge, Hash Join의 비용 을 산정한다. 그러나, 질의를 수행할 때 실제 비용은 이용 가능한 메모리의 양에 따 라 크게 차이가 날 수 있다.
결론적으로, 옵티마이저의 정확도는 비용 계산의 정확도에 따라 좌우되는데, 참고하 는 통계정보가 부족하거나 계산 과정의 몇 가지 가정들이 실제 데이타 분포와 실행 계획의 런타임 환경과 차이가 있기 때문에 정확도에 문제가 발생하는 것이다.

힌트 기능을 이용한 옵티마이저 동작 제어

이와 같은 현재의 옵티마이저의 한계를 보완하기 위해, 오라클에서는 SQL에 힌트 (hint)를 추가해서 사용자가 옵티마이저가 선택하는 실행 계획에 영향을 줄 수 있도 록 하고 있다.
옵티마이저가 최선이 아니 차선의 실행 계획을 선택하는 경우, 사용자가 SQL에 힌트 를 주어서 실행 계획을 베스트 플랜으로 만들도록 하는 것이 목적이다. 힌트를 제공 하는 것이 옵티마이저의 기능이 떨어지는 것을 의미하는 것은 아니다. 어떤 DBMS의 옵티마이저도 완전할 수는 없기 때문에, 힌트 기능의 제공은 반드시 필요하다.
옵티마이저의 실행 계획은 결국 조인 순서, 조인 방법, 테이블 액세스 경로를 결정 하는 것이기 때문에, 힌트의 종류도 크게 이 세 가지를 제어하는 것으로 구분할 수 있다.
다음 예는 Q1에 대해 힌트를 사용한 예를 보여주고 있는데, 처음 ‘ordered’는 from 절에 나와 있는 순서대로 조인 순서를 정하는 것이고, ‘use_nl’의 경우 dept 테이블을 inner table로 사용할 때 Nested Loop 방식만을 사용하도록 지정하고, full(e)는 emp 테이블은 항상 Full Table Scan을 통해서 액세스하도록 지정하는 것이다.
오라클에서 제공하는 다양한 힌트의 종류와 자세한 의미에 대한 설명은 <참고자료 5>를 보기 바란다.



오라클 SQL에서 힌트를 제공하는 또 다른 목적은, 사용자가 다양한 실행 계획을 수 행해 봄으로써 어떤 데이타 액세스 경로가 도움이 되는지를 테스트해 볼 수도 있다. 힌트의 사용은 아주 불가결한 경우 말고는 사용을 조심해야 한다. 실제로 이 힌트 기능이 남용되는 경우가 많다.
힌트를 사용하게 됨으로써 데이타베이스 환경의 변화(예를 들어, 테이블의 크기 변 화, 인덱스의 추가/삭제)가 발생할 때 옵티마이저가 더 나은 실행 계획을 선택하는 것을 방해할 수도 있다. 실제로 Oracle E-Business Suite 11i의 경우 포함된 27만 개의 SQL 중에서 0.3%만이 힌트를 포함하고 있다고 한다.

SQL 튜닝과 옵티마이저의 관계

SQL 튜닝은 특정 SQL 질의의 수행 시간을 단축하기 위해 사용자가 취하는 다양한 방법을 통칭한다. SQL 튜닝의 범위는 굉장히 포괄적인데, 옵티마이저와 관련한 방 법으로는 SQL 재작성, 힌트 사용, 새로운 인덱스 추가, 통계 데이타의 추가/갱신 등을 통해서 옵티마이저가 더욱더 효율적인 실행 계획을 생성하도록 하는 것이다.

SQL 재작성
사용자가 원하는 데이타를 질의하는 방법은 실제로 매우 다양할 수 있다. 극단적인 예로, C. J. Date는 한 SQL 문을 50가지 이상의 다른 SQL 문으로 표현이 가능함 을 보여 준다(http://www.dbpd.com/vault/9807xtra.htm 참조). SQL 재작성 을 통한 SQL 튜닝은 원래의 SQL 문을, 같은 결과를 내지만, 옵티마이저가 더 효과 적인 실행 계획을 생성할 수 있는 SQL 문으로 바꾸는 방법이다.

힌트 사용
앞에서 언급한 것처럼, 힌트 기능을 사용해서 옵티마이저가 선택하는 실행 계획을 바꾸는 방법이다.

새로운 인덱스 추가
SQL 문의 효율적인 처리를 위해서는 특정 테이블의 특정 칼럼 값을 이용해서 해당 데이타를 빨리 찾아야 하는데, 인덱스가 없기 때문에 옵티마이저가 어떤 실행 계획 을 선택하더라도 그 SQL 문은 느릴 수밖에 없는 경우가 있다. 이와 같은 상황에서 는 새로운 인덱스 생성을 통해서 옵티마이저가 해당 인덱스를 이용하는 새로운 실행 계획을 선택하도록 할 수 있다.

통계 데이타의 추가/갱신
앞에서 설명한 것처럼, 오라클 옵티마이저의 비용 산정 모듈에서는 테이블, 칼럼, 인덱스 등에 대한 통계정보를 이용해서 선택도, 카디널러티 등을 구하고 이를 통해 서 궁극적으로 실행 계획의 비용을 계산한다.
그런데, 만일 특정 테이블/칼럼에 대한 통계정보가 없거나, 오래 전에 만들어진 경 우는 비용 계산이 부정확하게 되고, 따라서 옵티마이저가 선택하는 실행 계획이 실 제로는 안 좋은 실행 계획일 수가 있다.
이를 해결하기 위해서는 특정 통계정보를 추가하거나 새로 갱신해 주어서 옵티마이 저가 정확한 비용 산정을 통해서 더 나은 실행 계획을 선택하도록 해주는 방법이다. 옵티마이저 기술의 발달은 궁극적으로 SQL 튜닝 관련 직종을 없앨 수도 있다. 그 러나, 다행인지 불행인지 몰라도, 향후 10년 사이에 이런 일이 벌어지지는 않을 것 같다.

향후 옵티마이저의 기술의 발전 방향

비록 옵티마이저 기술은 지난 30년간 꾸준히 발전해오면서 인간이 만든 가장 지능적 인 소프트웨어이지만, 앞으로도 끊임없이 기술 발전이 필요한 분야이다.
사용자가 사용하는 SQL 질의가 점점 더 복잡해지고, 데이타베이스에서 다루는 데이 타 양이 엄청난 속도로 늘어나고, 새로운 데이타의 종류를 데이타베이스에서 다루어 야 하기 때문에, 옵티마이저 기술의 중요성은 더욱 더 커질 것이다.
향후 옵티마이저 기술의 주요 발전 방향은 다음의 분야가 될 것이다. 여기서 나열한 분야는 주로 학계에서 연구가 활발히 진행중이거나 많은 진전이 있는 분야를 중심으 로 판단한 필자의 개인적인 의견이다.

질의 변환
오라클 옵티마이저와 관련해서 간략히 설명했지만, 현재의 옵티마이저가 처리하는 질의변환의 형태는 상대적으로 정형화되고 단순한 형태의 질의 변환만을 주로 수행 한다. 단일 SQL 블록(Select-From-Where)에 대한 질의변환 이외에, 복잡한 중첩 질의(nested query)를 단일 질의로 변환하는 방법, 중첩질의 내의 각 SQL 블록을 결합한 효과적인 실행 계획 생성이 가능해질 것이다.

비용 산정을 위한 정확한 통계정보 관리
실행 계획에 대한 정확한 비용 산정이 옵티마이저 기술의 핵심이다. 따라서, 지금 옵티마이저가 참고하는 통계정보보다 더 정교하고 복잡한 통계정보의 관리/유지 기 법들이 도입될 것이다.
예를 들어, 애트리뷰트 값들의 분포가 서로 독립적이라는 가정 대신에 상호 연관성 이 깊은 칼럼들에 대한 히스토그램 정보를 효과적으로 수집/활용하는 기술이 도입될 수도 있다.

런타임시 동적 질의 최적화
현재의 옵티마이저 기술은, 질의 수행 환경에 상관없이 옵티마이저가 선택한 실행 계획을 그대로 실행한다는 측면에서 정적(static) 질의 최적화 방법이다. 앞으로는 고정된 실행 계획을 그대로 수행하는 것이 아니라, SQL 실행 단계의 상황에 따라 실행 계획을 융통성 있게 바꾸는 기술이 개발될 것이다. 실제로 Oracle9i의 경우 초 보적인 형태의 동적 질의 최적화 기능을 제공하고 있다.

학습하는 옵티마이저
현재의 옵티마이저 기술은 통계정보의 변화나 사용자의 힌트가 없다면, 같은 SQL 질의에 대해서는 항상 똑같은 실행 계획을 선택할 것이다. 옵티마이저가 특정 질의 에 대해 생성한 실행 계획을 실제 수행했을 때, 예상과 달리 좋지 않은 성능을 보이 면, 옵티마이저가 다음 번에 최적화를 수행할 때는 이전의 실행 계획을 제외한 다른 대안을 찾게 되는 것이다.

출처 : 오라클사


'컴퓨터 > DB' 카테고리의 다른 글

25가지 효율적인 SQL 작성법  (0) 2009.01.15
Function 과 Procedures의 차이점  (0) 2009.01.15
데이터베이스의 DDL, DML, DCL  (0) 2009.01.15
페이징 방법 중 하나..  (0) 2009.01.15
오라클 함수 모음  (0) 2009.01.15
      
Posted by k_ben


웹페이지 게시판의 페이징기법..

여러가지 방법이 있지만..오라클 힌트를 이용한 간단한 방법도 있다..

예)
select a.id from (select /*+ INDEX_DESC(PK_BOARD) */ rownum as rnum, id from board where id>0 order by id desc) a where rnum >= 1 and rownum <=20

간단하게 설명하면 인덱스 역정렬을 하고 rownum을 사용해서 한페이징 20개 미만의 글들을 뿌려주게 됩니다..

무작정 쓰면 잘 안되니까 상황에 맞게 잘 쓰면 도움이 될겁니다..-_-;
      
Posted by k_ben

오라클 함수 모음

컴퓨터/DB : 2009. 1. 15. 21:35


1. 문자 함수
 1-1) CHR
 1-2) CONCAT 함수
 1-3) INITCAP 함수
 1-4) LOWER 함수
 1-5) LPAD 함수
 1-6) LTRIM 함수
 1-7) NLS_INITCAP 함수
 1-8) NLS_LOWER 함수
 1-9) NLSSORT 함수
 1-10) NLS_UPPER 함수
 1-11) REPLACE 함수
 1-12) RPAD 함수
 1-13) RTRIM 함수
 1-14) SOUNDEX 함수
 1-15) SUBSTR 함수
 1-16) TRANSLATE 함수
 1-17) TREAT 함수
 1-18) TRIM 함수
 1-19) UPPER 함수
 1-20) ASCII 함수
 1-21) INSTR 함수
 1-22) LENGTH 함수

2. 날짜 처리함수(datetime function)
 2-1) ADD_MONTHS 함수
 2-2) CURRENT_DATE 함수
 2-3) URRENT_TIMESTAMP 함수
 2-4) DBTIMEZONE 함수
 2-5) EXTRACT(datetime) 함수
 2-6) FROM_TZ 함수
 2-7) LAST_DAY 함수
 2-8) LOCALTIMESTAMP 함수 
 2-9) MONTHS_BETWEEN 함수
 2-10) NEW_TIME 함수
 2-11) NEXT_DAY 함수
 2-12) NUMTODSINTERVAL 함수
 2-13) NUMTOYMINTERVAL 함수
 2-14) ROUND(date) 함수
 2-15) SESSIONTIMEZONE 함수
 2-16) SYS_EXTRACT_UTC 함수
 2-17) SYSDATE 함수
 2-18) SYSTIMESTAMP 함수
 2-19) TO_DSINTERVAL 함수
 2-20) TO_TIMESTAMP 함수
 2-21) TO_TIMESTAMP_TZ 함수
 2-22) TO_YMINTERVAL 함수
 2-23) TRUNC(date) 함수
 2-24) TZ_OFFSET 함수

3.데이터 형 변환 함수(conversion function)
 3-1) ASCIISTR 함수
 3-2) BIN_TO_NUM 함수
 3-3) CAST 함수
 3-4) CHARTOROWID 함수
 3-5) COMPOSE 함수 
 3-6) CONVERT 함수
 3-7) HEXTORAW 함수
 3-8) NUMTODSINTERVAL 함수
 3-9) NUMTOYMINTERVAL 함수
 3-10) RAWTOHEX 함수
 3-11) RAWTONHEX 함수
 3-12) ROWIDTOCHAR 함수
 3-13) ROWIDTONCHAR 함수
 3-14) TO_CHAR(character) 함수
 3-15) TO_CLOB 함수
 3-16) TO_DSINTERVAL 함수
 3-17) TO_LOB 함수
 3-18) TO_MULTI_BYTE 함수
 3-19) TO_NCHAR(character) 함수
 3-20) TO_NCHAR(datetime) 함수
 3-21) TO_NCHAR(number) 함수
 3-22) TO_NCLOB 함수
 3-23) TO_NUMBER 함수
 3-24) TO_SINGLE_BYTE 함수
 3-25) TO_YMINTERVAL 함수
 3-26) TRANSLATE ... USING 함수
 3-27) UNISTR 함수

4. 기타함수(miscellaneous single row function)
 4-1) BFILENAME 함수
 4-2) COALESCE 함수
 4-3) DECODE 함수
 4-4) DEPTH 함수
 4-5) DUMP 함수
 4-6) EMPTY_BLOB 함수
 4-7) EMPTY_CLOB 함수
 4-8) EXISTSNODE 함수
 4-9) EXTRACT(XML) 함수
 4-10) EXTRACTVALUE 함수
 4-11) GREATEST 함수
 4-12) LEAST 함수
 4-13) NLS_CHARSET_DECL_LEN 함수
 4-14) NLS_CHARSET_ID 함수
 4-15) NLS_CHARSET_NAME 함수
 4-16) NULLIF 함수
 4-17) NVL2 함수
 4-18) PATH 함수
 4-19) SYS_CONNECT_BY_PATH 함수
 4-20) SYS_CONTEXT 함수
 4-21) SYS_DBURIGEN 함수
 4-22) SYS_EXTRACT_UTC 함수
 4-23) SYS_GUID 함수
 4-24) SYS_XMLAGG 함수
 4-25) SYS_XMLGEN 함수
 4-26) UID 함수
 4-27) USER 함수
 4-28) USERENV 함수
 4-29) VSIZE 함수
 4-30) XMLAGG 함수
 4-31) XMLCOLATTVAL 함수
 4-32) XMLCONCAT 함수
 4-33) XMLFOREST 함수
 4-34) XMLELEMENT 함수

5.그룹함수  Aggregate 함수
 5-1) AVG* 함수
 5-2) CORR* CORR* 함수
 5-3) COUNT* 함수
 5-4) COVAR_POP 함수
 5-5) COVAR_SAMP 함수
 5-6) CUME_DIST 함수
 5-7) DENSE_RANK 함수
 5-8) FIRST 함수
 5-9) GROUP_ID 함수
 5-10) Grouping 함수
 5-11) GROUPING_ID 함수
 5-12) LAST 함수
 5-13) MAX 함수
 5-14) MIN 함수
 5-15) PERCENTILE_CONT 함수
 5-16) PERCENTILE_DISC 함수
 5-17) PERCENT_RANK 함수
 5-18) RANK 함수
 5-19) REGR_(linear regression) function* 함수
 5-20) STDDEV 함수
 5-21) STDDEV_POP 함수
 5-22) STDDEV_SAMP 함수
 5-23) SUM 함수
 5-24) VAR_POP 함수
 5-25) VAR_SAMP 함수
 5-26) VARIANCE 함수
 5-27) Grouping sets 함수

6. Analytic 함수
 6-1) AVG* 함수
 6-2) CORR* CORR* 함수
 6-3) COUNT* 함수
 6-4) COVAR_SAMP 함수
 6-5) CUME_DIST 함수
 6-6) DENSE_RANK 함수
 6-7) FIRST 함수
 6-8) FIRST_VALUE 함수
 6-9) LAG 함수
 6-10) LAST_VALUE 함수
 6-11) LEAD 함수
 6-12) NTILE 함수
 6-13) RATIO_TO_REPORT 함수
 6-14) ROW_NUMBER 함수

7. 객체 참조 함수
 7-1) REF 타입

8. PseudoColumn을 의미하는 것
 8-1) ROWID 컬럼
 8-2) ROWNUM 컬럼
 
1-1) CHR 함수
--------------------------------------------------------------------------------
입력된 수의 바이너리 코드에 해당하는 문자를 반환한다.
【예제】
SQL> select chr(75)||chr(79)||chr(82)||chr(69)||chr(65)
   2    from dual;
CHR(7
-----
KOREA
SQL>
1-2) CONCAT 함수
--------------------------------------------------------------------------------
 입력되는 두 문자열을 연결하여 반환한다.
 입력되는 두 문자열의 타입이 다를 경우 다음과 같이 반환된다.
첫 번째 문자열 타입  두 번째 문자열 타입  반환되는 문자열 타입 CLOB  NCLOB  NCLOB NCLOB  NCHAR  NCLOB NCLOB  CHAR  NCLOB NCHAR  CLOB  NCLOB

【예제】
SQL> select concat('Republic of',' KOREA') from dual;
CONCAT('REPUBLICO
-----------------
Republic of KOREA
SQL>  

1-3) INITCAP 함수
--------------------------------------------------------------------------------
initcap('string‘) 함수는 입력 문자열 중에서
각 단어의 첫 글자를 대문자로 나머지는 소문자로 변환한 스트링을 반환한다
【예제】
SQL> select initcap('beautiful corea') from dual;
INITCAP('BEAUTI
---------------
Beautiful Corea
SQL>

1-4) LOWER 함수
--------------------------------------------------------------------------------
lower(string) 함수는 입력된 문자열을 소문자로 반환한다.
【예제】
SQL> select lower('Beautiful COREA') from dual;
LOWER('BEAUTIFU
---------------
beautiful corea
SQL>  

1-5) LPAD 함수
--------------------------------------------------------------------------------
lpad(char1,n,char2) 함수는
지정된 길이 n에서 문자 char1으로 채우고
남은 공간은 왼쪽부터 char2로 채워서 출력한다.
【형식】
lpad (char1, n [, char2] )
【예제】
SQL> select lpad ('Corea', 12, '*') from dual;
LPAD('COREA'
------------
*******Corea
SQL>

1-6) LTRIM 함수
--------------------------------------------------------------------------------
 LTRIM(문자열, 문자)함수는 문자열중
좌측으로부터 특정문자와 일치하는 문자를 제거하고 출력한다.
【형식】
ltrim(char [,set] )
【예제】
SQL> select LTRIM('xyxXxyLAST WORD','xy') from dual;
LTRIM('XYXXX
------------
XxyLAST WORD
SQL>
 
1-7) NLS_INITCAP 함수
--------------------------------------------------------------------------------
nls_initcap(‘string’) 함수는 입력 문자열 중에서
 각 단어의 첫 글자를 대문자로
           나머지는 소문자로 변환한 스트링을 반환한다.
 단어의 white space나 character가 알파뉴메릭이 아니더라도 상관없다.
nlsparam는 ‘nls_sort = sort'와 같은 형식을 가지며,
 여기서 sort는 linguistic sort sequence나 binary중의 하나이다.
【형식】
nls_initcap ( char [,'nlsparam'] )
【예제】
SQL> select nls_initcap('beautiful corea', 'nls_sort=binary')
  2  from dual;
NLS_INITCAP('BE
---------------
Beautiful Corea
SQL> select nls_initcap('beautiful corea','nls_sort=XDutch')
  2  from dual;
NLS_INITCAP('BE
---------------
Beautiful Corea
SQL>

1-8) NLS_LOWER 함수
--------------------------------------------------------------------------------
nls_lower(‘string’) 함수는 입력 문자열을 모두 소문자로 변환한 스트링을 반환한다. 
 단어의 white space나 character가 알파뉴메릭이 아니더라도 상관없다.
nlsparam는 ‘nls_sort = sort'와 같은 형식을 가지며,
 여기서 sort는 linguistic sort sequence나 binary중의 하나이다.
【형식】
nls_lower ( char [,'nlsparam'] )
【예제】
SQL> select nls_lower('CITTA''','nls_sort=XGerman') from dual;
NLS_LO
------
citta'
SQL>

1-9) NLSSORT 함수
--------------------------------------------------------------------------------
nlssort(‘string’) 함수는 입력 문자열을 소팅하여 스트링을 반환한다.
  단어의 white space나 character가 알파뉴메릭이 아니더라도 상관없다.
nlsparam는 ‘nls_sort = sort'와 같은 형식을 가지며,
 여기서 sort는 linguistic sort sequence나 binary중의 하나이다.
【형식】
nlssort ( char [,'nlsparam'] )
【예제】
SQL> select * from emp
  2    order by nlssort(name, 'nls_sort=XDanish');
        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1104 jijoe             220        100
      1103 kim               250        100
SQL>
 
1-10) NLS_UPPER 함수
--------------------------------------------------------------------------------
nls_upper(‘string’) 함수는 입력 문자열을 모두 소문자로 변환한 스트링을 반환한다.
  단어의 white space나 character가 알파뉴메릭이 아니더라도 상관없다.
nlsparam는 ‘nls_sort = sort'와 같은 형식을 가지며,
 여기서 sort는 linguistic sort sequence나 binary중의 하나이다.
【형식】
nls_upper ( char [,'nlsparam'] )
【예제】
SQL> select nls_upper('gro?e') from dual;
NLS_U
-----
gro?e
SQL> select nls_upper('gro?e','nls_sort=XGerman')
  2  from dual;
NLS_UP
------
grosse
SQL>
 
1-11) REPLACE 함수
--------------------------------------------------------------------------------
이 함수는 문자열에서 지정한 문자를 다른 문자로 치환한다.
  치환될 문자를 지정하지 않으면 해당 문자를 삭제한다.
【형식】
replace (char, search_string [, replacement_string] )
【예제】
SQL> select replace('aaabb','a','b') from dual;
REPLA
-----
bbbbb
SQL> select replace('aaabb','a') from dual;
RE
--
bb
SQL>

1-12) RPAD 함수
--------------------------------------------------------------------------------
rpad(char1,n,char2) 함수는 지정된 길이 n에서 문자 char1으로 채우고
남은 공간은 오른쪽부터 char2로 채워서 출력한다.
【형식】
rpad (char1, n [, char2] )
【예제】
SQL> select rpad('Corea',12,'*') from dual;
RPAD('COREA'
------------
Corea*******
SQL>
 
1-13) RTRIM 함수
--------------------------------------------------------------------------------
 RTRIM(문자열, 문자)함수는 문자열중
 우측으로부터 특정문자와 일치하는 문자를 제거하고 출력한다.
【형식】
rtrim(char [,set] )
【예제】
SQL> select RTRIM('BROWINGyxXxy','xy') "RTRIM example" from dual;
RTRIM exam
----------
BROWINGyxX
SQL>

1-14) SOUNDEX 함수
--------------------------------------------------------------------------------
soundex(‘char’) 함수는 char과 같은 발음의 이름을 표현한다.
【예제】
SQL> select name from emp;
NAME
----------
Cho
Joe
kim
jijoe
SQL> select name from emp
  2  where soundex(name) = soundex('jo');
NAME
----------
Joe
SQL>
 
1-15) SUBSTR 함수
--------------------------------------------------------------------------------
substr(str,m,n) 함수는 문자열 str 중에서 특정 위치 m으로부터 특정 길이n 만큼의 문자를 출력한다.
  m이 0이나 1이면 문자열의 첫글자를 의미하고,
  n이 생략되면 문자열의 끝까지를 의미한다.
  m이 음수이면 뒤쪽으로부터의 위치를 의미한다.
 SUBSTRB는 character 대신 byte를 사용하고,
 SUBSTDC는 unicode를 사용하며,
 SUBSTR2는 UCS2 codepoint를 사용하고,
 SUBSTR4는 UCS4 codepoint를 사용한다.
【형식】
{SUBSTR|SUBSTRB|SUBSTRC|SUNBSTD2|SUBSTR4}
  ( string, position [,substring_length] )
【예제】
SQL> select substr('abcdesfg', 3,2) from dual;
SU
--
cd
SQL> select substr('abcdefg',3) from dual;
SUBST
-----
cdefg
SQL> select substr('abcdefg', -3,2) from dual; ☜ 뒤에서 3번째부터 2글자를 의미한다.
SU
--
ef
SQL>
 
1-16) TRANSLATE 함수
--------------------------------------------------------------------------------
TRANSLATE (‘char’,‘from_string’,‘to_string’) 함수는
 char 내에 포함된 문자중 from_string에 지정한 모든 각각의 문자를
                         to_string문자로 각각 변경한다.
【형식】
TRANSLATE ('char','from_string','to_string')
【예제】
SQL> select translate('ababccc','c','d') from dual;
TRANSLA
-------
ababddd
SQL> select translate('2KRW229',
  2  '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',
  3  '9999999999XXXXXXXXXXXXXXXXXXXXXXXXXX') from dual;
TRANSLA
-------
9XXX999
SQL> select translate('2KRW229',
  2  '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ','0123456789')
  3  from dual;
TRAN
----
2229
SQL>
 
1-17) TREAT 함수
--------------------------------------------------------------------------------
TREAT 함수는 선언된 타입을 변경함으로써, 수퍼타입을 서브타입인 것처럼 처리할 수 있도록 한다.
【형식】
TREAT ( expr AS [ REF] [schema . ] type )
【예제】
SQL> select x.p.empno from person_table p;
select x.p.empno from person_table p
       *
ERROR at line 1:
ORA-00904: "X"."P"."EMPNO": invalid identifier
 
SQL> select treat(x.p as employee).empno empno,
  2               x.p.last_name last_name
  3   from person_table x;
 
     EMPNO LAST_NAME
---------- --------------------
           Seoul
      1234 Inchon
      5678 Arirang
 
SQL>
【예제】
SQL> select name, TREAT(VALUE(p) AS employee_t).salary salary
  2   FROM person p;
NAME                        SALARY
----------------------   ---------
Bob   
Joe                         100000
Tim                           1000
SQL>
 
1-18) TRIM 함수
--------------------------------------------------------------------------------
 이 함수는 LTRIM과 RTRIM 함수를 결합한 형태로
  문자값의 왼쪽 또는 오른쪽 부분에 정의한 문자를 절삭하여 출력한다.
LEADING은 LTRIM처럼 문자열 왼쪽의 문자를 지정하여 절삭하고,
 TRAILING은 RTRIM처럼 문자열 오른쪽 문자를 지정하여 절삭한다.
 BOTH는 왼쪽과 오른쪽 문자를 지정하여 절삭한다.
【형식】
TRIM ([{{{LEADING|TRAILING|BOTH} [trim_char] } | trim_char} FROM]
      trim_source )
【예제】
SQL> select trim (0 from 000123400) from dual;
TRIM
----
1234
SQL> select trim(trailing 'a' from 'abca') from dual;
TRI
---
abc
SQL> select trim(leading 'a' from 'abca') from dual;
TRI
---
bca
SQL> select trim(both 'a' from 'abca') from dual;
TR
--
bc
SQL>

1-19) UPPER 함수
--------------------------------------------------------------------------------
upper(string) 함수는 입력된 문자열을 대문자로 반환한다.
【예제】
SQL> select upper('Beautiful COREA') from dual;
UPPER('BEAUTIFU
---------------
BEAUTIFUL COREA
SQL>
 
1-20) ASCII 함수
--------------------------------------------------------------------------------
ASCII
ascii(‘char’) 함수는 주어진 char의 첫 글자의 아스키 값을 반환한다.
 char의 타입은 char, varchar2, nchar, nvarchar2중의 하나이어야 한다.
【예제】
SQL> select ascii('Korea') from dual;
ASCII('KOREA')
--------------
            75
SQL> select ascii('K') from dual;
ASCII('K')
----------
        75
SQL>
 
1-21) INSTR 함수
--------------------------------------------------------------------------------
이 함수는 문자 스트링 중에서
지정한 문자가 가장 처음 나타나는 위치를 숫자로 출력한다.
【형식】
{INSTR|INSTRB|INSTRC|INSTR2|INSTR4}
  ( string, substring [, position [,occurrence] ] )
【예제】
SQL> select instr('Corea','e') from dual;
INSTR('COREA','E')
------------------
                 4
SQL> select instr('corporate floor','or',3,2) from dual;
INSTR('CORPORATEFLOOR','OR',3,2)
--------------------------------
                              14
SQL> select instrb('corporate floor','or',5,2) from dual;
INSTRB('CORPORATEFLOOR','OR',5,2)
---------------------------------
                               14
SQL>

1-22) LENGTH 함수
--------------------------------------------------------------------------------
 LENGTH(char) 함수는 char의 길이를 반환한다.
LENGTHB는 character 대신 byte를 사용하고,
LENGTHC는 unicode를 사용하며,
LENGTH2는 UCS2 codepoint를 사용하고,
LENGTH4는 UCS4 codepoint를 사용한다.
【형식】
{LENGTH| LENGTHB| LENGTHC| LENGTH2| LENGTH4} (char)
【예제】
SQL> select length('Corea') from dual;
LENGTH('COREA')
---------------
              5
SQL> select lengthb('Corea') from dual;
LENGTHB('COREA')
----------------
               5
SQL>
 

2-1) ADD_MONTHS 함수
--------------------------------------------------------------------------------
ADD_MONTHS 
 ADD_MONTHS(d, n)는 날짜 d에 n 개월을 더한 일자를 반환한다.
【예제】
SQL> select current_date today, add_months(current_date,1) "next month"
  2  from dual;
TODAY     next mont
--------- ---------
29-JUL-04 29-AUG-04
SQL>
 
2-2) CURRENT_DATE 함수
--------------------------------------------------------------------------------

 이 함수는 현재 session의 날짜 정보를 반환한다.
【예제】
SQL> select current_date from dual;
CURRENT_D
---------
31-JUL-04
SQL> select sessiontimezone from dual;
SESSIONTIMEZONE
--------------------------------------------------------------------------
+09:00
SQL> alter session set NLS_DATE_FORMAT='DD-MON-YYYY HH24:MI:SS';
Session altered.
SQL> select current_date from dual;
CURRENT_DATE
--------------------
31-JUL-2004 09:31:57
SQL> alter session set time_zone='-5:0';
Session altered.
SQL> select sessiontimezone from dual;
SESSIONTIMEZONE
--------------------------------------------------------------------------
-05:00
SQL>
 
2-3) URRENT_TIMESTAMP 함수
--------------------------------------------------------------------------------
 이 함수는 현재 session의 날짜와 시간 정보를 반환한다.
 current_timestamp는 time zone까지 출력되지만,
 localtimestamp는 time zone은 출력되지 않는다.
【예제】
SQL> select current_timestamp, localtimestamp,
  2  current_date from dual;
CURRENT_TIMESTAMP
--------------------------------------------------------------------------
LOCALTIMESTAMP
--------------------------------------------------------------------------
CURRENT_D
---------
04-AUG-04 11.17.40.768776 AM +09:00
04-AUG-04 11.17.40.768776 AM
04-AUG-04
SQL>
 
2-4) DBTIMEZONE 함수
--------------------------------------------------------------------------------

데이터베이스 timezone을 반환한다.
【예제】
SQL> select dbtimezone from dual;
DBTIME
------
-07:00
SQL> select sessiontimezone from dual;
SESSIONTIMEZONE
--------------------------------------------------------------------------
+09:00
SQL>
 
2-5) EXTRACT(datetime) 함수
--------------------------------------------------------------------------------
특정 날짜/시간 값이나 날짜 값을 가진 표현식으로부터
  원하는 날짜 영역을 추출하여 출력한다. 
【형식】
EXTRACT ({year|month|day|hour|minute|second|
         timezone_hour|timezone_minute|
         timezone_region|timezone_abbr}
 FROM {datetime_value_expr|interval_value_rxpr})
【예제】
SQL> select extract(year from date '2004-8-2') from dual;
EXTRACT(YEARFROMDATE'2004-8-2')
-------------------------------
                           2004
SQL>
 
2-6) FROM_TZ 함수
--------------------------------------------------------------------------------
이 함수는 timestamp 값을 timestamp with time zone 값으로 변환한다.
【형식】
FROM_TZ ( timestamp_value, time_zone_value)
【예제】
SQL> select from_tz(timestamp '2004-8-11 08:00:00','3:00') from dual;
FROM_TZ(TIMESTAMP'2004-8-1108:00:00','3:00')
--------------------------------------------------------------------------
11-AUG-04 08.00.00.000000000 AM +03:00
SQL>
 
2-7) LAST_DAY 함수
--------------------------------------------------------------------------------
 이 함수는 지정한 달의 마지막 날을 출력한다.
【형식】
LAST_DAY ( date )
【예제】
SQL> select sysdate, last_day(sysdate) "last day",
  2  last_day(sysdate)- sysdate "Days Left"
  3  from dual;
SYSDATE   last day   Days Left
--------- --------- ----------
04-AUG-04 31-AUG-04         27
SQL>
 
2-8) LOCALTIMESTAMP 함수
--------------------------------------------------------------------------------
이 함수는 timestamp의 현재 날짜와 시각을 출력한다.
 current_timestamp는 time zone까지 출력되지만,
 localtimestamp는 time zone은 출력되지 않는다.
【형식】
localtimestamp [(timestamp_precision)]
【예제】
SQL> select current_timestamp, localtimestamp,
  2  current_date from dual;
CURRENT_TIMESTAMP
--------------------------------------------------------------------------
LOCALTIMESTAMP
--------------------------------------------------------------------------
CURRENT_D
---------
04-AUG-04 11.17.40.768776 AM +09:00
04-AUG-04 11.17.40.768776 AM
04-AUG-04
SQL>
 
【예제】오류가 발생하는 이유를 잘 이해하자.
SQL> CREATE TABLE local_test(col1 TIMESTAMP WITH LOCAL TIME ZONE);
Table created.
SQL> INSERT INTO local_test VALUES
  2  (TO_TIMESTAMP(LOCALTIMESTAMP, 'DD-MON-RR HH.MI.SSXFF'));
(TO_TIMESTAMP(LOCALTIMESTAMP, 'DD-MON-RR HH.MI.SSXFF'))
              *
ERROR at line 2:
ORA-01830: date format picture ends before converting entire input string
SQL> INSERT INTO local_test VALUES
  2  (TO_TIMESTAMP(LOCALTIMESTAMP, 'DD-MON-RR HH.MI.SSXFF PM'));
1 row created.
SQL> select * from local_test;
COL1
--------------------------------------------------------------------------
04-AUG-04 11.33.58.183398 AM
SQL>
 

2-9) MONTHS_BETWEEN 함수
--------------------------------------------------------------------------------
 MONTHS_BETWEEN(date1,date2) 함수는 date1과 date로 나타내는
 날짜와 날짜 사이의 개월 수를 출력한다.
【예제】
SQL> select months_between
  2  (to_date('02-02-2004','MM-DD-YYYY'),
  3   to_date('01-01-2003','MM-DD-YYYY') ) "Months"
  4  FROM dual;
    Months
----------
13.0322581
SQL>
 
2-10) NEW_TIME 함수
--------------------------------------------------------------------------------
NEW_TIME(date,zone1,zone2) 함수는 date, zone1 시간대를 zone2 시간대로 출력한다.
여기서 사용되는 zone은 다음 중의 하나이다.
 AST,ADT : Atlantic Standard or Daylight Time
 BST,BDT : Bering Standard or Daylight Time
 CST,CDT : Central Standard or Daylight Time
 EST,EDT : Eastern Standard or Daylight Time
 GMT : Greenwich Mean Time
 HST,HDT : Alaska-Hawaii Standard or Daylight Time
 MST,MDT : Mountain Standard or Daylight Time
 NST : Newfoundland Standard Time
 PST,PDT : Pacific Standard or Daylight Time
 YST,YDT : Yukon Standard or Daylight Time
【예제】
SQL> alter session set nls_date_format =
  2  'DD-MON-YYYY HH24:MI:SS';
Session altered.
SQL> select NEW_TIME(TO_DATE(
  2  '11-10-04 01:23:33', 'MM-DD-YY HH24:MI:SS'),
  3  'AST', 'PST') FROM DUAL;
NEW_TIME(TO_DATE('11
--------------------
09-NOV-2004 21:23:33
SQL>
 

2-11) NEXT_DAY 함수
--------------------------------------------------------------------------------
NEXT_DAY(date,char) 함수는 date로부터 char로 명시한 가장 최근의 날짜를 출력한다.
【예제】
SQL> select next_day('02-AUG-2004','MONDAY') from dual;
NEXT_DAY('02-AUG-200
--------------------
09-AUG-2004 00:00:00
SQL>
 

2-12) NUMTODSINTERVAL 함수
--------------------------------------------------------------------------------
 NUMTODSINTERVAL(n,'char_expr') 함수는 n을 interval day to second로 변환하여 출력한다.
 char_expr은 다음 중의 하나이다.
  ‘DAY’
  ‘HOUR’
  ‘MINUTE’
  ‘SECOND’
【예제】
SQL> select numtodsinterval(100,'MINUTE') from dual;
NUMTODSINTERVAL(100,'MINUTE')
--------------------------------------------------------------------------
+000000000 01:40:00.000000000
SQL>
【예제】
SQL> connect scott/tiger
Connected.
SQL> select ename, hiredate,
  2  numtodsinterval(100,'day')+hiredate from emp;
ENAME      HIREDATE  NUMTODSIN
---------- --------- ---------
SMITH      17-DEC-80 27-MAR-81
ALLEN      20-FEB-81 31-MAY-81
WARD       22-FEB-81 02-JUN-81
JONES      02-APR-81 11-JUL-81
MARTIN     28-SEP-81 06-JAN-82
BLAKE      01-MAY-81 09-AUG-81
CLARK      09-JUN-81 17-SEP-81
SCOTT      19-APR-87 28-JUL-87
KING       17-NOV-81 25-FEB-82
TURNER     08-SEP-81 17-DEC-81
ADAMS      23-MAY-87 31-AUG-87
JAMES      03-DEC-81 13-MAR-82
FORD       03-DEC-81 13-MAR-82
MILLER     23-JAN-82 03-MAY-82
14 rows selected.
SQL>
 
2-13) NUMTOYMINTERVAL 함수
--------------------------------------------------------------------------------
NUMTOYMINTERVAL(n,'char_expr') 함수는 n을 interval year to month로 변환하여 출력한다.
 char_expr은 다음 중의 하나이다.
  ‘YEAR’
  ‘MONTH’ 
【예제】
SQL> select numtoyminterval(30,'month') from dual;
NUMTOYMINTERVAL(30,'MONTH')
---------------------------------------------------------------------------
+000000002-06
SQL>
【예제】
SQL> connect scott/tiger
Connected.
SQL> select ename,hiredate,
  2  numtoyminterval(30,'month')+hiredate from emp;
ENAME      HIREDATE  NUMTOYMIN
---------- --------- ---------
SMITH      17-DEC-80 17-JUN-83
ALLEN      20-FEB-81 20-AUG-83
WARD       22-FEB-81 22-AUG-83
JONES      02-APR-81 02-OCT-83
MARTIN     28-SEP-81 28-MAR-84
BLAKE      01-MAY-81 01-NOV-83
CLARK      09-JUN-81 09-DEC-83
SCOTT      19-APR-87 19-OCT-89
KING       17-NOV-81 17-MAY-84
TURNER     08-SEP-81 08-MAR-84
ADAMS      23-MAY-87 23-NOV-89
JAMES      03-DEC-81 03-JUN-84
FORD       03-DEC-81 03-JUN-84
MILLER     23-JAN-82 23-JUL-84
14 rows selected.
SQL>
 

2-14) ROUND(date) 함수
--------------------------------------------------------------------------------
이 함수는 날짜를 주어진 형식으로 반올림하는 함수이다.
 날짜 형식이 없으면 가장 가까운 날을 출력한다.
【형식】
ROUND( date [,fmt] )
【예제】
SQL> select localtimestamp, round(sysdate,'year') from dual;
LOCALTIMESTAMP
--------------------------------------------------------------------------
ROUND(SYS
---------
04-AUG-04 01.26.24.197977 PM
01-JAN-05
SQL> select localtimestamp,round(sysdate,'day') from dual;
LOCALTIMESTAMP
--------------------------------------------------------------------------
ROUND(SYS
---------
04-AUG-04 01.29.57.839269 PM
08-AUG-04
SQL> select localtimestamp,round(sysdate) from dual;
LOCALTIMESTAMP
--------------------------------------------------------------------------
ROUND(SYS
---------
04-AUG-04 01.30.11.552050 PM
05-AUG-04
SQL>
 
2-15) SESSIONTIMEZONE 함수
--------------------------------------------------------------------------------
이 함수는 현재 세션의 시간대역을 출력한다.
【예제】
SQL> select sessiontimezone, current_timestamp from dual;
SESSIONTIMEZONE
--------------------------------------------------------------------------
CURRENT_TIMESTAMP
--------------------------------------------------------------------------
+09:00
04-AUG-04 01.37.13.355873 PM +09:00
SQL> select sessiontimezone, tz_offset(sessiontimezone) from dual;
SESSIONTIMEZONE
--------------------------------------------------------------------------
TZ_OFFS
-------
+09:00
+09:00
SQL>
 
2-16) SYS_EXTRACT_UTC 함수
--------------------------------------------------------------------------------
sys_extract_utc(datetime_with_timezone) 함수는
UTC(coordinated universal time: Greenwich mean time) 시각을 반환한다. 
【예제】
SQL> select systimestamp, sys_extract_utc(systimestamp) from dual;
SYSTIMESTAMP
--------------------------------------------------------------------------
SYS_EXTRACT_UTC(SYSTIMESTAMP)
--------------------------------------------------------------------------
06-AUG-04 02.41.39.258976 PM +09:00
06-AUG-04 05.41.39.258976 AM

SQL>
 
2-17) SYSDATE 함수
--------------------------------------------------------------------------------
이 함수는 오늘 현재 날짜와 시각을 출력한다.
【예제】
SQL> select sysdate, current_timestamp from dual;
SYSDATE
---------
CURRENT_TIMESTAMP
--------------------------------------------------------------------------
04-AUG-04
04-AUG-04 01.51.39.767156 PM +09:00
SQL> select to_char
  2  (sysdate, 'MM-DD-YYYY HH24:MI:SS') from dual;
TO_CHAR(SYSDATE,'MM
-------------------
08-04-2004 13:53:18
SQL>
 
2-18) SYSTIMESTAMP 함수
--------------------------------------------------------------------------------
이 함수는 시스템의 날짜를 출력한다.
【예제】
SQL> select sysdate,systimestamp,localtimestamp from dual;
SYSDATE
---------
SYSTIMESTAMP
--------------------------------------------------------------------------
LOCALTIMESTAMP
--------------------------------------------------------------------------
04-AUG-04
04-AUG-04 01.58.06.346528 PM +09:00
04-AUG-04 01.58.06.346552 PM
SQL>
 
2-19) TO_DSINTERVAL 함수
--------------------------------------------------------------------------------
이 함수는 문자열을 interval day to second 형식으로 변환하는 함수이다.
【형식】
to_dsinterval ( char [ ‘nlsparam’] )
【예제】
SQL> select sysdate,
  2  sysdate+to_dsinterval('003 17:00:00') as "3days 17hours later"
  3  from dual;
SYSDATE   3days 17h
--------- ---------
04-AUG-04 08-AUG-04
SQL>
 
2-20) TO_TIMESTAMP 함수
--------------------------------------------------------------------------------
이 함수는 문자열을 timestamp 형식으로 변환하여 출력한다 
【형식】
to_timestamp ( char [,fmt ['nlsparam'] ] )
【예제】
SQL> select to_timestamp('2004-8-20 1:30:00', 'YYYY-MM-DD HH:MI:SS')
  2  from dual;
TO_TIMESTAMP('2004-8-201:30:00','YYYY-MM-DDHH:MI:SS')
--------------------------------------------------------------------------
20-AUG-04 01.30.00.000000000 AM
SQL>
 

2-21) TO_TIMESTAMP_TZ 함수
--------------------------------------------------------------------------------
이 함수는 문자열을 timestamp with time zone 형식으로 변환하여 출력한다. 
【형식】
to_timestamp_tz ( char [,fmt ['nlsparam'] ] )
【예제】
SQL> select to_timestamp_tz('2004-8-20 1:30:00 -3:00',
  2  'YYYY-MM-DD HH:MI:SS TZH:TZM') from dual;
TO_TIMESTAMP_TZ('2004-8-201:30:00-3:00','YYYY-MM-DDHH:MI:SSTZH:TZM')
--------------------------------------------------------------------------
20-AUG-04 01.30.00.000000000 AM -03:00
SQL>
 
2-22) TO_YMINTERVAL 함수
--------------------------------------------------------------------------------
TO_YMINTERVAL ( char ) 함수는 문자열을 interval year to month 형식으로 변환하는 함수이다.
【예제】
SQL> select sysdate,
  2  sysdate+to_yminterval('01-03') "15Months later"
  3  from dual;
SYSDATE   15Months
--------- ---------
04-AUG-04 04-NOV-05
SQL>
 
2-23) TRUNC(date) 함수
--------------------------------------------------------------------------------
이 함수는 날짜를 절삭하여 출력한다.
【형식】
TRUNC ( date [.fmt] )
【예제】
SQL> select trunc(to_date('27-AUG-04','DD-MON-YY'), 'YEAR')
  2  from dual;
TRUNC(TO_
---------
01-JAN-04
SQL>
 
2-24) TZ_OFFSET 함수
--------------------------------------------------------------------------------
이 함수는 time zone의 offset 값을 출력한다.
【형식】
TZ_OFFSET ( {‘time_zone_name’ | SESSIONTIMEZONE | DBTIMEZONE |
             ‘{+|-} hh:mi’ } )
【예제】
SQL> select sessiontimezone, tz_offset('ROK') from dual;
SESSIONTIMEZONE
---------------------------------------------------------------------------
TZ_OFFS
-------
+09:00
+09:00
SQL>
 

3-1) ASCIISTR 함수
--------------------------------------------------------------------------------
 asciistr('string')의 string의 아스키 문자로 반환한다.
Ä
【예제】
SQL> select ascii('ABÄCDE') from dual;
☜ ABÄCDE의 두번째 Ä는 A에 움라우트(Umlaut)가 붙은 글씨이다.
ASCIIS
------
ABDCDE
           
SQL>
 

3-2) BIN_TO_NUM 함수
--------------------------------------------------------------------------------
 이 함수는 2진수 벡터를 10진수로 변환한다.
SQL> select bin_to_num(1,0,1,0) from dual;
BIN_TO_NUM(1,0,1,0)
-------------------
                 10
SQL>
 
3-3) CAST 함수
--------------------------------------------------------------------------------
 데이터형식이나 collection 형식을 다른 데이터형식이나 다른 collection 형식으로 변환한다.
【예제】데이터형식인 경우
SQL> select current_date from dual;
CURRENT_D
---------
30-JUL-04
SQL> select cast(current_date as timestamp) from dual;
CAST(CURRENT_DATEASTIMESTAMP)
---------------------------------------------------------------------------
30-JUL-04 12.29.15.000000 PM
SQL>
 
3-4) CHARTOROWID 함수
--------------------------------------------------------------------------------
 이 함수는 char, varchar2, nchar, ncharvar2형 데이터 타입을 rowid 형 데이터 타입으로 변경한다.
【예제】
SQL> select name from emp
  2  where rowid = chartorowid('AAAHZ+AABAAAMWiAAF');
NAME
----------
jijoe
SQL> select rowid,name from emp;
ROWID              NAME
------------------ ----------
AAAHZ+AABAAAMWiAAA Cho
AAAHZ+AABAAAMWiAAB Joe
AAAHZ+AABAAAMWiAAC kim
AAAHZ+AABAAAMWiAAF jijoe
SQL>

여기서 rowid의 의미는 다음과 같다.
AAAHZ+  AAB  AAAMWi  AAA 객체번호  테이블스페이스번호  블록번호  행번호
 

3-5) COMPOSE 함수
--------------------------------------------------------------------------------
 입력된 스트링을 unicode로 나타낸다.
【예제】
SQL> select compose('aa' || unistr('308') ) from dual;
CO
--
aa
SQL>
 
3-6) CONVERT 함수
--------------------------------------------------------------------------------
입력된 문자열을 지정한 코드로 변환한다.
공용 문자셋은 살펴보자.
US7ASCII  US 7-bit ASCII 문자 WE8DEC  서유럽 8비트 문자 WE8HP  HP 서유럽 레이져젯 8비트 문자 F7DEC  DEC 프랑스 7비트 문자 WE8EBCDIC500  IBM 서유럽 EBCDIC 코드 페이지 500 WE8PC850  IBM PC 코드 페이지 850 WE8ISO8859P1  ISO 8859 서유럽 8비트 문자
【예제】
SQL> select convert('arirang','we8pc850') from dual;
CONVERT
-------
arirang
SQL>
 
3-7) HEXTORAW 함수
--------------------------------------------------------------------------------
HEXTORAW(char) 함수는 char, varchar2, nchar, nvarchar2 따위의 문자로 주어지는
 hexadecimal digit을 raw 값으로 변환한다.
【예제】
SQL> create table test(raw_col RAW(10));
Table created.
SQL> insert into test VALUES (HEXTORAW('7D'));
1 row created.
SQL> select * from test;
RAW_COL
--------------------
7D
SQL>
 

3-8) NUMTODSINTERVAL 함수
--------------------------------------------------------------------------------
 NUMTODSINTERVAL(n,'char_expr') 함수는 n을 interval day to second로 변환하여 출력한다.
 char_expr은 다음 중의 하나이다.
  ‘DAY’
  ‘HOUR’
  ‘MINUTE’
  ‘SECOND’
【예제】
SQL> select numtodsinterval(100,'MINUTE') from dual;
NUMTODSINTERVAL(100,'MINUTE')
--------------------------------------------------------------------------
+000000000 01:40:00.000000000
SQL>
【예제】
SQL> connect scott/tiger
Connected.
SQL> select ename, hiredate,
  2  numtodsinterval(100,'day')+hiredate from emp;
ENAME      HIREDATE  NUMTODSIN
---------- --------- ---------
SMITH      17-DEC-80 27-MAR-81
ALLEN      20-FEB-81 31-MAY-81
WARD       22-FEB-81 02-JUN-81
JONES      02-APR-81 11-JUL-81
MARTIN     28-SEP-81 06-JAN-82
BLAKE      01-MAY-81 09-AUG-81
CLARK      09-JUN-81 17-SEP-81
SCOTT      19-APR-87 28-JUL-87
KING       17-NOV-81 25-FEB-82
TURNER     08-SEP-81 17-DEC-81
ADAMS      23-MAY-87 31-AUG-87
JAMES      03-DEC-81 13-MAR-82
FORD       03-DEC-81 13-MAR-82
MILLER     23-JAN-82 03-MAY-82
14 rows selected.
SQL>
 

3-9) NUMTOYMINTERVAL 함수
--------------------------------------------------------------------------------
NUMTOYMINTERVAL(n,'char_expr') 함수는 n을 interval year to month로 변환하여 출력한다.
 char_expr은 다음 중의 하나이다.
  ‘YEAR’
  ‘MONTH’ 
【예제】
SQL> select numtoyminterval(30,'month') from dual;
NUMTOYMINTERVAL(30,'MONTH')
---------------------------------------------------------------------------
+000000002-06
SQL>
【예제】
SQL> connect scott/tiger
Connected.
SQL> select ename,hiredate,
  2  numtoyminterval(30,'month')+hiredate from emp;
ENAME      HIREDATE  NUMTOYMIN
---------- --------- ---------
SMITH      17-DEC-80 17-JUN-83
ALLEN      20-FEB-81 20-AUG-83
WARD       22-FEB-81 22-AUG-83
JONES      02-APR-81 02-OCT-83
MARTIN     28-SEP-81 28-MAR-84
BLAKE      01-MAY-81 01-NOV-83
CLARK      09-JUN-81 09-DEC-83
SCOTT      19-APR-87 19-OCT-89
KING       17-NOV-81 17-MAY-84
TURNER     08-SEP-81 08-MAR-84
ADAMS      23-MAY-87 23-NOV-89
JAMES      03-DEC-81 03-JUN-84
FORD       03-DEC-81 03-JUN-84
MILLER     23-JAN-82 23-JUL-84
14 rows selected.
SQL>
 
 

3-10) RAWTOHEX 함수
--------------------------------------------------------------------------------
RAWTOHEX(raw) 함수는 raw 값을 hexadecimal 값으로 변환한다.
【예제】
SQL> create table test(raw_col RAW(10));
Table created.
SQL> insert into test VALUES (HEXTORAW('7D'));
1 row created.
SQL> select * from test;
RAW_COL
--------------------
7D
SQL> select rawtohex(raw_col) from test;
RAWTOHEX(RAW_COL)
--------------------
7D
SQL>
 
3-11) RAWTONHEX 함수
--------------------------------------------------------------------------------
RAWTONHEX(raw) 함수는 raw 값을 nvarchar2형 hexadecimal 값으로 변환한다.
【예제】
SQL> create table test(raw_col RAW(10));
Table created.
SQL> insert into test VALUES (HEXTORAW('7D'));
1 row created.
SQL> select * from test;
RAW_COL
--------------------
7D
SQL> select rawtonhex(raw_col) from test;
RAWTONHEX(RAW_COL)
--------------------
7D
SQL>
 
3-12) ROWIDTOCHAR 함수
--------------------------------------------------------------------------------
RAWIDTOCHAR(rowid) 함수는 rowid 값을 varchar2 형식의 데이터로 변환한다.
【예제】
SQL> select rowid from test;
ROWID
------------------
AAAHbHAABAAAMXCAAA
SQL> select rowid from test
  2  where rowidtochar(rowid) like '%AABAA%';
ROWID
------------------
AAAHbHAABAAAMXCAAA
SQL>
여기서 rowid의 의미는 다음과 같다.
AAAHbH  AAB  AAAMXC  AAA 객체번호  테이블스페이스번호  블록번호  행번호
 

3-13) ROWIDTONCHAR 함수
--------------------------------------------------------------------------------
RAWIDTONCHAR(rowid) 함수는 rowid 값을 nvarchar2 형식의 데이터로 변환한다.
【예제】
SQL> select rowid from test;
ROWID
------------------
AAAHbHAABAAAMXCAAA
SQL> select rowid from test
  2  where rowidtochar(rowid) like '%AABAA%';
ROWID
------------------
AAAHbHAABAAAMXCAAA
SQL> select lengthb(rowidtonchar(rowid)), rowidtonchar(rowid)
  2  from test;
LENGTHB(ROWIDTONCHAR(ROWID)) ROWIDTONCHAR(ROWID
---------------------------- ------------------
                          36 AAAHbHAABAAAMXCAAA
SQL>

여기서 rowid의 의미는 다음과 같다.
AAAHbH  AAB  AAAMXC  AAA 객체번호  테이블스페이스번호  블록번호  행번호
 

3-14) TO_CHAR(character) 함수
--------------------------------------------------------------------------------
 이 함수는 nchar, nvarchar2, clob, nclob 형식의 데이터를
데이터베이스 character set으로 변환한다. 즉, 문자로 변환한다.
【형식】
 TO_CHAR( nchar| clob | nclob)
【예제】
SQL> select to_char('01110') from dual;
TO_CH
-----
01110
SQL>
 

3-15) TO_CLOB 함수
--------------------------------------------------------------------------------
이 함수는 LOB 컬럼에 있는 NCLOB나 또는 다른 문자 스트링을 CLOB로 변환한다.
【형식】
 TO_CLOBR({ lob_column | char})
【예제】
SQL> select to_clob('corea') from dual;
TO_CLOB('COREA')
--------------------------------------------------------------------------
corea
SQL>
 

3-16) TO_DSINTERVAL 함수
--------------------------------------------------------------------------------
이 함수는 문자열을 interval day to second 형식으로 변환하는 함수이다.
【형식】
to_dsinterval ( char [ ‘nlsparam’] )
【예제】
SQL> select sysdate,
  2  sysdate+to_dsinterval('003 17:00:00') as "3days 17hours later"
  3  from dual;
SYSDATE   3days 17h
--------- ---------
04-AUG-04 08-AUG-04
SQL>
 
3-17) TO_LOB 함수
--------------------------------------------------------------------------------
 TO_LOB(long_column) 함수는 LONG, LONG RAW 컬럼의 데이터를 LOB 값으로 변환한다.
【예제】
SQL> create table test2(zz clob);
Table created.
SQL> insert into test2
  2  (select to_lob(p.raw_col) from test p);
SQL>
 
3-18) TO_MULTI_BYTE 함수
--------------------------------------------------------------------------------
TO_MULTI_BYTE(char) 함수는 싱글 바이트 문자를 포함한 모든 문자열을 다중바이트 문자열로 변환한다.
【예제】
SQL> select dump(to_multi_byte('Corea')) from dual;
DUMP(TO_MULTI_BYTE('COREA'))
-----------------------------------------------------
Typ=1 Len=10: 163,195,163,239,163,242,163,229,163,225
SQL>
 

3-19) TO_NCHAR(character) 함수
--------------------------------------------------------------------------------
 이 함수는 문자스트링, clob, nclob 형식의 데이터를 national character set,
 즉 nchar으로 변환한다. 이는 translate ... using 문의 경우와 같다.
【형식】
TO_NCHAR({char|clob|nclob} [,fmt [,'nlsparam']])
【예제】
SQL> select to_nchar('Corea') from dual;
TO_NC
-----
Corea
SQL>
 
3-20) TO_NCHAR(datetime) 함수
--------------------------------------------------------------------------------
 이 함수는 date, timestamp, timestamp with time zone, timestamp with local time zone,
 interval month to year, interval day to second 형식의 데이터를
 nchar 형식의 데이터로 변환한다.
【형식】
TO_NCHAR({datetime|interval} [,fmt [,'nlsparam']])
【예제】
SQL> select to_nchar(sysdate) from dual;
TO_NCHAR(SYSDATE)
------------------------------
05-AUG-04
SQL>
 

3-21) TO_NCHAR(number) 함수
--------------------------------------------------------------------------------
 이 함수는 숫자를 nvarchar2 형식의 데이터로 변환한다.
【형식】
TO_NCHAR(n [,fmt [,'nlsparam']])
【예제】
SQL> select to_nchar(1234) from dual;
TO_N
----
1234
SQL> select to_nchar(rownum) from test;
TO_NCHAR(ROWNUM)
----------------------------------------
1
SQL>
 

3-22) TO_NCLOB 함수
--------------------------------------------------------------------------------
이 함수는 clob, 문자열 형식의 데이터를 nclob 형식의 데이터로 변환한다.
【형식】
TO_NCLOB({char|lob_column})
【예제】
SQL> select to_nclob('Corea') from dual;
TO_NCLOB('COREA')
--------------------------------------------------------------------------
Corea
SQL>
 

3-23) TO_NUMBER 함수
--------------------------------------------------------------------------------
이 함수는 숫자를 포함하는 char, varchar2, nchar, nvarchar2 형식의
 문자 데이터를 number 형식의 숫자 데이터로 변환한다.
【형식】
TO_NUMBER(char [,fmt [,'nlsparam']])
【예제】
SQL> select to_number('1234') from dual;
TO_NUMBER('1234')
-----------------
             1234
SQL>
 
3-24) TO_SINGLE_BYTE 함수
--------------------------------------------------------------------------------
TO_SINGLE_BYTE(char) 함수는 다중 바이트 문자열을 single byte 문자로 변환한다.
【예제】
SQL> select dump(to_multi_byte('Corea')) from dual;
DUMP(TO_MULTI_BYTE('COREA'))
-----------------------------------------------------
Typ=1 Len=10: 163,195,163,239,163,242,163,229,163,225
SQL> select dump(to_single_byte('Corea')) from dual;
DUMP(TO_SINGLE_BYTE('COREA'))
------------------------------
Typ=1 Len=5: 67,111,114,101,97
SQL> select to_single_byte(chr(65)) from dual;
T
-
A
SQL>
 

3-25) TO_YMINTERVAL 함수
--------------------------------------------------------------------------------
TO_YMINTERVAL ( char ) 함수는 문자열을 interval year to month 형식으로 변환하는 함수이다.
【예제】
SQL> select sysdate,
  2  sysdate+to_yminterval('01-03') "15Months later"
  3  from dual;
SYSDATE   15Months
--------- ---------
04-AUG-04 04-NOV-05
SQL>
 
3-26) TRANSLATE ... USING 함수
--------------------------------------------------------------------------------
이 함수는 텍스트 형식의 데이터를 지정한 문자 형식의 데이터로 변환한다.
【형식】
TRANSLATE ( text USING {CHAR_CS|NCHAR_CS} )
【예제】
SQL> select translate('Corea' USING char_cs) from dual;
TRANS
-----
Corea
SQL> select to_nchar('Corea') from dual;
TO_NC
-----
Corea
SQL>
 
3-27) UNISTR 함수
--------------------------------------------------------------------------------
UNISTR('string') 함수는 스트링 형식의 데이터를 nchar 형식의 데이터로 변환한다.
【예제】
SQL> select unistr('abc0e50f10f6') from dual;
UNISTR
------
abc??o
SQL> select unistr('Corea') from dual;
UNIST
-----
Corea
SQL>
 

4-1) BFILENAME 함수
--------------------------------------------------------------------------------
 서버 파일 시스템 상에 실제로 위치한 LOB 바이너리 파일의 위치한 BFILE locator를 반환한다.
【형식】
bfilename ('디렉토리‘,’파일이름‘)
【예제】BFILE을 insert하는 예
SQL> connect system/manager
SQL> host mkdir /export/home/oracle/bfile
SQL> create directory bfile_dir as '/export/home/oracle/bfile';
Directory created.
SQL> grant read on directory bfile_dir to jijoe;
Grant succeeded.
SQL> connect jijoe/joe_password
SQL> create table bfile_doc (id number, doc bfile);
SQL> insert into bfile_doc
   1    values(1111,bfilename('bfile_dir','unix.hwp'));
1 row created.
SQL>
 
4-2) COALESCE 함수
--------------------------------------------------------------------------------
이 함수는 나열된 값 중에서 NULL이 아닌 첫 번째 값을 반환한다.  
【예제】
SQL> select coalesce('','','arirang','kunsan') from dual;
COALESC
-------
arirang
SQL>
 

4-3) DECODE 함수
--------------------------------------------------------------------------------
DECODE는 일반적인 프로그래밍 언어의 IF문을 SQL 문자 또는 PL/SQL 안으로 끌어들여 사용하기 위하여 만들어진 오라클 함수이다.
따라서 일반 프로그래밍 언어의 IF문이 수행 할 수 있는 기능을 포함하고 있다.
  select시의 decode 사용은 from 절만 빼고 어디에서나 사용할 수 있다.
  일반 프로그래밍과 decode 함수를 서로 비교하여 보자.
IF문 Decode 함수 IF A=B THEN RETURN 'T';END IF; DECODE(A,B,'T') IF A=B THENRETURN 'T';ELSIF A=C THENRETURN 'F';ELSERETURN 'X';END IF; DECODE(A,B,'T',C,'F','X')
【형식】
DECODE(검색컬럼,조건1,결과값1,
                  조건2,결과값2,...,기본값);
【예제】
SQL> connect jijoe/jijoe_password
SQL> create table aa(
  2  pid        number(12) primary key,
  3  addr varchar2(20),
  4  name varchar2(10));
SQL> insert into aa values(1234,'kunsan','jijoe')
SQL> insert into aa values(3456,'seoul','sunny')
SQL> select * from aa;
       PID ADDR                 NAME
---------- -------------------- ----------
      1234 kunsan               jijoe
      3456 seoul                sunny
SQL> select decode(pid,1234,name) name from aa;
NAME
----------
jijoe

SQL>
【예제】
SQL> desc ddd
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 NO                                                 NUMBER(4)
 NAME                                               VARCHAR2(10)
 HIRDATE                                            DATE
 DEPTNO                                             NUMBER(5)
SQL> select * from ddd;
        NO NAME       HIRDATE       DEPTNO
---------- ---------- --------- ----------
         1 student1   01-JAN-04         10
         2 student2   01-FEB-04         10
         3 student3   01-MAR-04         20
         4 student4   01-MAY-04         30
SQL> select count(decode(to_char(hirdate,'MM'),'01',1)) "JAN",
  2         count(decode(to_char(hirdate,'MM'),'02',1)) "FEB",
  3         count(decode(to_char(hirdate,'MM'),'03',1)) "MAR",
  4         count(*) "Total"
  5  from ddd
  6  where to_char(hirdate,'MM') >= '01' AND
  7        to_char(hirdate,'MM') <= '06';
       JAN        FEB        MAR      Total
---------- ---------- ---------- ----------
         1          1          1          4
SQL>
 

4-4) DEPTH 함수
--------------------------------------------------------------------------------
DEPTH( correlation_integer) 함수는 UNDER_PATH나 EQUALS_PATH 조건과 함께 사용되는 보조함수이다.
 이 함수는 UNDER_PATH 조건에 상관관계의 수치를 반환한다.
【예제】
SQL> select * from resource_view;
SQL> select path(1), depth(2)
  2  from resource_view
  3  where under_path(res, '/sys/schemas/PUBLIC/www.w3.org/2001', 1)=1
  4    and under_path(res, '/sys/schemas/PUBLIC/www.w3.org/2001', 2)=1;
PATH(1)                                      DEPTH(2)
------------------------------------------ ----------
/xml.xsd                                            1
        
SQL>
 
4-5) DUMP 함수
--------------------------------------------------------------------------------
지정한 데이터의 위치와 길이 따위를 지정한 형식으로 반환한다.
【형식】
DUMP(expr [,반환형식[,시작위치[,길이]]] )
【예제】
SQL> select dump('Corea', 1016) from dual;
DUMP('COREA',1016)
-----------------------------------------------------
Typ=96 Len=5 CharacterSet=KO16KSC5601: 43,6f,72,65,61
SQL> select dump('Corea', 8,3,2) "Octal" from dual;
Octal
---------------------
Typ=96 Len=5: 162,145
SQL> select dump('Corea',16,3,2) "ASCII" from dual;
ASCII
-------------------
Typ=96 Len=5: 72,65
SQL>
 
4-6) EMPTY_BLOB 함수
--------------------------------------------------------------------------------
EMPTY_BLOB () 함수는 LOB 변수를 초기화하기 위하여 쓰이거나,
 또는 INSERT 문이나 UPDATE 문에서 empty LOB 위치를 반환한다.
【예시】
UPDATE print_media SET ad_photo = EMPTY_BLOB();
 
4-7) EMPTY_CLOB 함수
--------------------------------------------------------------------------------
EMPTY_CLOB () 함수는 LOB 변수를 초기화하기 위하여 쓰이거나,
 또는 INSERT 문이나 UPDATE 문에서 empty LOB 위치를 반환한다.
【예시】
UPDATE print_media SET ad_photo = EMPTY_CLOB();
 
4-8) EXISTSNODE 함수
--------------------------------------------------------------------------------
이 함수는 node의 존재여부를 확인하여 그 결과를 반환한다.
 0은 노드가 남아 있지 않은 경우이고,
 1은 아직 노드가 존재하는 경우이다.
【형식】
EXISTSNODE(XMLType_instance, XPath_string [,namespace_string] )
【예제】
SQL> select * from resource_view;
SQL> select res,any_path
  2  from resource_view
  3  where existsnode(res, 'xdbconfig.xml') =0;
26 rows selected.
SQL>
 

4-9) EXTRACT(XML) 함수
--------------------------------------------------------------------------------
이 함수는 existsnode와 유사한 함수이다.
【형식】
EXTRACT(XMLType_instance, XPath_string [,namespace_string] )
【예제】
SQL> select * from resource_view;
SQL> select extract(res,'xdbconfig.xml')
  2  from resource_view;
 
26 rows selected.
SQL>
 

4-10) EXTRACTVALUE 함수
--------------------------------------------------------------------------------
이 함수는 existsnode와 유사한 함수로써 node의 스칼라 값을 반환한다.
【형식】
EXTRACTVALUE(XMLType_instance, XPath_string [,namespace_string] )
【예제】
SQL> select * from resource_view;
SQL> select extractvalue(res,'xdbconfig.xml')
  2  from resource_view;
 
26 rows selected.
SQL>
 
4-11) GREATEST 함수
--------------------------------------------------------------------------------
GREATEST (expr,...) 함수는 expr 중에서 가장 큰 값을 반환한다.
【예제】
SQL> select greatest(20,10,30) from dual;
GREATEST(20,10,30)
------------------
                30
SQL>
 
4-12) LEAST 함수
--------------------------------------------------------------------------------
LEAST (expr,...) 함수는 expr 중에서 가장 작은 값을 반환한다.
【예제】
SQL> select least(20,10,30) from dual;
GREATEST(20,10,30)
------------------
                10
SQL> select least('bb','aa','cc') from dual;
GR
--
aa
SQL>
 
4-13) NLS_CHARSET_DECL_LEN 함수
--------------------------------------------------------------------------------
NLS_CHARSET_DECL_LEN (byte_count , char_set_id) 함수는 nchar로 선언된 폭을 반환한다.
【예제】
SQL> select nls_charset_decl_len
  2  (200, nls_charset_id('ja16eucfixed')) from dual
NLS_CHARSET_DECL_LEN(200,NLS_CHARSET_ID('JA16EUCFIXED'))
--------------------------------------------------------
                                                     100
SQL>
 

4-14) NLS_CHARSET_ID 함수
--------------------------------------------------------------------------------
nls_charset_id('text') 함수는 문자셋 이름에 대응하는 ID 번호를 반환한다.
 여기서 text는 서버에서 지원되는 CHAR_CS나 NCHAR_CS이다.
【예제】
SQL> select nls_charset_id('ja16euc') from dual;
NLS_CHARSET_ID('JA16EUC')
-------------------------
                      830
SQL>
 
4-15) NLS_CHARSET_NAME 함수
--------------------------------------------------------------------------------
nls_charset_name('number') 함수는 문자섹 ID 번호에 대응하는 문자의 이름을 반환한다.
【예제】
SQL> select nls_charset_name(830) from dual;
NLS_CHA
-------
JA16EUC
SQL> select nls_charset_name(1) from dual;
NLS_CHAR
--------
US7ASCII
SQL>
 

4-16) NULLIF 함수
--------------------------------------------------------------------------------
NULLIF(expr1, expr2) 함수는
 expr1과 expr2를 비교하여
       같으면 null을 반환하고,
       같지 않으면 expr1을 반환한다.
이는 CASE 문으로 쓰면 다음과 같다.
  CASE WHEN expr1 = expr2 THEN NULL ELSE expr1 END
【예제】
SQL> select nullif('aa','AA') from dual;
NU
--
aa
SQL> select nullif('aa','aa') from dual;
NU
--

SQL>
 

4-17) NVL2 함수
--------------------------------------------------------------------------------
NVL2(expr1, expr2, expr3) 함수는
   expr1이 null이 아니면 expr2를 반환하고,
   expr1이 null이면 expr3을 반환한다.
【예제】
SQL> select nvl2('','Corea','Korea') from dual;
NVL2(
-----
Korea
SQL> select nvl2('aa','Corea','Korea') from dual;
NVL2(
-----
Corea
SQL>
 

4-18) PATH 함수
--------------------------------------------------------------------------------
PATH(correlation_path) 함수는 under_path나 equals_path의 보조함수로서,
 자원의 관계경로를 반환한다.
【예제】
SQL> select * from resource_view;
SQL> select path(1), depth(2)
  2  from resource_view
  3  where under_path(res, '/sys/schemas/PUBLIC/www.w3.org/2001', 1)=1?
  4    and under_path(res, '/sys/schemas/PUBLIC/www.w3.org/2001', 2)=1;
PATH(1)                                      DEPTH(2)
------------------------------------------ ----------
/xml.xsd                                            1
        
SQL>
 

4-19) SYS_CONNECT_BY_PATH 함수
--------------------------------------------------------------------------------
SYS_CONNECT_BY_PATH(column, char) 함수는 계층적 쿼리에서만 유효하며,
 column의 절대 경로를 char로 지정한 문자로 분리하여 반환한다.
【예제】
SQL> select sys_connect_by_path(name, '/') from emp
  2  start with name='jijoe'
  3  connect by prior id=1101;
SYS_CONNECT_BY_PATH(NAME,'/')
-----------------------------
/jijoe
SQL> select * from emp;
        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100
SQL>
 
4-20) SYS_CONTEXT 함수
--------------------------------------------------------------------------------
 이 함수는 namespace와 관계되는 parameter의 값을 반환한다.
【형식】
SYS_CONTEXT('namespace','parameter' [,length])
【예제】
SQL> select sys_context('userenv','session_user') from dual;
SYS_CONTEXT('USERENV','SESSION_USER')
-------------------------------------
JIJOE
SQL> select sys_context('userenv','lang') from dual;
SYS_CONTEXT('USERENV','LANG')
-----------------------------
US
SQL>
 userenv에서 사용될 parameter는 다음과 같다.
AUDITED_CURSORID AUTHENTICATION_DATA BG_JOB_ID
CLIENT_IDENTIFIER CLIENT_INFO  CURRENT_SCHEMA
CURRENT_SCHEMAID CURRENT_SQL  CURRENT_USER
CURRENT_USERID  DB_DOMAIN  DB_NAME
ENTRY_ID  EXTERNAL_NAME  FG_JOB_ID
GLOBAL_CONTEXT_MEMORY HOST   INSTANCE
IP_ADDRESS  ISDBA   LANG
LANGUAGE  NETWORK_PROTOCOL NLS_CALENDAR
NLS_CURRENCY  NLS_DATE_FORMAT  NLS_DATE_LANGUAGE
NLS_SORT  NLS_TERRITORY  OS_USER
PROXY_USER  PROXY_USERID  SESSION_USER
SESSION_USERID  SESSIONID  TERMINAL
 

4-21) SYS_DBURIGEN 함수
--------------------------------------------------------------------------------
이 함수는 입력된 argument에 대한 DBURIType의 URL을 반환한다.
【형식】
SYS_DBURIGEN({column|attribute} [rowid],... [,'text()'])
【예제】
SQL> select sys_dburigen(id,name) from emp
  2  where name='jijoe';
SYS_DBURIGEN(ID,NAME)(URL, SPARE)
------------------------------------------------------------------------
DBURITYPE('/PUBLIC/EMP/ROW[ID=''1104'']/NAME', NULL)
SQL> select * from emp;
        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100
SQL>
 
4-22) SYS_EXTRACT_UTC 함수
--------------------------------------------------------------------------------
sys_extract_utc(datetime_with_timezone) 함수는
UTC(coordinated universal time: Greenwich mean time) 시각을 반환한다. 
【예제】
SQL> select systimestamp, sys_extract_utc(systimestamp) from dual;
SYSTIMESTAMP
--------------------------------------------------------------------------
SYS_EXTRACT_UTC(SYSTIMESTAMP)
--------------------------------------------------------------------------
06-AUG-04 02.41.39.258976 PM +09:00
06-AUG-04 05.41.39.258976 AM

SQL>
 
4-23) SYS_GUID 함수
--------------------------------------------------------------------------------
sys_guid() 함수는 globally unique identifier를 반환한다.
【예제】
SQL> select sys_guid() from dual;
SYS_GUID()
--------------------------------
E0F6C6D5767C01ADE034080020B588F4
SQL>
 
4-24) SYS_XMLAGG 함수
--------------------------------------------------------------------------------
이 함수는 sys_xmlgen 문에서 만든 XML 문을 기본적으로 ROWSET 태그를 새로 추가 시킨다.
【형식】
SYS_XMLAGG( expr [fmt] )
【예제】
SQL> select sys_xmlagg(sys_xmlgen(name)) from emp
  2  where name like 'j%';
SYS_XMLAGG(SYS_XMLGEN(NAME))
--------------------------------------------------------------------------
<ROWSET>
  <NAME>jijoe</NAME>
</ROWSET>

SQL>
 
4-25) SYS_XMLGEN 함수
--------------------------------------------------------------------------------
이 함수는 지정한 행이나 열을 XML 문으로 만들어 반환한다.
【형식】
SYS_XMLGEN( expr [fmt] )
【예제】
SQL> select sys_xmlgen(name) from emp
  2  where name like 'j%';
SYS_XMLGEN(NAME)
--------------------------------------------------------------------------
<NAME>jijoe</NAME>
SQL>
 
4-26) UID 함수
--------------------------------------------------------------------------------
UID 함수는 사용자의 유일한 ID를 정수로 반환한다.
【예제】
SQL> select uid from dual;
       UID
----------
        93
SQL>
 
4-27) USER 함수
--------------------------------------------------------------------------------
이 함수는 사용자의 이름을 반환한다.
【예제】
SQL> select user,uid from dual;
USER                                  UID
------------------------------ ----------
JIJOE                                  93
SQL>
 

4-28) USERENV 함수
--------------------------------------------------------------------------------
USERENV('parameter') 함수는 사용자의 환경에 관한 정보를 반환한다.
 parameter는 다음과 같은 것이 있다.
CLIENT_INFO ENTRYID  ISDBA  LANG 
LANGUAGE SESSIONID TERMINAL
【예제】
SQL> select userenv('language') from dual;
USERENV('LANGUAGE')
----------------------------------------------------
AMERICAN_AMERICA.KO16KSC5601
SQL>
 
 
4-29) VSIZE 함수
--------------------------------------------------------------------------------
VSIZE('expr') 함수는 expr이 표시되는 바이트 수를 반환한다.
【예제】
SQL> select name, vsize(name) from emp
  2  where name like 'jijoe';
NAME       VSIZE(NAME)
---------- -----------
jijoe                5
SQL>
$ cat .profile
..........
NLS_LANG=AMERICAN_AMERICA.KO16KSC5601  ☜ 한글 문자셋으로 설정
export NLS_LANG
NLS_LANG=AMERICAN_AMERICA.UTF8  ☜ UNICODE로 설정
export NLS_LANG
$

테이블에서 저장된 데이터가 한글 문자셋인지 유니코드인지 식별하려면 다음과 같이 확인해 볼 수 있다.
    select 한글컬럼명, vsize(한글컬럼명) from 테이블명;
여기서 한글 컬럼에 한글이 3글자라면, vsize 결과가
    9이면 unicode이고,
    6이면 한글 문자셋으로 저장된 것임을 알 수 있다.
【예제】
SQL> select * from test;
 
        ID NAME
---------- ----------------------------------------
      1113 아리랑
      1112 쓰리랑
 
SQL> select name, vsize(name) from test;
 
NAME                                     VSIZE(NAME)
---------------------------------------- -----------
아리랑                                             6
쓰리랑                                             6
 
SQL>
 

4-30) XMLAGG 함수
--------------------------------------------------------------------------------
이 함수는 xmlelement에 의해서 XML 태그를 만든 문장을 모으는 기능이다.
【형식】
XMLAGG( XMLType_instance [order_by_clause])
【예제】
 SQL> select xmlagg(xmlelement("name",e.name)) from emp e;
XMLAGG(XMLELEMENT("NAME",E.NAME))
--------------------------------------------------------------------------
<name>Cho</name>
<name>Joe</name>
<name>kim</name>
<name>jijoe</name>
SQL>
 

4-31) XMLCOLATTVAL 함수
--------------------------------------------------------------------------------
이 함수는 XML fragment를 만드는 기능이다
【형식】
XMLCOLATTVAL( value_expr [AS c_alias],...)
【예제】
SQL> select xmlcolattval(e.name,e.id,e.salary) from emp e;
XMLCOLATTVAL(E.NAME,E.ID,E.SALARY)
--------------------------------------------------------------------------
<column name="NAME">Cho</column>
<column name="ID">1101</column>
<column name="S
<column name="NAME">Joe</column>
<column name="ID">1102</column>
<column name="S
<column name="NAME">kim</column>
<column name="ID">1103</column>
<column name="S
<column name="NAME">jijoe</column>
<column name="ID">1104</column>
<column name=

SQL> select * from emp;
        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100
SQL>
 

4-32) XMLCONCAT 함수
--------------------------------------------------------------------------------
XMLCONCAT( XMLType_instance,...) 함수는 XMLType instance를 series로 넣어 만드는 기능이다.
【예제】
SQL> select xmlconcat(
  2    xmlelement("name",e.name),xmlelement("bonus",e.bonus))
  3  from emp e;
XMLCONCAT(XMLELEMENT("NAME",E.NAME),XMLELEMENT("BONUS",E.BONUS))
--------------------------------------------------------------------------
<name>Cho</name>
<bonus>125</bonus>
<name>Joe</name>
<bonus>100</bonus>
<name>kim</name>
<bonus>100</bonus>
<name>jijoe</name>
<bonus>100</bonus>
SQL>
 
4-33) XMLFOREST 함수
--------------------------------------------------------------------------------
이 함수는 각각의 argument parameter를  XML로 변환한다.
【형식】
XMLFOREST( value_expr [AS c_alias],...)
【예제】
SQL> select xmlelement("emp",
  2  xmlforest(e.id, e.name, e.bonus)) from emp e;
XMLELEMENT("EMP",XMLFOREST(E.ID,E.NAME,E.BONUS))
--------------------------------------------------------------------------
<emp>
  <ID>1101</ID>
  <NAME>Cho</NAME>
  <BONUS>125</BONUS>
</emp>
<emp>
  <ID>1102</ID>
  <NAME>Joe</NAME>
  <BONUS>100</BONUS>
</emp>
<emp>
  <ID>1103</ID>
  <NAME>kim</NAME>
  <BONUS>100</BONUS>
</emp>
<emp>
  <ID>1104</ID>
  <NAME>jijoe</NAME>
  <BONUS>100</BONUS>
</emp>
SQL> select * from emp;
        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100
SQL>
 
 
4-34) XMLELEMENT 함수
--------------------------------------------------------------------------------
이 함수는 XML 태그를 붙이는 기능이다
【예제】
SQL> select xmlelement("name",e.name) from emp e
  2  where name like 'j%';
XMLELEMENT("NAME",E.NAME)
--------------------------------------------------------------------------
<name>jijoe</name>
SQL>
 

5-1) AVG* 함수
--------------------------------------------------------------------------------
조건을 만족하는 행(row)의 평균을 값을 반환하며,
 aggregate 함수나
 analytic 함수로 사용된다.
【형식】
AVG( [DISTINCT | ALL] 컬럼명)
   [ [OVER] (analytic 절)]
【예제】aggregate 예
SQL> select * from emp;
        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100
SQL> select avg(salary) from emp;
AVG(SALARY)
-----------
        240
SQL>
【예제】analytic 예
SQL> select avg(distinct salary) over(partition by bonus)
  2  from emp;
AVG(DISTINCTSALARY)OVER(PARTITIONBYBONUS)
-----------------------------------------
                               236.666667
                               236.666667
                               236.666667
                                      250

SQL> select avg(salary) over(partition by bonus order by id
    2 rows between 1 preceding and 1 following) as avg  from emp;
       AVG
----------
       245
236.666667
       235
       250
SQL>
 

5-2) CORR* CORR* 함수
--------------------------------------------------------------------------------
집합 쌍의 상관관계 계수를 반환한다.
【형식】
CORR( expr1, expr2 ) [ [OVER] (analytic 절)]
【예제】
SQL> select corr(avg(bonus),max(bonus))
  2  from employees
  3  group by dept_no;
CORR(AVG(BONUS),MAX(BONUS))
---------------------------
                          1
SQL>
 
5-3) COUNT* 함수
--------------------------------------------------------------------------------

 쿼리한 행의 수를 반환한다.
【형식】
COUNT([*|DISTINCT|ALL] 컬럼명) [ [OVER] (analytic 절)]
【예제】
SQL> select count(*) from emp;
  COUNT(*)
----------
         4
SQL> select count (distinct dept_no) from employees;
COUNT(DISTINCTDEPT_NO)
----------------------
                     2
SQL> select count (all dept_no) from employees;
COUNT(ALLDEPT_NO)
-----------------
                4
SQL> select salary,count(*)
  2  over (order by salary)
  3  from emp;
    SALARY COUNT(*)OVER(ORDERBYSALARY)
---------- ---------------------------
       220                           1
       240                           2
       250                           4
       250                           4
SQL>
 

5-4) COVAR_POP 함수
--------------------------------------------------------------------------------
이 함수는 number 쌍의 집합에 대한 population covariance를 반환한다.
【형식】
COVAR_POP(expr1, expr2 [ OVER (analytic 절)] )
【예제】
SQL> select covar_pop(bonus,salary) from emp;
COVAR_POP(BONUS,SALARY)
-----------------------
                   62.5
SQL> select * from emp;
        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100
SQL>
 
5-5) COVAR_SAMP 함수
--------------------------------------------------------------------------------
이 함수는 number 쌍의 집합에 대한 sample covariance를 반환한다.
【형식】
COVAR_SAMP(expr1, expr2 [ OVER (analytic 절)] )
【예제】
SQL> select covar_samp(bonus,salary) from emp;
COVAR_SAMP(BONUS,SALARY)
------------------------
              83.3333333
SQL> select * from emp;
        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100
SQL>
 
5-6) CUME_DIST 함수
--------------------------------------------------------------------------------
이 함수는 그룹 값 내에서 어떤 값의 cumulative distribution(누적분포)을 계산한다.
【형식】
CUME_DIST(expr,... WITHIN GROUP (ORDER BY
     expr [DESC | ASC] [NULLS {FIRST|LAST}],...)
또는
CUME_DIST() over ([query_partition_clause] order_by_clause)
【예제】
SQL> select cume_dist(230) within group
  2  (order by salary ) from emp;
CUME_DIST(230)WITHINGROUP(ORDERBYSALARY)
----------------------------------------
                                      .4
SQL> select * from emp;
        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100
SQL>
 

5-7) DENSE_RANK 함수
--------------------------------------------------------------------------------

그룹 내에서 순위를 반환한다.
【예제】
SQL> select * from employees;
        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100
SQL> select dense_rank(230, .05) within group
  2  (order by salary, bonus) "Dense Rank"
  3  from employees;
Dense Rank
----------
         2
SQL>
 

5-8) FIRST 함수
--------------------------------------------------------------------------------
first나 last 함수는 행을 서열화 시켜서 첫 번째나 마지막 행을 추출한다.
【형식】
집합함수 KEEP (
 DENSE_RANK FIRST ORDER BY
    expr [DESC|ASC][NULL{FIRST|LAST}],...)
【예제】
SQL> select
  2  min(salary) keep (dense_rank first order by salary) "Worst",
  3  max(salary) keep (dense_rank last order by salary) "Best"
  4  from employees
  5  order by id;
     Worst       Best
---------- ----------
       220        250
SQL> select * from employees;
        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100
SQL>
 

5-9) GROUP_ID 함수
--------------------------------------------------------------------------------
GROUP() 함수는 group by로 분리되어 복제된 번호로 복제 횟수를 구분하도록 출력한다.
번호가 0부터 시작되므로 n번 복제되었으면 n-1의 번호가 출력된다.
【예제】
SQL> select dept_no, group_id() from employees
  2  group by dept_no;
   DEPT_NO GROUP_ID()
---------- ----------
        10          0
        20          0
SQL> select * from employees;
        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100
SQL>
 

5-10) Grouping 함수
--------------------------------------------------------------------------------
Grouping 함수는 Rollup이나 cube 연산자랑 함께 사용하여
 grouping 함수에서 기술된 컬럼이 그룹핑시 사용되었는지 보여주는 함수이다.
특별히 연산의 기능은 없으며,
  rollup이나 cube 연산 후 출력된 결과에 대한 사용자의 이해를 높이기 위해 사용된다.
  즉, grouping 함수를 이용할 경우 출력되는 결과값 중 null 값이 있다면,
      이 null 값이 rollup이나 cube 연산의 결과로 생성된 값인지,
      원래 테이블상에 null 값으로 저장된 것인지 확인할 수 있다.
. grouping 함수는 인수로 하나의 값만을 가진다.
. grouping 함수에 사용된 인수는 group by 절에 기술된 값 중에 하나와 반드시 일치해야 한다.
. grouping 함수의 결과값으로 0 또는 1을 반환한다.
    0은 해당인수로 쓰인 값이 rollup이나 cube 연산에 사용되었음을 나타나고,
    1은 사용되지 않았음을 의미한다.
【형식】
SELECT   컬럼명,그룹함수(컬럼명), GROUPING(컬럼명)
FROM  테이블명
WHERE  조건
GROUP BY [ROLLUP | CUBE] 그룹핑하고자하는 컬럼명,...
HAVING  그룹조건
ORDER BY 컬럼명 또는 위치번호
【예제】
SQL> select grade,deptno,sum(salary),GROUPING(deptno)
  2  from aaa
  3  group by rollup(grade,deptno);
     GRADE     DEPTNO SUM(SALARY) GROUPING(DEPTNO)
---------- ---------- ----------- ----------------
         1         10         100                0
         1         20         500                0
         1         30         300                0
         1                    900                1
         2         10         400                0
         2         20         200                0
         2         30         600                0
         2                   1200                1
                             2100                1
9 rows selected.
SQL>
 
5-11) GROUPING_ID 함수
--------------------------------------------------------------------------------
GROUPING_ID(expr,...) 함수는 행과 관련되는 GROUPING 비트 벡터에 대응되는 수치를 반환한다.
【예제】
SQL> select * from employees;
        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100
SQL> select sum(salary), grouping_id(dept_no)
  2  from employees
  3  group by dept_no;
SUM(SALARY) GROUPING_ID(DEPT_NO)
----------- --------------------
        500                    0
        460                    0
SQL>
 
5-12) LAST 함수
--------------------------------------------------------------------------------
first나 last 함수는 행을 서열화 시켜서 첫 번째나 마지막 행을 추출한다.
【형식】
집합함수 KEEP (
 DENSE_RANK LAST ORDER BY
    expr [DESC|ASC][NULL{FIRST|LAST}],...)
【예제】
SQL> select
  2  min(salary) keep (dense_rank first order by salary) "Worst",
  3  max(salary) keep (dense_rank last order by salary) "Best"
  4  from employees
  5  order by id;
     Worst       Best
---------- ----------
       220        250
SQL> select * from employees;
        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100
SQL>
 

5-13) MAX 함수
--------------------------------------------------------------------------------
이 함수는 최대 값을 반환한다.
【형식】
MAX ([{DISTINCT|ALL}] expr) [OVER(analytic_clause)]
【예제】
SQL> select max(salary) over (partition by dept_no)
  2  from employees;
MAX(SALARY)OVER(PARTITIONBYDEPT_NO)
-----------------------------------
                                250
                                250
                                240
                                240
SQL> select max(salary) from employees;
MAX(SALARY)
-----------
        250
SQL>
 
5-14) MIN 함수
--------------------------------------------------------------------------------
이 함수는 최소 값을 반환한다.
【형식】
MIN ([{DISTINCT|ALL}] expr) [OVER(analytic_clause)]
【예제】
SQL> select min(salary) over (partition by dept_no)
  2  from employees;
MIN(SALARY)OVER(PARTITIONBYDEPT_NO)
-----------------------------------
                                250
                                250
                                220
                                220
SQL> select min(salary) from employees;
MIN(SALARY)
-----------
        220
SQL>
 

5-15) PERCENTILE_CONT 함수
--------------------------------------------------------------------------------
이 함수는 연속 모델에 대한 inverse distribution function이다.
【형식】
PERCENTILE_CONT(expr) WITHIN GROUP (ORDER BY expr [{DESC|ASC}])
  [OVER (query_partition_cluause)]
【예제】
SQL> select dept_no,percentile_cont(0.5) within group
  2  (order by salary DESC)
  3  from employees GROUP BY dept_no;
   DEPT_NO PERCENTILE_CONT(0.5)WITHINGROUP(ORDERBYSALARYDESC)
---------- --------------------------------------------------
        10                                                250
        20                                                230
SQL> select * from employees;
        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100
SQL>
 

5-16) PERCENTILE_DISC 함수
--------------------------------------------------------------------------------
이 함수는 불연속 모델에 대한 inverse distribution function이다.
【형식】
PERCENTILE_DISC(expr) WITHIN GROUP (ORDER BY expr [{DESC|ASC}])
  [OVER (query_partition_cluause)]
【예제】
SQL> select dept_no,percentile_disc(0.5) within group
  2  (order by salary DESC)
  3  from employees GROUP BY  dept_no;
   DEPT_NO PERCENTILE_DISC(0.5)WITHINGROUP(ORDERBYSALARYDESC)
---------- --------------------------------------------------
        10                                                250
        20                                                240
SQL> select * from employees;
        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100
SQL>
 

5-17) PERCENT_RANK 함수
--------------------------------------------------------------------------------
이 함수는 CUME_DIST 함수와 유사하게 percent_rank 값을 반환한다.
【형식】
PERCENT_RANK(expr,...) WITHIN GROUP (ORDER BY expr [{DESC|ASC}]
  [NULLS {FIRST|LAST}],...)
또는
PERCENT_RANK() OVER( [query_partition_clause] order_by_clause)
【예제】
SQL> select percent_rank(230,0.05) within group
  2  (order by salary,bonus) from employees;
PERCENT_RANK(230,0.05)WITHINGROUP(ORDERBYSALARY,BONUS)
------------------------------------------------------
                                                   .25
SQL> select * from employees;
        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100
SQL>
 

5-18) RANK 함수
--------------------------------------------------------------------------------
이 함수는 그룹 내에서 위치를 반환한다.
【형식】
RANK(expr,...) WITHIN GROUP (ORDER BY expr [{DESC|ASC}]
  [NULLS {FIRST|LAST}],...)
또는
RANK() OVER( [query_partition_clause] order_by_clause)
【예제】
SQL> select rank(230,0.05) within group
  2 (order by salary,bonus) from employees;
RANK(230,0.05)WITHINGROUP(ORDERBYSALARY,BONUS)
----------------------------------------------
                                             2
SQL> select * from employees;
        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100
SQL>
 

5-19) REGR_(linear regression) function* 함수
--------------------------------------------------------------------------------
선형 회귀(linear regression) 함수 ordinary-least squares regression line을 찾도록 한다.
 사용되는 회귀함수는 자음 중 하나이다.
 REGR_SLOPE REGR_INTERCEPT REGR_COUNT
 REGR_R2 REGR_AVGX REGR_AVGY 
 REGR_SXX REGR_SYY REGR_SXY
【형식】
REGR { REGR_SLOPE|REGR_INTERCEPT|REGR_COUNT|REGR_R2|REGR_AVGX|
       REGR_AVGY|REGR_SXX|REGR_SYY|REGR_SXY}
    (expr1,expr2) [OVER (analytic_clause)]
【예제】
SQL> select regr_slope(salary,bonus) from employees
REGR_SLOPE(SALARY,BONUS)
------------------------
              .533333333
SQL> select * from employees;
        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100
SQL>
 

5-20) STDDEV 함수
--------------------------------------------------------------------------------
이 함수는 standard deviation을 반환한다.
【형식】
STDDEV [{DISTINCT|ALL}] (expr) [OVER (analytic_clause)]
【예제】
SQL> select stddev(salary) from emp;
STDDEV(SALARY)
--------------
    14.1421356
SQL> select * from emp;
        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100
SQL>
 

5-21) STDDEV_POP 함수
--------------------------------------------------------------------------------
이 함수는 population standard deviation을 반환한다.
【형식】
STDDEV_POP (expr) [OVER (analytic_clause)]
【예제】
SQL> select stddev_pop(salary) from emp;
STDDEV_POP(SALARY)
------------------
        12.2474487
SQL> select * from emp;
        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100
SQL>

5-22) STDDEV_SAMP 함수
--------------------------------------------------------------------------------
이 함수는 cumulative sample standard deviation을 반환한다.
【형식】
STDDEV_SAMP (expr) [OVER (analytic_clause)]
【예제】
SQL> select stddev_samp (salary) from emp;
STDDEV_SAMP(SALARY)
-------------------
         14.1421356
SQL> select * from emp;
        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100

SQL>
 

5-23) SUM 함수
--------------------------------------------------------------------------------
이 함수는 합계를 반환한다.
【형식】
SUM ([{DISTINCT|ALL}] expr) [OVER (analytic_clause)]
【예제】
SQL> select sum(salary) from emp;
SUM(SALARY)
-----------
        960
SQL> select * from emp;
        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100
SQL>
 

5-24) VAR_POP 함수
--------------------------------------------------------------------------------
이 함수는 population variance를 반환한다.
【형식】
VAR_POP (expr) [OVER (analytic_clause)]
【예제】
SQL> select var_pop(salary) from emp;
VAR_POP(SALARY)
---------------
            150
SQL> select * from emp;
        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100

SQL>
 

5-25) VAR_SAMP 함수
--------------------------------------------------------------------------------
이 함수는 sample variance를 반환한다.
【형식】
VAR_SAMP (expr) [OVER (analytic_clause)]
【예제】
SQL> select var_samp(salary) from emp;
VAR_SAMP(SALARY)
----------------
             200
SQL> select * from emp;
        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100

SQL>
 

5-26) VARIANCE 함수
--------------------------------------------------------------------------------
이 함수는 variance를 반환한다.
【형식】
VARIANCE ([{DISTINCT|ALL}] expr) [OVER (analytic_clause)]
【예제】
SQL> select variance(salary) from emp;
VARIANCE(SALARY)
----------------
             200
SQL> select * from emp;
        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100
SQL>
 

5-27) Grouping sets 함수
--------------------------------------------------------------------------------
Grouping sets 함수는 Group by의 확장된 형태로 하나의 쿼리문에서 원하는 그룹핑 조건을 여러 개 기술할 수 있으며,
 grouping sets 함수 사용이 불가능한 이전 버전에서
 복잡한 union all 연산자를 사용하여 기술하던 것을 간단하게
 한 문장 안에서 해결할 수 있어 검색시 효율성이 증대 된다.
 다시 말해서, grouping sets 함수를 사용하면,
              group by ... union all을 사용한 것보다
              SQL 문이 간단해지고 또한 실행시 성능이 빨라진다.
【형식】
SELECT   컬럼명,그룹함수(컬럼명), GROUPING(컬럼명)
FROM  테이블명
WHERE  조건
GROUP BY [ROLLUP | CUBE] 그룹핑하고자하는 컬럼명, ...
  [GROUPING SETS (컬럼명,컬럼명, ...), ...]
HAVING  그룹조건
ORDER BY 컬럼명 또는 위치번호
【예제】
SQL> select grade,deptno,sum(salary)
  2  from aaa
  3  group by grouping sets(grade,deptno);
     GRADE     DEPTNO SUM(SALARY)
---------- ---------- -----------
         1                    900
         2                   1200
                   10         500
                   20         700
                   30         900
SQL> select grade,deptno,sum(salary)
  2  from aaa
  3  group by grouping sets((grade,name),(deptno,name));
     GRADE     DEPTNO SUM(SALARY)
---------- ---------- -----------
         1                    100
         1                    300
         1                    500
         2                    200
         2                    400
         2                    600
                   10         100
                   20         200
                   30         300
                   10         400
                   20         500
                   30         600
12 rows selected.
SQL>
【예제】Union all을 사용한 경우
SQL> select grade,deptno,sum(salary)
  2  from aaa
  3  group by grade,deptno
  4  union all
  5  select grade,deptno,sum(salary)
  6  from aaa
  7  group by grade,deptno;
     GRADE     DEPTNO SUM(SALARY)
---------- ---------- -----------
         1         10         100
         1         20         500
         1         30         300
         2         10         400
         2         20         200
         2         30         600
         1         10         100
         1         20         500
         1         30         300
         2         10         400
         2         20         200
         2         30         600
12 rows selected.
SQL>
composite columns란 rollup, cube, grouping sets 절과 같은 기능을 사용하면
표현되는 각 컬럼이 하나가 아닌 복수 개의 컬럼으로 정의되는 경우이며
다음 표를 보고 이해하자.
composite column 문의 경우  group by 문의 경우 group by grouping sets(a,b,c)  group by a union allgroup by b union allgroup by c  group by grouping sets(a,b,(b,c))  group by a union allgroup by b union allgroup by b,c  group by grouping sets((a,b,c))  group by a,b,c  group by grouping sets(a,(b),())  group by a union allgroup by b union allgroup by ()  group by grouping sets(a,rollup(b,c))  group by a union allgroup by rollup(b,c)  group by rollup(a,b,c)  group by (a,b,c) union allgroup by (a,b) union allgroup by (a) union allgroup by ()  group by cube(a,b,c)  group by (a,b,c) union allgroup by (a,b) union allgroup by (a,c) union allgroup by (b,c) union allgroup by (a) union allgroup by (b) union allgroup by (c) union allgroup by () 
 

6-1) AVG* 함수
--------------------------------------------------------------------------------
조건을 만족하는 행(row)의 평균을 값을 반환하며,
 aggregate 함수나
 analytic 함수로 사용된다.
【형식】
AVG( [DISTINCT | ALL] 컬럼명)
   [ [OVER] (analytic 절)]
【예제】aggregate 예
SQL> select * from emp;
        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100
SQL> select avg(salary) from emp;
AVG(SALARY)
-----------
        240
SQL>
【예제】analytic 예
SQL> select avg(distinct salary) over(partition by bonus)
  2  from emp;
AVG(DISTINCTSALARY)OVER(PARTITIONBYBONUS)
-----------------------------------------
                               236.666667
                               236.666667
                               236.666667
                                      250

SQL> select avg(salary) over(partition by bonus order by id
    2 rows between 1 preceding and 1 following) as avg  from emp;
       AVG
----------
       245
236.666667
       235
       250
SQL>
 

6-2) CORR* CORR* 함수
--------------------------------------------------------------------------------
집합 쌍의 상관관계 계수를 반환한다.
【형식】
CORR( expr1, expr2 ) [ [OVER] (analytic 절)]
【예제】
SQL> select corr(avg(bonus),max(bonus))
  2  from employees
  3  group by dept_no;
CORR(AVG(BONUS),MAX(BONUS))
---------------------------
                          1
SQL>
 
6-3) COUNT* 함수
--------------------------------------------------------------------------------

 쿼리한 행의 수를 반환한다.
【형식】
COUNT([*|DISTINCT|ALL] 컬럼명) [ [OVER] (analytic 절)]
【예제】
SQL> select count(*) from emp;
  COUNT(*)
----------
         4
SQL> select count (distinct dept_no) from employees;
COUNT(DISTINCTDEPT_NO)
----------------------
                     2
SQL> select count (all dept_no) from employees;
COUNT(ALLDEPT_NO)
-----------------
                4
SQL> select salary,count(*)
  2  over (order by salary)
  3  from emp;
    SALARY COUNT(*)OVER(ORDERBYSALARY)
---------- ---------------------------
       220                           1
       240                           2
       250                           4
       250                           4
SQL>
 

6-4) COVAR_SAMP 함수
--------------------------------------------------------------------------------
이 함수는 number 쌍의 집합에 대한 sample covariance를 반환한다.
【형식】
COVAR_SAMP(expr1, expr2 [ OVER (analytic 절)] )
【예제】
SQL> select covar_samp(bonus,salary) from emp;
COVAR_SAMP(BONUS,SALARY)
------------------------
              83.3333333
SQL> select * from emp;
        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100
SQL>
 

6-5) CUME_DIST 함수
--------------------------------------------------------------------------------
이 함수는 그룹 값 내에서 어떤 값의 cumulative distribution(누적분포)을 계산한다.
【형식】
CUME_DIST(expr,... WITHIN GROUP (ORDER BY
     expr [DESC | ASC] [NULLS {FIRST|LAST}],...)
또는
CUME_DIST() over ([query_partition_clause] order_by_clause)
【예제】
SQL> select cume_dist(230) within group
  2  (order by salary ) from emp;
CUME_DIST(230)WITHINGROUP(ORDERBYSALARY)
----------------------------------------
                                      .4
SQL> select * from emp;
        ID NAME           SALARY      BONUS
---------- ---------- ---------- ----------
      1101 Cho               250        125
      1102 Joe               240        100
      1103 kim               250        100
      1104 jijoe             220        100
SQL>
 
6-6) DENSE_RANK 함수
--------------------------------------------------------------------------------

그룹 내에서 순위를 반환한다.
【예제】
SQL> select * from employees;
        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100
SQL> select dense_rank(230, .05) within group
  2  (order by salary, bonus) "Dense Rank"
  3  from employees;
Dense Rank
----------
         2
SQL>
 
6-7) FIRST 함수
--------------------------------------------------------------------------------
first나 last 함수는 행을 서열화 시켜서 첫 번째나 마지막 행을 추출한다.
【형식】
집합함수 KEEP (
 DENSE_RANK FIRST ORDER BY
    expr [DESC|ASC][NULL{FIRST|LAST}],...)
【예제】
SQL> select
  2  min(salary) keep (dense_rank first order by salary) "Worst",
  3  max(salary) keep (dense_rank last order by salary) "Best"
  4  from employees
  5  order by id;
     Worst       Best
---------- ----------
       220        250
SQL> select * from employees;
        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100
SQL>
 
6-8) FIRST_VALUE 함수
--------------------------------------------------------------------------------
이 함수는 서열화된 값에서 첫 번째를 출력한다.
【형식】
FIRST_VALUE ( expr ) OVER ( analytic_절)
【예제】
SQL> select salary,first_value(name)
  2  over (order by salary asc)
  3  from (select * from employees
  4        where dept_no = 20
  5        order by salary);
    SALARY FIRST_VALU
---------- ----------
       220 jijoe
       240 jijoe
SQL> select * from employees;
        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100
SQL>
 
6-9) LAG 함수
--------------------------------------------------------------------------------
이 함수는 analytic 함수로서,
self join하지 않고 하나의 테이블에서 동시에 한 행(row) 이상을 접근할 수 있도록 한다.
【형식】
LAG ( value_expr [,offset] [,default] )
     OVER ([query_partition_clause] order_by_clause )
【예제】
SQL> select name,salary,LAG(salary,1,0)    
  2   OVER (ORDER BY salary) FROM employees;
NAME           SALARY LAG(SALARY,1,0)OVER(ORDERBYSALARY)
---------- ---------- ----------------------------------
jijoe             220                                  0
Joe               240                                220
Cho               250                                240
kim               250                                250
SQL> select * from employees;
        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100
SQL>
 

6-10) LAST_VALUE 함수
--------------------------------------------------------------------------------
이 함수는 서열화된 값에서 마지막 번째를 출력한다.
【형식】
LAST_VALUE ( expr ) OVER ( analytic_절)
【예제】
SQL> select salary,last_value(name)
  2  over (order by salary asc)
  3  from (select * from employees
  4        where dept_no = 20
  5        order by salary);
    SALARY LAST_VALUE
---------- ----------
       220 jijoe
       240 Joe
SQL> select * from employees;
        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100
SQL>
 

6-11) LEAD 함수
--------------------------------------------------------------------------------
이 함수는 analytic 함수로서, self join하지 않고
하나의 테이블에서 동시에 한 행(row) 이상을 접근할 수 있도록 한다.
【형식】
LEAD ( value_expr [,offset] [,default] )
     OVER ([query_partition_clause] order_by_clause )
【예제】
SQL> select name,salary,LEAD(salary,1,0)   
  2   OVER (ORDER BY salary) FROM  employees;
NAME           SALARY LEAD(SALARY,1,0)OVER(ORDERBYSALARY)
---------- ---------- -----------------------------------
jijoe             220                                 240
Joe               240                                 250
Cho               250                                 250
kim               250                                   0
SQL> select * from employees;
        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100
SQL>
 
6-12) NTILE 함수
--------------------------------------------------------------------------------
이 함수는 analytic 함수로서, 데이터를 주어진 bucket 수 expr로 분리한다.
【형식】
NTILE ( expr ) OVER ([query_partition_clause] order_by_clause )
【예제】
SQL> select name,salary,NTILE(3) OVER (ORDER BY salary DESC)
  2  FROM  employees;
NAME           SALARY NTILE(3)OVER(ORDERBYSALARYDESC)
---------- ---------- -------------------------------
Cho               250                               1
kim               250                               1
Joe               240                               2
jijoe             220                               3
SQL> select * from employees;
        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100
SQL>
 

6-13) RATIO_TO_REPORT 함수
--------------------------------------------------------------------------------
이 함수는 analytic 함수로서, 데이터 합에 대한 구성비를 계산한다.
【형식】
RATIO_TO_REPORT ( expr ) OVER ([query_partition_clause])
【예제】
SQL> select name,salary,RATIO_TO_REPORT(salary) OVER ()
  2   FROM  employees;
NAME           SALARY RATIO_TO_REPORT(SALARY)OVER()
---------- ---------- -----------------------------
Cho               250                    .260416667
Joe               240                           .25
kim               250                    .260416667
jijoe             220                    .229166667
SQL> select * from employees;
        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100
SQL>
 

6-14) ROW_NUMBER 함수
--------------------------------------------------------------------------------
이 함수는 analytic 함수로서, 각 행(row)에 unique 번호를 부여한다.
【형식】
ROW_NUMBER () OVER ([query_partition_clause] order_by_clause )
【예제】
SQL> SELECT ROW_NUMBER() OVER (ORDER BY salary DESC),name
  2    FROM  employees;
ROW_NUMBER()OVER(ORDERBYSALARYDESC) NAME      
----------------------------------- ----------
                                  1 Cho       
                                  2 kim       
                                  3 Joe       
                                  4 jijoe     
SQL> select * from employees;
        ID    DEPT_NO NAME           SALARY      BONUS
---------- ---------- ---------- ---------- ----------
      1101         10 Cho               250        125
      1102         20 Joe               240        100
      1103         10 kim               250        100
      1104         20 jijoe             220        100
SQL>
 
 
7-1) REF 타입
--------------------------------------------------------------------------------
테이블의 어떤 컬럼이 독립된 다른 객체 테이블을 참조하는 데이터 타입을 의미한다.
일반적으로 테이블을 만들때 사용하는 외부키(foreign-key)를 이용한 참조관계와 유사하다.
REF 타입의 컬럼 데이터를 읽을 때는 반드시 DEREF 함수를 사용한다.
REF 타입으로 정의된 컬럼에는 실제 데이터가 저장되는 것이 아니고 참조되는 객체가 존재하는 포인트정보만 가지고 있기 때문에 객체가 삭제 된다면, 해당 컬러은 정상적으로 검색되지 못한다.
이러한 현상을 REF의 Dangling 현상이고 한다.
이러한 dangling 현상을 방지하기 위해서는 삭제된 객체 정보를 참조하는 행의 컬럼 정보를 analyze 명령어를 이용하여 null 값으로 변경해 주어야 한다.
【예제】
SQL> connect jijoe/jijoe_password
connected
SQL> create type person_type as object(
  2  first_name         varchar2(10),
  3  last_name          varchar2(10),
  4  phone              varchar(12),
  5  birthday           varchar2(12));
  6  /
Type created.
SQL> create type emp_type as object (
  2  empno      number,
  3  emp        person_type);
  4  /
Type created.
SQL> create table emp2 of emp_type
  2  oidindex emp_oid;
Table created.
SQL> insert into emp2 values(
  2  emp_type(1000,person_type('junik','joe','123-1234','20-jul-04')));
1 row created.
SQL> create table dept(
  2  empno      number(4),
  3  ename      varchar2(15),
  4  mgr        REF emp_type SCOPE IS emp2);
Table created.
SQL> insert into dept
  2  select empno, 'SCOTT', REF(e)
  3  from emp2 e
  4  where empno=1000;
1 row created.

【예제】
SQL> select ename,empno from dept;
ENAME                EMPNO
--------------- ----------
SCOTT                 1000
SQL> select mgr, DEREF(mgr) from dept;
MGR
--------------------------------------------------------------------------------
DEREF(MGR)(EMPNO, EMP(FIRST_NAME, LAST_NAME, PHONE, BIRTHDAY))
--------------------------------------------------------------------------------
0000220208DFA05B27A63701D9E034080020B588F4DFA05B27A63601D9E034080020B588F4
EMP_TYPE(1000, PERSON_TYPE('junik', 'joe', '123-1234', '20-jul-04'))

SQL>
【예제】
SQL> select empno,ename,mgr
  2  from dept
  3  where mgr is dangling;
no rows selected
SQL> analyze table dept validate REF update set dangling to NULL;
Table analyzed.
SQL>
 
8-1) ROWID 컬럼
--------------------------------------------------------------------------------
오라클에서 내부적으로 사용되는 컬럼을 pseudocolumn이라고 하며,
ROWID, ROWNUM등이 있다.
ROWID는 데이터베이스에서 컬럼이 위치한 장소이다.
【예제】
SQL> select rowid from test;
ROWID
------------------
AAAHbHAABAAAMXCAAA
SQL> select rowid from test
  2  where rowidtochar(rowid) like '%AABAA%';
ROWID
------------------
AAAHbHAABAAAMXCAAA
SQL> select lengthb(rowidtonchar(rowid)), rowidtonchar(rowid)
  2  from test;
LENGTHB(ROWIDTONCHAR(ROWID)) ROWIDTONCHAR(ROWID
---------------------------- ------------------
                          36 AAAHbHAABAAAMXCAAA
SQL>

여기서 rowid의 의미는 다음과 같다.
AAAHbH  AAB  AAAMXC  AAA 객체번호  테이블스페이스번호  블록번호  행번호
 

8-2) ROWNUM 컬럼
--------------------------------------------------------------------------------
오라클에서 내부적으로 사용되는 컬럼을 pseudocolumn이라고 하며,
ROWID, ROWNUM등이 있다.
ROWNUM은 테이블에서 select 되어진 일련 번호임
【예제】
SQL> select rownum,ename from emp;
 
    ROWNUM ENAME
---------- ----------
         1 CLARK
         2 MILLER
         3 JONES
         4 ALLEN
         5 MARTIN
         6 CHAN
 
6 rows selected.
 
SQL> delete from emp where ename='JONES';
 
1 row deleted.
 
SQL> select rownum,ename from emp;
 
    ROWNUM ENAME
---------- ----------
         1 CLARK
         2 MILLER
         3 ALLEN
         4 MARTIN
         5 CHAN
 
SQL> 
      
Posted by k_ben


테이블 스페이스 생성
Create tablespace SOLFEP
DATAFILE '경로\파일이름.dbf' size 20000M
extent management local
uniform size 10M

 ALTER TABLESPACE TSMOON
ADD DATAFILE 'c:\oracle\oradata\ora9\TSMO.dbf' SIZE 200M
AUTOEXTEND ON NEXT 50M
MAXSIZE 500M

 유저 생성
CREATE USER solfep
identified by solfep123
default tablespace SOLFEP

 권한주기
grant create session to user명
grant create table to user명
grant create view to user명
grant connect, resource to user명

grant dba to user명

----------------------------------------------------------
암호나 sid모를때 도스창으로 접속..
sqlplus /nolog 로 접속

sql> conn sys/sys(암호..) as sysdba  <--sysdba권한으로 접속

connected

sql>

 sql> select username, accout_status from dba_users;

USERNAME                            ACCOUNT_STATUS

--------------------------- -------------------------------

SYSTEM                               LOCKED(TIMED)

SYS                                      LOCKED(TIMED)

 
lock 을 풀어준다.

sql> alter user test account unlock;

-----------------------------------------------------------------------

계정 추가와 동시에 테이블 스페이스 할당

create user user_name identified by password default tablespace users;

계정 추가시킨후 수정

alter user user_name default tablespace users;

'컴퓨터 > DB' 카테고리의 다른 글

페이징 방법 중 하나..  (0) 2009.01.15
오라클 함수 모음  (0) 2009.01.15
오라클 오류메시지  (0) 2009.01.15
데이터베이스 스키마  (0) 2009.01.15
데이터 베이스 테이블스페이스  (0) 2009.01.15
      
Posted by k_ben


참고하시고 msconfig에 가셔서 수정 요망.


0 0x0000 작업을 완료했습니다.
1 0x0001 올바르지 않은 함수입니다.
2 0x0002 지정한 파일을 찾을 수 없습니다.
3 0x0003 지정한 경로를 찾을 수 없습니다.
4 0x0004 파일을 열 수 없습니다.
5 0x0005 접근이 거부되었습니다.
6 0x0006 잘못된 핸들입니다.
7 0x0007 저장 컨트롤 블록이 손상되었습니다.
8 0x0008 저장 공간이 부족해서 이 명령을 수행할 수 없습니다.
9 0x0009 저장 컨트롤 블록 주소가 올바르지 않습니다.
10 0x000A 환경이 올바르지 않습니다.
11 0x000B 잘못된 형식의 프로그램을 로드하려고 했습니다.
12 0x000C 액세스 코드가 올바르지 않습니다.
13 0x000D 데이터가 올바르지 않습니다.
14 0x000E 저장 공간이 부족해서 이 작업을 완료할 수 없습니다.
15 0x000F 지정한 드라이브를 찾을 수 없습니다.
16 0x0010 디렉터리를 삭제할 수 없습니다.
17 0x0011 파일을 다른 디스크 드라이브로 이동할 수 없습니다.
18 0x0012 더 이상 파일이 없습니다.
19 0x0013 매체가 쓰기 금지되었습니다.
20 0x0014 지정한 장치를 찾을 수 없습니다.
21 0x0015 장치가 준비되지 않았습니다.
22 0x0016 장치가 명령을 인식하지 않습니다.
23 0x0017 데이터 오류 (주기적 중복 검사)
24 0x0018 프로그램에서 명령을 내렸으나 명령 길이가 올바르지 않습니다.
25 0x0019 드라이브에서 디스크의 특정 영역이나 트랙의 위치를 지정할 수 없습니다.
26 0x001A 지정한 디스크나 디스켓을 액세스할 수 없습니다.
27 0x001B 드라이브에서 요청한 섹터를 찾을 수 없습니다.
28 0x001C 프린터에 용지가 떨어졌습니다.
29 0x001D 지정한 장치에 쓸 수 없습니다.
30 0x001E 지정한 장치로부터 읽을 수 없습니다.
31 0x001F 시스템에 부착된 장치가 작동하지 않습니다.
32 0x0020 다른 프로세스에서 이 파일을 사용하고 있기 때문에 이 파일을 액세스할 수 없습니다.
33 0x0021 다른 프로세스에서 이 파일의 일부를 잠궜기 때문에 이 파일을 액세스할 수 없습니다.
34 0x0022 드라이브에 잘못된 디스켓이 있습니다. ? (볼륨 일련 번호: ?)을(를) in? 드라이브에 넣으십시오.
36 0x0024 공유하기 위해 연 파일이 너무 많습니다.
38 0x0026 파일의 끝입니다.
39 0x0027 디스크가 가득 차 있습니다.
50 0x0032 네트워크 요청이 지원되지 않습니다.
51 0x0033 원격 컴퓨터를 사용할 수 없습니다.
52 0x0034 네트워크에 중복된 이름이 있습니다.
53 0x0035 네트워크 경로를 찾을 수 없습니다.
54 0x0036 네트워크가 사용 중입니다.
55 0x0037 지정한 네트워크 리소스 또는 장치를 더 이상 사용할 수 없습니다.
56 0x0038 네트워크 BIOS 명령 한계에 도달했습니다.
57 0x0039 네트워크어댑터 하드웨어 오류가 발생했습니다.
58 0x003A 지정한 서버에서 요청한 작업을 수행할 수 없습니다.
59 0x003B 예기치 않은 네트워크 오류가 발생했습니다.
60 0x003C 원격 어댑터가 호환되지 않습니다.
61 0x003D 프린터 대기열이 가득 찼습니다.
62 0x003E 서버에 인쇄 대기 중인 파일을 저장할만한 공간이 없습니다.
63 0x003F 인쇄 대기 중인 파일이 삭제되었습니다.
64 0x0040 지정한 네트워크 이름을 더 이상 사용할 수 없습니다.
65 0x0041 네트워크 접근이 거부되었습니다.
66 0x0042 네트워크 리소스 종류가 올바르지 않습니다.
67 0x0043 네트워크 이름을 찾을 수 없습니다.
68 0x0044 지역 컴퓨터 네트워크 어댑터 카드의 이름 한계를 초과했습니다.
69 0x0045 네트워크 BIOS 세션 한계를 초과했습니다.
70 0x0046 원격 서버가 일시 중지되었거나 프로세스가 시작 중입니다.
71 0x0047 수용할 수 있는 최대 개수의 연결이 이미 있으므로 더 이상 연결을 작성 할 수 없습니다.
72 0x0048 지정한 프린터나 디스크 장치가 일시 중지되었습니다.
80 0x0050 파일이 존재합니다.
82 0x0052 디렉터리나 파일을 작성할 수 없습니다.
83 0x0053 INT 24에서 오류
84 0x0054 이 요청을 처리할만한 저장 공간이 없습니다.
85 0x0055 지역 장치 이름이 이미 사용 중입니다.
86 0x0056 지정한 네트워크 암호가 올바르지 않습니다.
87 0x0057 매개 변수가 올바르지 않습니다.
88 0x0058 네트워크에서 쓰기 오류가 발생했습니다.
89 0x0059 지금 다른 프로세스를 시작할 수 없습니다.
100 0x0064 다른 시스템 신호기를 작성할 수 없습니다.
101 0x0065 단독 신호기를 다른 프로세스가 소유하고 있습니다.
102 0x0066 신호기가 설정되었으므로 닫을 수 없습니다.
103 0x0067 신호기를 다시 설정할 수 없습니다.
104 0x0068 인터럽트 시간에 단독 신호기를 요청할 수 없습니다.
105 0x0069 이 신호기의 이전 소유권이 끝났습니다.
106 0x006A ? 드라이브에 디스켓을 넣으십시오.
107 0x006B 선택 디스켓을 넣지 않았으므로 프로그램이 중지되었습니다.
108 0x006C 디스크가 사용 중이거나 다른 프로세스에서 잠궜습니다.
109 0x006D 파이프가 종료되었습니다.
110 0x006E 지정한 장치나 파일을 열 수 없습니다.
111 0x006F 파일 이름이 너무 깁니다.
112 0x0070 디스크에 충분한 공간이 없습니다.
113 0x0071 사용할 수 있는 내부 파일 식별자가 이제 없습니다.
114 0x0072 대상 내부 파일 식별자가 올바르지 않습니다.
117 0x0075 응용 프로그램의 IOCTL 호출이 올바르지 않습니다.
118 0x0076 쓰기 확인(verify-on-write) 스위치 매개 변수 값이 올바르지 않습니다.
119 0x0077 요청한 명령이 지원되지 않습니다.
120 0x0078 이 함수는 Win32 모드에서만 유효합니다.
121 0x0079 신호기 시간 초과 기간이 만료되었습니다.
122 0x007A 시스템 호출에 전달된 데이터 영역이 너무 작습니다.
123 0x007B 파일 이름, 디렉터리 이름, 또는 디스크 이름의 구문이 올바르지 않습니다.
124 0x007C 시스템 호출 수준이 올바르지 않습니다.
125 0x007D 디스크에 디스크 이름이 없습니다.
126 0x007E 지정한 모듈을 찾을 수 없습니다.
127 0x007F 지정한 프로시저를 찾을 수 없습니다.
128 0x0080 대기 중인 하위 프로세스가 없습니다.
129 0x0081 ? 응용 프로그램을 Win32 모드에서 실행할 수 없습니다.
130 0x0082 원시 디스크 I/O 이외의 작업에 열려 있는 디스크 분할 영역의 파일 핸들을 사용하려고 했습니다.
131 0x0083 파일의 시작 부분 앞으로 파일 포인터를 옮기려고 했습니다.
132 0x0084 지정한 장치나 파일에 설정할 수 없는 파일 포인터입니다.
133 0x0085 JOIN이나 SUBST 명령을 이전에 결합된 드라이브를 포함하는 드라이브에 사용할 수 없습니다.
134 0x0086 이미 결합된 드라이브에 JOIN이나 SUBST 명령을 사용하려고 했습니다.
135 0x0087 이미 대체된 드라이브에 JOIN이나 SUBST 명령을 사용하려고 했습니다.
136 0x0088 결합되지 않은 드라이브의 JOIN을 삭제하려고 했습니다.
137 0x0089 대체되지 않은 드라이브의 대체품을 삭제하려고 했습니다.
138 0x008A 결합된 드라이브의 디렉터리로 드라이브를 결합하려고 했습니다.
139 0x008B 대체된 드라이브의 디렉터리로 드라이브를 대체하려고 했습니다.
140 0x008C 대체된 드라이브의 디렉터리로 드라이브를 결합하려고 했습니다.
141 0x008D 결합된 드라이브의 디렉터리로 드라이브를 SUBST하려고 했습니다.
142 0x008E 지금 JOIN이나 SUBST를 수행할 수 없습니다.
143 0x008F 같은 드라이브의 디렉터리로 드라이브를 결합하거나 대체할 수 없습니다.
144 0x0090 루트 디렉터리의 하위 디렉터리가 아닙니다.
145 0x0091 디렉터리가 비어 있지 않습니다.
146 0x0092 지정한 경로가 대체용으로 사용 중입니다.
147 0x0093 사용할 수 있는 리소스가 부족하므로 이 명령을 처리할 수 없습니다.
148 0x0094 지금 지정한 경로를 사용할 수 없습니다.
149 0x0095 드라이브의 디렉터리가 이전 대체 대상인 드라이브를 결합하거나 대체하려고 했습니다.
150 0x0096 CONFIG.SYS 파일에 시스템 추적 정보가 지정되지 않았거나 추적이 허용되지 않습니다.
151 0x0097 DosMuxSemWait용으로 지정한 신호기 사건의 개수가 올바르지 않습니다.
152 0x0098 DosMuxSemWait가 실행되지 않았습니다. 너무 많은 신호기가 이미 설정되었습니다.
153 0x0099 DosMuxSemWait 목록이 올바르지 않습니다.
154 0x009A 입력한 디스크 이름이 대상 파일 시스템의 이름 한계를 넘었습니다.
155 0x009B 다른 스레드를 작성할 수 없습니다.
156 0x009C 수신측 프로세스에서 신호를 거부했습니다.
157 0x009D 세그먼트가 이미 삭제되었거나 잠글 수 없습니다.
158 0x009E 세그먼트가 이미 잠금이 해제되었습니다.
159 0x009F 스레드 ID의 주소가 올바르지 않습니다.
160 0x00A0 DosExecPgm에 전달된 인수 문자열이 올바르지 않습니다.
161 0x00A1 지정한 경로가 올바르지 않습니다.
162 0x00A2 신호가 이미 대기 중입니다.
164 0x00A4 시스템에서 더 이상의 스레드를 작성할 수 없습니다.
167 0x00A7 파일의 영역을 잠글 수 없습니다.
170 0x00AA 요청한 리소스가 사용 중입니다.
173 0x00AD 잠금 요청이 제공된 취소 영역에서 두드러지지 않습니다.
174 0x00AE 파일 시스템에서 잠금 유형의 자동 변경을 지원하지 않습니다.
180 0x00B4 올바르지 않은 세그먼트 번호가 검색되었습니다.
182 0x00B6 운영 체제에서 ? 프로그램을 실행할 수 없습니다.
183 0x00B7 그 파일이 이미 존재하면 파일을 작성할 수 없습니다.
186 0x00BA 전달된 플래그가 올바르지 않습니다.
187 0x00BB 지정한 시스템 신호기 이름을 찾을 수 없습니다.
188 0x00BC 운영 체제에서 ? 프로그램을 실행할 수 없습니다.
189 0x00BD 운영 체제에서 ? 프로그램을 실행할 수 없습니다.
190 0x00BE 운영 체제에서 ? 프로그램을 실행할 수 없습니다.
191 0x00BF Win32 모드에서 ? 프로그램을 실행할 수 없습니다.
192 0x00C0 운영 체제에서 ? 프로그램을 실행할 수 없습니다.
193 0x00C1 ?은 올바른 Win32 응용 프로그램이 아닙니다.
194 0x00C2 운영 체제에서 ? 프로그램을 실행할 수 없습니다.
195 0x00C3 운영 체제에서 ? 프로그램을 실행할 수 없습니다.
196 0x00C4 운영 체제에서 이 응용 프로그램을 실행할 수 없습니다.
197 0x00C5 운영 체제가 현재 이 응용 프로그램을 실행하도록 구성되어 있지 않습니다.
198 0x00C6 운영 체제에서 ? 프로그램을 실행할 수 없습니다.
199 0x00C7 운영 체제에서 이 응용 프로그램을 실행할 수 없습니다.
200 0x00C8 코드 세그먼트가 64KB 이상일 수 없습니다.
201 0x00C9 운영 체제에서 ? 프로그램을 실행할 수 없습니다.
202 0x00CA 운영 체제에서 ? 프로그램을 실행할 수 없습니다.
203 0x00CB 입력한 환경 옵션을 찾을 수 없습니다.
205 0x00CD 명령 하위 트리에 신호 핸들러를 갖고 있는 프로세스가 없습니다.
206 0x00CE 파일 이름이나 확장명이 너무 깁니다.
207 0x00CF 링 2 스택이 사용 중입니다.
208 0x00D0 전역 파일 이름 문자, * 또는 ?가 잘못 입력되었거나 너무 많은 전역 파일 이름 문자가 지정되었습니다.
209 0x00D1 통지된 신호가 올바르지 않습니다.
210 0x00D2 신호 핸들러를 설정할 수 없습니다.
212 0x00D4 세그먼트가 잠겼으므로 다시 할당할 수 없습니다.
214 0x00D6 이 프로그램이나 동적 연결 모듈에 너무 많은 동적 연결 모듈이 부착되었습니다.
215 0x00D7 LoadModule로의 호출을 중첩할 수 없습니다.
230 0x00E6 파이프 상태가 올바르지 않습니다.
231 0x00E7 모든 파이프 인스턴스가 사용 중입니다.
232 0x00E8 파이프를 닫고 있습니다.
233 0x00E9 파이프의 다른 쪽 끝에 프로세스가 없습니다.
234 0x00EA 사용 가능한 데이터가 더 있습니다.
240 0x00F0 세션이 취소되었습니다.
254 0x00FE 지정한 확장된 속성 이름이 올바르지 않습니다.
255 0x00FF 확장된 속성에 일관성이 없습니다.
259 0x0103 사용 가능한 데이터가 더 이상 없습니다.
266 0x010A 복사 API를 사용할 수 없습니다.
267 0x010B 디렉터리 이름이 올바르지 않습니다.
275 0x0113 확장된 속성이 버퍼에 맞지 않습니다.
276 0x0114 탑재된 파일 시스템의 확장된 속성 파일이 손상되었습니다.
277 0x0115 확장된 속성표 파일이 가득 찼습니다.
278 0x0116 지정한 확장 속성 핸들이 올바르지 않습니다.
282 0x011A 탑재된 파일 시스템에서 확장된 속성을 지원하지 않습니다.
288 0x0120 호출자가 소유하지 않는 mutex를 해제하려고 했습니다.
298 0x012A 신호기에 너무 많이 통지했습니다.
299 0x012B Read/WriteProcessMemory 요청의 일부만 완료되었습니다.
317 0x013D ?용 메시지 파일에서 메시지 번호 0x?의 메시지를 찾을 수 없습니다.
487 0x01E7 잘못된 주소를 액세스하려고 했습니다.
534 0x0216 계산 결과가 32비트를 초과했습니다.
535 0x0217 파이프의 다른 쪽 끝에 프로세스가 있습니다.
536 0x0218 프로세스에서 파이프의 다른 쪽 끝을 열기를 기다리는 중입니다.
994 0x03E2 확장된 속성의 액세스가 거부되었습니다.
995 0x03E3 스레드 종료나 응용 프로그램 요청때문에 I/O 연산이 취소되었습니다.
996 0x03E4 중복된 I/O 사건에 대해 신호가 없습니다.
997 0x03E5 중복된 I/O 연산이 진행 중입니다.
998 0x03E6 메모리 위치의 액세스가 올바르지 않습니다.
999 0x03E7 Inpage 연산을 수행하는 중에 오류가 발생했습니다.
1001 0x03E9 되돌이 수준이 너무 깊어서 스택 오버플로가 발생했습니다.
1002 0x03EA 전송된 메시지에 대한 작업을 창에서 할 수 없습니다.
1003 0x03EB 이 함수를 완료할 수 없습니다.
1004 0x03EC 잘못된 플래그입니다.
1005 0x03ED 볼륨에 인식된 파일 시스템이 없습니다. 모든 필요한 파일 시스템 드라이버를 로드하였고
볼륨이 손상되지 않았는지 확인해 주십시오.
1006 0x03EE 파일의 볼륨이 표면상 변경되었으므로 열려진 파일은 더 이상 유효하지 않습니다
1007 0x03EF 전체 화면 모드에서 요청한 작업을 수행할 수 없습니다.
1008 0x03F0 존재하지 않는 토큰을 참조하려고 했습니다.
1009 0x03F1 구성 레지스트리 데이터베이스가 손상되었습니다.
1010 0x03F2 구성 레지스트리 키가 올바르지 않습니다.
1011 0x03F3 구성 레지스트리 키를 열 수 없습니다.
1012 0x03F4 구성 레지스트리 키를 읽을 수 없습니다.
1013 0x03F5 구성 레지스트리 키에 쓸 수 없습니다.
1014 0x03F6 레지스트리 데이터베이스의 파일 중 하나를 기록 또는 선택 복사를 사용하여 회복해야 할 경우였습니다. 회복이 완료되었습니다.
1015 0x03F7 레지스트리가 손상되었습니다.
레지스트리 데이터를 포함하는 파일 중 하나의 구조가 손상되었거나 메모리에 있는 파일의 시스템
이미지가 손상되었거나, 사본이나 로그 파일이 없거나 손상된 이유로 파일을 복구할 수 없습니다.
1016 0x03F8 레지스트리에서 초기화된 I/O 작업에 복구 불가능한 오류가 발생했습니다.
레지스트리의 시스템 이미지를 포함하는 파일 중의 하나를 읽거나 쓰거나 내용을 지우는 것이
불가능합니다.
1017 0x03F9 파일을 레지스트리로 로드하거나 복구하려고 했으나 지정한 파일이 레지스트리 파일 형식이 아닙니다.
1018 0x03FA 삭제 표시가 된 레지스트리 키에서 잘못된 연산을 하려고 했습니다.
1019 0x03FB 레지스트리 기록에 필요한 공간을 할당할 수 없습니다.
1020 0x03FC 이미 서브키나 값을 갖고 있는 레지스트리 키에 기호 연결을 작성할 수 없습니다.
1021 0x03FD 소멸성 상위 키 하에서 안정된 서브키를 작성할 수 없습니다.
1022 0x03FE 통지 변경 요청이 수행 중이며 그 정보가 호출자의 버퍼에 반환되지 않았습니다.
호출자는 지금 변경 사항을 알기 위해 파일을 이뉴머레이트할 필요가 있습니다.
1051 0x041B 정지 컨트롤이 다른 실행 중인 서비스가 의존하는 서비스로 전송되었습니다.
1052 0x041C 요청한 컨트롤이 이 서비스에 유효하지 않습니다.
1053 0x041D 서비스가 시작이나 컨트롤 요청에 적시에 반응하지 못했습니다.
1054 0x041E 서비스용으로 스레드를 작성할 수 없습니다.
1055 0x041F 서비스 데이터베이스가 잠겼습니다.
1056 0x0420 서비스의 인스턴스가 이미 실행 중입니다.
1057 0x0421 계정 이름이 올바르지 않거나 존재하지 않습니다.
1058 0x0422 지정한 서비스가 실행 불능 상태이거나 시작할 수 없습니다.
1059 0x0423 원형 서비스 종속성이 지정되었습니다.
1060 0x0424 지정한 서비스가 설치되어 있지 않습니다.
1061 0x0425 지금 서비스에서 컨트롤 메시지를 받아들일 수 없습니다.
1062 0x0426 서비스가 시작되지 않았습니다.
1063 0x0427 서비스 프로세스를 서비스 컨트롤러에 연결할 수 없습니다.
1064 0x0428 서비스에서 컨트롤 요청을 처리할 때 오류가 발생했습니다.
1065 0x0429 지정한 데이터베이스가 존재하지 않습니다.
1066 0x042A 서비스에서 서비스 고유의 오류 코드를 돌려주었습니다.
1067 0x042B 프로세스가 예기치 않게 종료되었습니다.
1068 0x042C 종속성 서비스나 그룹을 시작할 수 없습니다.
1069 0x042D 로그온할 수 없으므로 서비스를 시작할 수 없습니다.
1070 0x042E 시작한 후 서비스가 시작 대기 상태에 걸려 있습니다.
1071 0x042F 지정한 서비스 데이터베이스 잠금이 올바르지 않습니다.
1072 0x0430 지정한 서비스가 삭제 표시되었습니다.
1073 0x0431 지정한 서비스가 이미 존재합니다.
1074 0x0432 시스템이 현재 가장 좋은 시스템 구성으로 실행 중입니다.
1075 0x0433 종속성 서비스가 존재하지 않거나 삭제 표시되었습니다.
1076 0x0434 현재 시동은 `마지막으로 인식된 양호한 컨트롤 세트`로 사용하도록 받아들여졌습니다.
1077 0x0435 지난 시동 이후로 서비스를 시작하려는 시도가 없었습니다.
1078 0x0436 그 이름이 서비스 이름이나 서비스 디스플레이 이름으로 이미 사용 중입니다.
1100 0x044C 테이프의 실제 끝에 도달했습니다.
1101 0x044D 테이프 액세스가 파일 표시에 도달했습니다.
1102 0x044E 테이프의 앞부분이나 분할 영역에 도달했습니다.
1103 0x044F 테이프 액세스가 파일 세트의 끝에 도달했습니다.
1104 0x0450 테이프에 더 이상의 데이터가 없습니다.
1105 0x0451 테이프를 분할할 수 없습니다.
1106 0x0452 다중 볼륨 분할 영역을 가진 새 테이프에 액세스할 때 현재 블록 크기가 올바르지 않습니다.
1107 0x0453 테이프를 로드할 때 테이프 분할 영역 정보를 찾을 수 없습니다.
1108 0x0454 매체를 꺼내는 메카니즘을 잠글 수 없습니다.
1109 0x0455 매체의 적재를 해제할 수 없습니다.
1110 0x0456 드라이브의 매체가 변경되었을지도 모릅니다.
1111 0x0457 I/O 버스가 재설정되었습니다.
1112 0x0458 드라이브에 매체가 없습니다.
1113 0x0459 대상 멀티바이트 코드페이지에 Unicode 문자의 매핑이 없습니다.
1114 0x045A 동적 연결 라이브러리 (DLL) 초기화 루틴이 실패했습니다.
1115 0x045B 시스템 종료 중입니다.
1116 0x045C 시스템 종료 중이 아니므로 시스템 종료를 취소할 수 없습니다.
1117 0x045D I/O 장치 오류때문에 요청을 처리할 수 없습니다.
1118 0x045E 초기화가 완료된 직렬 장치가 없습니다. 직렬 드라이버의 로드가 해제됩니다.
1119 0x045F 다른 장치들과 인터럽트 요청(IRQ)을 공유 중이던 장치를 열 수 없습니다.
그 IRQ를 사용하는 다른 장치가 이미 하나 이상 열려 있습니다.
1120 0x0460 직렬 포트에 씀으로써 직렬 I/O 연산이 완료되었습니다.
(IOCTL_SERIAL_XOFF_COUNTER이 0에 도달했습니다.)
1121 0x0461 시간 초과 기간이 만료되어 직렬 I/O 연산이 완료되었습니다.
(IOCTL_SERIAL_XOFF_COUNTER이 0에 도달하지 않았습니다.)
1122 0x0462 플로피 디스크에서 ID 주소 표시를 찾을 수 없습니다.
1123 0x0463 플로피 섹터 ID 필드와 플로피 디스크 컨트롤러 트랙 주소가 일치하지 않습니다.
1124 0x0464 플로피 디스크 드라이버가 플로피 디스크 컨트롤러를 인식하지 못하는 오류가 보고되었습니다.
1125 0x0465 플로피 디스크 컨트롤러가 레지스터에 일관성이 없는 결과값을 돌려주었습니다.
1126 0x0466 하드디스크를 액세스하는 동안 위치 재조정 작업이 여러 번의 재시도에도 불구하고 실패하였습니다.
1127 0x0467 하드디스크를 액세스하는 동안 디스크 연산이 여러 번의 재시도에도 불구하고 실패하였습니다.
1128 0x0468 하드디스크를 액세스하는 동안 디스크 컨트롤러 재설정이 필요하였으나 실패하였습니다.
1129 0x0469 테이프의 실제 끝에 도달했습니다.
1130 0x046A 이 명령을 처리하는데 사용할 서버 저장 공간이 부족합니다.
1131 0x046B 잠재적 교착 조건이 검색되었습니다.
1132 0x046C 기본 주소나 지정된 파일 오프셋의 맞춤이 올바르지 않습니다.
1140 0x0474 다른 응용 프로그램이나 드라이버에서 시스템 전원 상태를 변경하지 못하게 했습니니다.
1141 0x0475 시스템 BIOS로 시스템 전원 상태를 변경하려고 했으나 실패했습니다.
1150 0x047E 지정한 프로그램에 새 버전의 Windows가 필요합니다.
1151 0x047F 지정한 프로그램이 Windows 또는 MS-DOS용 프로그램이 아닙니다.
1152 0x0480 지정한 프로그램의 인스턴스를 하나 이상 실행할 수 없습니다.
1153 0x0481 지정한 프로그램이 구 버전의 Windows에서 작성되었습니다.
1154 0x0482 이 응용 프로그램을 실행하는데 필요한 라이브러리 파일 중의 하나가 손상되었습니다.
1155 0x0483 지정한 파일로 이 작업을 할 수 있도록 연결된 프로그램이 없습니다.
1156 0x0484 응용 프로그램에 명령을 보내는 동안 오류가 발생했습니다.
1157 0x0485 이 응용 프로그램을 실행하는데 필요한 라이브러리 파일 중의 하나를 찾을 수 없습니다.
1200 0x04B0 지정한 장치 이름이 올바르지 않습니다.
1201 0x04B1 장치가 현재 연결되어 있지 않지만 연결을 기억하고 있습니다.
1202 0x04B2 이전에 기억된 적이 있는 장치를 기억하려고 했습니다.
1203 0x04B3 네트워크 공급자에서 네트워크 경로를 알 수 없습니다.
1204 0x04B4 지정한 네트워크 공급자 이름이 올바르지 않습니다.
1205 0x04B5 네트워크 연결 초기화 파일을 열 수 없습니다.
1206 0x04B6 네트워크 연결 초기화 파일이 손상되었습니다.
1207 0x04B7 컨테이너가 아닌 것을 이뉴머레이트할 수 없습니다.
1208 0x04B8 확장 오류가 발생했습니다.
1209 0x04B9 지정한 그룹 이름의 형식이 올바르지 않습니다.
1210 0x04BA 지정한 컴퓨터 이름의 형식이 올바르지 않습니다.
1211 0x04BB 지정한 사건 이름의 형식이 올바르지 않습니다.
1212 0x04BC 지정한 도메인 이름의 형식이 올바르지 않습니다.
1213 0x04BD 지정한 서비스 이름의 형식이 올바르지 않습니다.
1214 0x04BE 지정한 네트워크 이름의 형식이 올바르지 않습니다.
1215 0x04BF 지정한 공유 이름의 형식이 올바르지 않습니다.
1216 0x04C0 지정한 암호의 형식이 올바르지 않습니다.
1217 0x04C1 지정한 메시지 이름의 형식이 올바르지 않습니다.
1218 0x04C2 지정한 메시지 대상의 형식이 올바르지 않습니다.
1219 0x04C3 신용장이 기존의 신용장들과 충돌을 일으킵니다.
1220 0x04C4 네트워크 서버에 세션을 설정하려고 했으나 이미 그 서버에 너무 많은 세션이 설정되어 있습니다.
1221 0x04C5 워크그룹 또는 도메인 이름이 이미 네트워크상의 다른 컴퓨터에서 사용중입니다.
1222 0x04C6 네트워크가 없거나 시작되지 않았습니다.
1223 0x04C7 사용자가 작업을 취소했습니다.
1224 0x04C8 사용자 매핑 섹션이 열려 있는 파일에서 요청한 작업을 수행할 수 없습니다.
1225 0x04C9 원격 시스템에서 네트워크 연결을 거부했습니다.
1226 0x04CA 네트워크 연결이 닫혔습니다.
1227 0x04CB 네트워크 전송 끝점이 이미 그것과 연결된 주소를 갖고 있습니다.
1228 0x04CC 주소가 아직 네트워크 끝점과 연결되지 않았습니다.
1229 0x04CD 존재하지 않는 네트워크 연결에서 작업이 시도되었습니다.
1230 0x04CE 활성 네트워크 연결에서 잘못된 작업이 시도되었습니다.
1231 0x04CF 원격 네트워크에 전송할 수 없습니다.
1232 0x04D0 원격 시스템에 전송할 수 없습니다.
1233 0x04D1 원격 시스템에서 전송 프로토콜을 지원하지 않습니다.
1234 0x04D2 원격 시스템의 대상 네트워크 끝점에 실행중인 서비스가 없습니다.
1235 0x04D3 요청이 취소되었습니다.
1236 0x04D4 네트워크 연결이 지역 시스템에서 취소되었습니다.
1237 0x04D5 작업을 완료할 수 없습니다. 재시도하십시오.
1238 0x04D6 이 계정에 동시에 연결할 수 있는 개수의 한계를 초과했으므로 서버에 더 연결할 수 없습니다
1239 0x04D7 허용되지 않는 시간에 이 계정에 로그인 하려고 했습니다.
1240 0x04D8 이 국에서 그 계정에 로그인할 수 없습니다.
1241 0x04D9 네트워크 주소를 요청한 작업에 사용할 수 없습니다.
1242 0x04DA 서비스가 이미 등록되었습니다.
1243 0x04DB 지정한 서비스가 존재하지 않습니다.
1244 0x04DC 사용자에게 권한이 없으므로 요청한 작업을 수행할 수 없습니다.
1245 0x04DD 사용자가 네트워크에 로그온하지 않았으므로 요청한 작업을 할 수 없습니다. 지정한 서비스가 존재하지 않습니다.
1246 0x04DE 처리중인 작업을 계속하기 위해 호출기를 필요로 하는 것을 되돌립니다.
1247 0x04DF 초기화가 이미 완료되었을 때 초기화 작업을 수행하려고 했습니다.
1248 0x04E0 지역 장치가 더 이상 없습니다.
1300 0x0514 참조되는 모든 특권이 호출자에게 지정되어 있지는 않습니다.
1301 0x0515 계정 이름과 시스템 보안 ID간의 일부 매핑이 완료되지 않았습니다.
1302 0x0516 이 계정에 특정하게 설정되어 있는 시스템 할당량 제한이 없습니다.
1303 0x0517 사용 가능한 암호화 키가 없습니다. 잘 알려진 암호화 키가 리턴되었습니다.
1304 0x0518 NT 암호가 너무 복잡하여 LAN Manager 암호로 변환할 수 없습니다.
리턴된 LAN Manager 암호가 NULL 문자열입니다.
1305 0x0519 수정 수준을 알 수 없습니다.
1306 0x051A 두 수정 수준이 호환되지 않습니다.
1307 0x051B 이 시스템 보안 ID가 이 개체의 소유자로서 지정되지 않을지도 모릅니다.
1308 0x051C 이 시스템 보안 ID가 개체의 주 그룹으로서 지정되지 않을지도 모릅니다.
1309 0x051D 현재 클라이언트를 의인화하고 있지 않은 스레드를 이용하여 의인화 토큰 방식으로 작업하려고 했습니다.
1310 0x051E 그룹을 사용할 수 없을지도 모릅니다.
1311 0x051F 로그온 요청을 처리하는 데 사용할 수 있는 로그온 서버가 현재 없습니다.
1312 0x0520 지정한 로그온 세션이 존재하지 않습니다. 이미 종료되었을지도 모릅니다.
1313 0x0521 지정한 특권이 존재하지 않습니다.
1314 0x0522 요청한 특권을 클라이언트가 갖고 있지 않습니다.
1315 0x0523 제공한 이름이 올바르게 형성된 계정 이름이 아닙니다.
1316 0x0524 지정한 사용자가 이미 존재합니다.
1317 0x0525 지정한 사용자가 존재하지 않습니다.
1318 0x0526 지정한 그룹이 이미 존재합니다.
1319 0x0527 지정한 그룹이 존재하지 않습니다.
1320 0x0528 지정한 사용자 계정이 이미 지정한 그룹의 구성원이거나, 지정한 그룹에 구성원이 있어서
삭제할 수 없습니다.
1321 0x0529 지정한 사용자 계정이 지정한 그룹 계정의 구성원이 아닙니다.
1322 0x052A 마지막 남은 관리 계정을 사용 불능 상태로 하거나 삭제할 수 없습니다.
1323 0x052B 암호를 업데이트할 수 없습니다. 현재 암호로 제공된 값이 올바르지 않습니다.
1324 0x052C 암호를 업데이트할 수 없습니다. 새 암호로 제공된 값이 암호에 사용할 수 없는 문자를 포함합니다.
1325 0x052D 암호 업데이트 규칙을 위반했으므로 암호를 업데이트할 수 없습니다.
1326 0x052E 로그온할 수 없음: 사용자 이름을 알 수 없거나 암호가 틀립니다.
1327 0x052F 로그온할 수 없음: 사용자 계정 한계.
1328 0x0530 로그온할 수 없음: 계정 로그온 시간 한계 위반
1329 0x0531 로그온할 수 없음: 이 컴퓨터에 로그온할 수 없는 사용자입니다.
1330 0x0532 로그온할 수 없음: 지정한 계정 암호 사용 기간이 만료되었습니다.
1331 0x0533 로그온할 수 없음: 계정이 현재 사용할 수 없는 상태입니다.
1332 0x0534 계정 이름과 시스템 보안 ID간에 매핑이 되지 않았습니다.
1333 0x0535 한번에 너무 많은 지역 사용자 식별자(LUID)를 요청했습니다.
1334 0x0536 사용 가능한 지역 사용자 식별자(LUID)가 더 이상 없습니다.
1335 0x0537 시스템 보안 ID의 부인증 부분이 이 특별 사용에 적합하지 않습니다.
1336 0x0538 액세스 컨트롤 목록(ACL) 구조가 올바르지 않습니다.
1337 0x0539 시스템 보안 ID 구조가 올바르지 않습니다.
1338 0x053A 시스템 보안 기술자 구조가 올바르지 않습니다.
1340 0x053C 상속된 액세스 컨트롤 목록(ACL)이나 액세스 컨트롤 항목(ACE)를 작성할 수 없습니다.
1341 0x053D 서버가 현재 사용불능 상태입니다.
1342 0x053E 서버가 현재 사용가능 상태입니다.
1343 0x053F 제공된 값이 식별자 인증에 부적합합니다.
1344 0x0540 시스템 보안 정보의 업데이트에 필요한 메모리가 더 이상 없습니다.
1345 0x0541 지정한 속성이 올바르지 않거나 전체적으로 그룹의 속성과 호환되지 않습니다.
1346 0x0542 의인화 수준이 올바르지 않거나 제공한 내용이 올바르지 않습니다.
1347 0x0543 익명 수준의 시스템 보안 토큰을 열 수 없습니다.
1348 0x0544 요청한 확인 정보 클래스가 올바르지 않습니다.
1349 0x0545 토큰의 종류가 사용 목적에 부적합합니다.
1350 0x0546 연결된 시스템 보안이 없는 개체에서 시스템 보안 작업을 수행할 수 없습니다.
1351 0x0547 Windows NT 서버에 연락할 수 없거나 도메인 내의 개체가 필요한 정보를 검색당하지 않도록
보호되고 있습니다.
1352 0x0548 시스템 보안 계정 관리자(SAM)나 지역 시스템 보안 권한(LSA) 서버가 시스템 보안 작업을 수행하기에
부적절한 상태에 있습니다.
1353 0x0549 시스템 보안 작업을 수행하기에 도메인의 상태가 부적절합니다.
1354 0x054A 이 작업은 도메인의 주 도메인 컨트롤러에서만 할 수 있습니다.
1355 0x054B 지정한 도메인이 존재하지 않습니다.
1356 0x054C 지정한 도메인이 이미 존재합니다.
1357 0x054D 서버 당 도메인 수의 한계를 초과하려고 했습니다.
1358 0x054E 심각한 매체 오류나 디스크상의 데이터 구조 손상때문에 요청한 작업을 완료할 수 없습니다.
1359 0x054F 시스템 보안 계정 데이터베이스에 내부적인 불일치가 있습니다.
1360 0x0550 일반 액세스 종류가 이미 비일반 종류에 매핑되어야 하는 액세스 마스크에 포함되어 있습니다.
1361 0x0551 시스템 보안 기술자의 형식이 올바르지 않습니다(절대적 또는 자기 상대적).
1362 0x0552 요청한 작업을 로그온 과정에서만 수행할 수 있습니다.
호출 과정이 로그온 과정으로 등록되지 않았습니다.
1363 0x0553 이미 사용중인 ID로 새 로그온 세션을 시작할 수 없습니다.
1364 0x0554 지정한 인증 패키지를 알 수 없습니다.
1365 0x0555 로그온 세션이 요청한 작업과 일치하는 상태에 있지 않습니다.
1366 0x0556 로그온 세션 ID가 이미 사용 중입니다.
1367 0x0557 로그온 요청에 잘못된 로그온 유형 값이 있습니다.
1368 0x0558 파이프에서 데이터를 읽기 전까지 이름 파이프를 통해 의인화가 불가능합니다.
1369 0x0559 레지스트리 하위 트리의 트랜잭션 상태가 요청한 작업과 호환되지 않습니다.
1370 0x055A 내부 시스템 보안 데이터베이스가 손상되었습니다.
1371 0x055B 제공된 계정에서 이 작업을 수행할 수 없습니다.
1372 0x055C 제공된 특별 그룹에서 이 작업을 수행할 수 없습니다.
1373 0x055D 제공된 특별 사용자에서 이 작업을 수행할 수 없습니다.
1374 0x055E 그룹이 현재 사용자의 주 그룹이므로 그룹에서 사용자를 제거할 수 없습니다.
1375 0x055F 기본 토큰에서 이미 이 토큰을 사용 중입니다.
1376 0x0560 지정한 지역 그룹이 존재하지 않습니다.
1377 0x0561 지정한 계정 이름이 지역 그룹의 구성원이 아닙니다.
1378 0x0562 지정한 계정 이름이 이미 지역 그룹의 구성원입니다.
1379 0x0563 지정한 지역 그룹이 이미 존재합니다.
1380 0x0564 로그온할 수 없음: 사용자가 이 컴퓨터에서 요청한 로그온 유형을 받지 못했습니다.
1381 0x0565 단일 시스템에 저장할 수 있는 기밀의 최대 개수를 초과했습니다.
1382 0x0566 기밀의 길이가 허용되는 최대 길이를 초과했습니다.
1383 0x0567 지역 시스템 보안 권한 데이터베이스에 내부 불일치가 있습니다.
1384 0x0568 로그온하려는 동안 사용자의 시스템 보안 환경에 너무 많은 시스템 보안 ID가 쌓였습니다.
1385 0x0569 로그온할 수 없음: 사용자가 이 컴퓨터에서 요청한 로그온 종류를 받지 못했습니다.
1386 0x056A 사용자 암호를 변경하는데 교차 암호화된 암호가 필요합니다.
1387 0x056B 구성원이 존재하지 않으므로 새 구성원을 지역 그룹에 없습니다.
1388 0x056C 구성원이 잘못된 계정 종류를 가지므로 지역 그룹에 추가할 수 없습니다.
1389 0x056D 너무 많은 시스템 보안 ID가 지정되었습니다.
1390 0x056E 이 사용자 암호를 변경하려면 교차 암호화된 암호가 필요합니다.
1391 0x056F ACL에 상속 가능한 구성요소가 없습니다.
1392 0x0570 파일이나 디렉터리가 손상되었으므로 읽을 수 없습니다.
1393 0x0571 디스크 구조가 손상되었으므로 읽을 수 없습니다.
1394 0x0572 지정한 로그온 세션에 사용자 세션 키가 없습니다.
1395 0x0573 액세스 중인 서비스는 특정 수의 연결에만 사용할 수 있습니다.
서비스에서 허용하는 연결 수에 이미 도달했으므로 더 이상 연결할 수 없습니다.
1400 0x0578 잘못된 창 핸들입니다.
1401 0x0579 잘못된 메뉴 핸들입니다.
1402 0x057A 잘못된 커서 핸들입니다.
1403 0x057B 잘못된 바로 가는 키 표 핸들입니다.
1404 0x057C 잘못된 후크 핸들입니다.
1405 0x057D 다중 창 위치 구조에 부적합한 핸들입니다.
1406 0x057E 최상위 수준의 하위 창을 작성할 수 없습니다.
1407 0x057F 창 클래스를 찾을 수 없습니다.
1408 0x0580 다른 스레드에 속한 잘못된 창입니다.
1409 0x0581 바로 가는 키가 이미 등록되었습니다.
1410 0x0582 이미 존재하는 클래스입니다.
1411 0x0583 존재하지 않는 클래스입니다.
1412 0x0584 클래스에 여전이 열려 있는 창이 있습니다.
1413 0x0585 잘못된 색인입니다.
1414 0x0586 잘못된 아이콘 핸들입니다.
1415 0x0587 개인 DIALOG 창 단어를 이용 중입니다.
1416 0x0588 목록 식별자를 찾을 수 없습니다.
1417 0x0589 대표 문자를 찾을 수 없습니다.
1418 0x058A 스레드에 열려 있는 클립보드가 없습니다.
1419 0x058B 바로 가는 키가 등록되어 있지 않습니다.
1420 0x058C 올바른 대화 창이 아닙니다.
1421 0x058D 컨트롤 ID를 찾을 수 없습니다.
1422 0x058E 편집 컨트롤 기능이 없으므로 명령 실행 상자에 부적절한 메시지입니다.
1423 0x058F 창이 명령 실행 상자가 아닙니다.
1424 0x0590 높이가 256보다 작아야 합니다.
1425 0x0591 잘못된 장치 환경 (DC) 핸들입니다.
1426 0x0592 잘못된 후크 프로시저 종류입니다.
1427 0x0593 잘못된 후크 프로시져입니다.
1428 0x0594 모듈 핸들 없이 지역 후크가 아닌 후크를 설정할 수 없습니다.
1429 0x0595 이 후크 프로시저는 전역으로만 설정가능합니다.
1430 0x0596 저널 후크 프로시저가 이미 설치되었습니다.
1431 0x0597 후크 프로시저가 설치되어 있지 않습니다.
1432 0x0598 단일 선택 목록에 부적합한 메시지입니다.
1433 0x0599 LB_SETCOUNT가 비지연 목록에 전송되었습니다.
1434 0x059A 이 목록에서는 탭 정지를 지원하지 않습니다.
1435 0x059B 다른 스레드에서 작성한 개체를 삭제할 수 없습니다.
1436 0x059C 하위 창에서 메뉴를 가질 수 없습니다.
1437 0x059D 창에 시스템 메뉴를 가질 수 없습니다.
1438 0x059E 잘못된 메시지 상자 유형입니다.
1439 0x059F 잘못된 시스템 범위의 (SPI_*) 매개 변수입니다.
1440 0x05A0 화면이 이미 잠겨졌습니다.
1441 0x05A1 다중 창 위치 구조에서 창의 모든 핸들은 같은 상위 핸들을 가져야 합니다.
1442 0x05A2 하위 창이 아닙니다.
1443 0x05A3 잘못된 GW_* 명령입니다.
1444 0x05A4 잘못된 스레드 식별자입니다.
1445 0x05A5 다중 문서 인터페이스(MDI) 창이 아닌 창으로부터 메시지를 처리할 수 없습니다.
1446 0x05A6 돌출 메뉴가 이미 실행중입니다.
1447 0x05A7 창에 스크롤 막대가 없습니다.
1448 0x05A8 스크롤 막대 범위는 0x7FFF보다 클 수 없습니다.
1449 0x05A9 지정한 방식으로 창을 표시하거나 제거할 수 없습니다.
1450 0x05AA 시스템 리소스가 부족하여 요청한 서비스를 완료할 수 없습니다.
1451 0x05AB 시스템 리소스가 부족하여 요청한 서비스를 완료할 수 없습니다.
1452 0x05AC 시스템 리소스가 부족하여 요청한 서비스를 완료할 수 없습니다.
1453 0x05AD 할당된 리소스가 부족하여 요청한 서비스를 완료할 수 없습니다.
1454 0x05AE 할당된 리소스가 부족하여 요청한 서비스를 완료할 수 없습니다.
1455 0x05AF 페이징 파일이 너무 작아서 이 작업을 완료할 수 없습니다.
1456 0x05B0 메뉴 항목을 찾을 수 없습니다.
1500 0x05DC 이벤트 로그 파일이 손상되었습니다.
1501 0x05DD 열 수 있는 이벤트 로그 파일이 없으므로 사건 기록 서비스를 실행할 수 없습니다.
1502 0x05DE 이벤트 로그 파일이 가득 찼습니다.
1503 0x05DF 이벤트 로그 파일이 읽는 동안 변경되었습니다.
1700 0x06A4 문자열 바인딩이 올바르지 않습니다.
1701 0x06A5 바인딩 핸들의 종류가 올바르지 않습니다.
1702 0x06A6 바인딩 핸들이 올바르지 않습니다.
1703 0x06A7 RPC 프로토콜 시퀀스가 지원되지 않습니다.
1704 0x06A8 RPC 프로토콜 시퀀스가 올바르지 않습니다.
1705 0x06A9 문자열의 범용 유일 식별자(UUID)가 올바르지 않습니다.
1706 0x06AA 끝점 형식이 올바르지 않습니다.
1707 0x06AB 네트워크 주소가 올바르지 않습니다.
1708 0x06AC 끝점을 찾을 수 없습니다.
1709 0x06AD 시간 초과 값이 올바르지 않습니다.
1710 0x06AE 개체의 범용 유일 식별자(UUID)를 찾을 수 없습니다.
1711 0x06AF 개체의 범용 유일 식별자(UUID)가 이미 등록되었습니다.
1712 0x06B0 유형의 범용 유일 식별자(UUID)가 이미 등록되었습니다.
1713 0x06B1 RPC 서버가 이미 듣고 있습니다.
1714 0x06B2 등록된 프로토콜 시퀀스가 없습니다.
1715 0x06B3 RPC 서버가 듣고 있지 않습니다.
1716 0x06B4 관리자 유형을 알 수 없습니다.
1717 0x06B5 인터페이스를 알 수 없습니다.
1718 0x06B6 바인딩이 없습니다.
1719 0x06B7 프로토콜 시퀀스가 없습니다.
1720 0x06B8 끝점을 작성할 수 없습니다.
1721 0x06B9 이 작업을 완료하는 데 사용할 리소스가 부족합니다.
1722 0x06BA RPC 서버를 사용할 수 없습니다.
1723 0x06BB RPC 서버가 너무 바빠서 이 작업을 완료할 수 없습니다.
1724 0x06BC 네트워크 옵션이 올바르지 않습니다.
1725 0x06BD 이 스레드에 활성 상태의 원격 프로시저 호출이 없습니다.
1726 0x06BE 원격 프로시저 호출을 할 수 없습니다.
1727 0x06BF 원격 프로시저 호출을 할 수 없으므로 실행되지 않았습니다.
1728 0x06C0 원격 프로시저 호출(RPC) 프로토콜 오류가 발생했습니다.
1730 0x06C2 RPC 서버에서 지원하지 않는 전송 구문입니다.
1732 0x06C4 지원되지 않는 범용 유일 식별자(UUID) 종류입니다.
1733 0x06C5 태그가 올바르지 않습니다.
1734 0x06C6 배열 한계 값이 올바르지 않습니다.
1735 0x06C7 바인딩에 항목 이름이 없습니다.
1736 0x06C8 이름 구문이 올바르지 않습니다.
1737 0x06C9 지원되지 않는 이름 구문입니다.
1739 0x06CB 범용 유일 식별자(UUID)를 작성하는 데 사용할 수 있는 네트워크 주소가 없습니다.
1740 0x06CC 끝점이 중복되었습니다.
1741 0x06CD 알 수 없는 인증 유형입니다.
1742 0x06CE 호출의 최대 횟수가 너무 작습니다.
1743 0x06CF 문자열이 너무 깁니다.
1744 0x06D0 RPC 프로토콜 시퀀스를 찾을 수 없습니다.
1745 0x06D1 프로시저 개수가 범위를 벗어났습니다.
1746 0x06D2 바인딩에 인증 정보가 없습니다.
1747 0x06D3 알 수 없는 인증 서비스입니다.
1748 0x06D4 인증 수준을 알 수 없습니다.
1749 0x06D5 시스템 보안 환경이 올바르지 않습니다.
1750 0x06D6 알 수 없는 인증 서비스입니다.
1751 0x06D7 항목이 올바르지 않습니다.
1752 0x06D8 서버의 끝점에서 작업을 수행할 수 없습니다.
1753 0x06D9 끝점 매퍼에서 사용 가능한 더 이상의 끝점이 없습니다.
1754 0x06DA 저장된 인터페이스가 없습니다.
1755 0x06DB 항목 이름이 불완전합니다.
1756 0x06DC 버전 옵션이 올바르지 않습니다.
1757 0x06DD 더 이상의 구성원이 없습니다.
1758 0x06DE 저장을 해제할 대상이 없습니다.
1759 0x06DF 인터페이스를 찾을 수 없습니다.
1760 0x06E0 항목이 이미 존재합니다.
1761 0x06E1 항목을 찾을 수 없습니다.
1762 0x06E2 이름 서비스를 사용할 수 없습니다.
1763 0x06E3 네트워크 주소 패밀리가 올바르지 않습니다.
1764 0x06E4 요청한 작업이 지원되지 않습니다.
1765 0x06E5 의인화하는데 시스템 보안 환경을 사용할 수 없습니다.
1766 0x06E6 원격 프로시저 호출(RPC)에서 내부 오류가 발생했습니다.
1767 0x06E7 RPC 서버에서 정수를 0으로 나누려고 했습니다.
1768 0x06E8 RPC 서버에서 주소 지정 오류가 발생했습니다.
1769 0x06E9 RPC 서버에서 0으로 나누는 부동 소수점 연산이 있었습니다.
1770 0x06EA RPC 서버에서 부동 소수점 언더플로가 발생했습니다.
1771 0x06EB RPC 서버에서 부동 소수점 오버플로가 발생했습니다.
1772 0x06EC 자동 핸들의 바인딩에 사용할 수 있는 RPC 서버 목록을 다 써버렸습니다.
1773 0x06ED 문자 번역표 파일을 열 수 없습니다.
1774 0x06EE 문자 번역표가 수록되어 있는 파일의 바이트 수가 512보다 적습니다.
1775 0x06EF 원격 프로시저 호출동안 클라이언트로부터 호스트로 널 컨텍스트 핸들이 전달되었습니다.
1777 0x06F1 원격 프로시저 호출동안 컨텍스트 핸들이 변경되었습니다.
1778 0x06F2 원격 프로시저 호출로 전달된 바인딩 핸들이 일치하지 않습니다.
1779 0x06F3 스터브에서 원격 프로시저 호출 핸들을 가져올 수 없습니다.
1772 0x06F4 널 참조 포인터가 스터브에 전달되었습니다.
1781 0x06F5 정리 값이 범위를 벗어났습니다.
1782 0x06F6 바이트 수가 너무 작습니다.
1783 0x06F7 스터브에 불량 데이터가 수신되었습니다.
1784 0x06F8 공급된 사용자 버퍼가 요청한 작업에 부적합합니다.
1785 0x06F9 디스크 매체를 인식할 수 없습니다. 포맷되지 않은 것같습니다.
1786 0x06FA 워크스테이션에 신뢰성 있는 기밀이 없습니다.
1787 0x06FB Windows NT Server의 SAM 데이터베이스에 이 워크스테이션의 신뢰성 있는 관계를 위한 컴퓨터
계정이 없습니다.
1788 0x06FC 주 도메인과 신뢰성 있는 도메인 간에 신뢰성 있는 관계를 설정할 수 없습니다.
1789 0x06FD 이 워크스테이션과 주 도메인 간에 신뢰성 있는 관계를 가질 수 없습니다.
1790 0x06FE 네트워크 로그인 할 수 없습니다.
1791 0x06FF 이 스레드에 대한 원격 프로시저 호출이 이미 진행주입니다.
1792 0x0700 로그온을 시도했지만 네트워크 로그온 서비스가 시작하지 않았습니다.
1793 0x0701 사용자의 계정이 만료되었습니다.
1794 0x0702 네트워크 재지정이 사용 중이므로 해제할 수 없습니다.
1795 0x0703 지정한 프린터 드라이버가 이미 설치되었습니다.
1796 0x0704 지정한 포트는 알 수 없는 포트입니다.
1797 0x0705 알려지지 않은 프린터 드라이버입니다.
1798 0x0706 인쇄 프로세서가 알 수 없는 것입니다.
1799 0x0707 지정한 분리자 파일이 잘못되었습니다.
1800 0x0708 지정한 우선순위가 잘못되었습니다.
1801 0x0709 프린터 이름이 잘못되었습니다.
1802 0x070A 프린터가 이미 존재합니다.
1803 0x070B 프린터 명령이 잘못되었습니다.
1804 0x070C 지정한 데이터 형식이 잘못되었습니다.
1805 0x070D 지정한 환경이 잘못되었습니다.
1806 0x070E 바인딩이 더 이상 없습니다.
1807 0x070F 사용된 계정이 도메인 상호 신탁 계정입니다. 전역 사용자 계정이나 지역 사용자 계정을 사용해서
서버에 액세스하십시오.
1808 0x0710 사용한 계정이 컴퓨터 계정입니다. 전역 사용자 계정이나 지역 사용자 계정을 사용하여 서버에
액세스하십시오.
1809 0x0711 사용한 계정이 서버 신탁 계정입니다. 전역 사용자 계정이나 지역 사용자 계정을 사용하여 서버에
액세스하십시오.
1810 0x0712 지정한 도메인의 이름이나 시스템 보안 ID (SID)가 해당 도메인의 신탁 정보와 일치하지 않습니다.
1811 0x0713 서버가 사용 중이며 언로드할 수 없습니다.
1812 0x0714 지정한 이미지 파일에 리소스 영역이 없습니다.
1813 0x0715 지정한 리소스 형식을 이미지 파일에서 찾을 수 없습니다.
1814 0x0716 지정한 리소스 이름을 이미지 파일에서 찾을 수 없습니다.
1815 0x0717 지정한 리소스 언어 ID를 이미지 파일에서 찾을 수 없습니다.
1816 0x0718 할당된 리소스가 부족하여 이 명령을 처리할 수 없습니다.
1817 0x0719 등록된 인터페이스가 없습니다.
1818 0x071A 호출을 처리하는 과정에서 서버가 수정되었습니다.
1819 0x071B 바인딩 핸들에 필요한 정보 중 일부가 없습니다.
1820 0x071C 통신 오류.
1821 0x071D 요청한 인증 단계가 지원되지 않습니다.
1822 0x071E 주요 이름이 등록되지 않았습니다.
1823 0x071F 지정한 오류는 올바른 Windows RPC 오류 코드가 아닙니다.
1824 0x0720 이 컴퓨터에서만 유효한 UUID가 할당되었습니다.
1825 0x0721 보안 패키지 특정 오류가 발생했습니다.
1826 0x0722 스레드가 취소되지 않았습니다.
1827 0x0723 인코딩/디코딩 핸들에서 잘못된 작동이 발생했습니다.
1828 0x0724 일련의 순차적인 패키지 중 호환되지 않는 버전입니다.
1829 0x0725 RPC 중 호환되지 않는 버전입니다.
1898 0x076A 그룹 멤버를 찾을 수 없습니다.
1899 0x076B 엔드포인트 매퍼 데이터베이스를 작성할 수 없습니다.
1900 0x076C 개체 일반 고유 식별자(UUID)에 아무런 값이 없습니다.
1901 0x076D 지정한 시간이 잘못되었습니다.
1902 0x076E 지정한 폼 이름이 잘못되었습니다.
1903 0x076F 지정한 폼 크기가 잘못되었습니다.
1904 0x0770 지정한 프린터 핸들이 이미 대기중입니다.
1905 0x0771 지정한 프린터가 삭제되었습니다.
1906 0x0772 프린터의 상태가 올바르지 않습니다.
1907 0x0773 최초로 로그온하기 전에 사용자 암호를 바꾸어야 합니다.
1908 0x0774 이 도메인에 대한 도메인 컨트롤러를 찾을 수 없습니다.
1909 0x0775 참조 계정이 현재 잠겨 있어서 로그온할 수 없습니다.
2000 0x07D0 픽셀 포맷이 올바르지 않습니다.
2001 0x07D1 지정한 드라이버가 올바르지 않습니다.
2002 0x07D2 창 모양 또는 클래스 속성이 이 작업에 올바르지 않습니다.
2003 0x07D3 요청한 메타파일 작업은 지원하지 않습니다.
2004 0x07D4 요청한 변환작업은 지원하지 않습니다.
2005 0x07D5 요청한 자르기 작업은 지원하지 않습니다.
2202 0x089A 지정한 사용자 이름이 올바르지 않습니다.
2250 0x08CA 네트워크 연결이 없습니다.
2401 0x0961 네트워크 연결에 얼려 있는 파일이 있거나 처리되지 않은 요청이 있습니다.
2402 0x0962 사용중인 연결이 아직 있습니다.
2404 0x0964 장치가 활성 프로세서에서 사용 중이며 연결 해제할 수 없습니다.
3000 0x0BB8 지정한 인쇄 모니터를 알 수 없습니다.
3001 0x0BB9 지정한 프린터 드라이버가 현재 사용중입니다.
3002 0x0BBA 스풀 파일을 찾을 수 없습니다.
3003 0x0BBB StartDocPrinter 호출이 사용되지 않았습니다.
3004 0x0BBC AddJob 호출이 사용되지 않았습니다.
3005 0x0BBD 지정한 인쇄 프로세서가 이미 설치되었습니다.
3006 0x0BBE 지정한 인쇄 모니터가 이미 설치되었습니다.
4000 0x0FA0 명령을 처리하는 동안에 WINS에서 오류가 발생했습니다.
4001 0x0FA1 지역 WINS를 삭제할 수 없습니다.
4002 0x0FA2 파일로부터 들여오기 작업이 실패했습니다.
4003 0x0FA3 백업을 실패했습니다. 이전에 전체 백업을 하셨습니까?
4004 0x0FA4 백업을 실패했습니다. 데이터베이스를 백업한 디렉터리를 확인해 보십시오.
4005 0x0FA5 WINS 데이터베이스에 이 이름이 없습니다.
4006 0x0FA6 구성되지 않은 파트너를 갖는 이중화는 사용할 수 없습니다.
6118 0x17E6 이 작업 그룹의 서버 목록을 현재 사용할 수 없습니다. 


      
Posted by k_ben


개념..(네이버에 어떤분이 이해하기 쉽게 써놨길래 퍼왔습니다..)

테이블스페이스는 데이터베이스의 물리적 스키마(테이블,인덱스)를 생성하기 위한 공간입니다. 
테이블스페이스가 생성되기 위해서는 당연히 데이터베이스가 정의되어야 하고요...
이러한 테이블스페이스가 필요로 하는 물리적 디스크 공간이 데이터파일입니다.
테이블스페이스와 데이터파일의 관계는 당연히 1:N 의 관계이고요...
당연히 테이블스페이스가 처음 생성이 될때는 데이터파일이 지정되어야 합니다.
오라클 데이터베이스같은 경우에는, 오라클 데몬 (DBWR인가...)이 다음의 프로세스를 거쳐 테이블스페이스를 생성합니다.

 1. 테이블스페이스 생성 구문 및 파라미터를 분석한다.

2. 데이터파일 경로가 파일 시스템상에 존재하는 올바른 경로인지 확인한다.

3. 데이터파일을 지정된 파일 시스템에 생성한다.

4. 파일시스템이 생성되면 테이블스페이스를 데이터 사전에 등록하고 생성한다.

테이블스페이스가 생성되면, 그 테이블스페이스를 사용할 유저를 생성합니다.
유저의 생성 구문은
create user "사용자명" identified by "암호"
default tablespace "테이블스페이스명"
temporary tablespace "임시테이블스페이스명";
입니다. 당연히 테이블스페이스가 지정이 되어 있어야 유저를 생성할 수 있습니다
(기본 테이블스페이스는 기본적으로 "시스템"테이블 스페이스입니다)

한가지 예를 들어 설명드리겠습니다.

예를 들어 "홍길동" 이 농사를 짓습니다.
농사를 지으려면 "땅"이 필요합니다.
"땅"을 구획을 지어 구별할 수 있는 이름으로 나누기 위해서는,
나라에서 지정하는 주소의 규칙을 따라서 "행정구역"으로 구분합니다.
"홍길동"이 농사를 짓기 위해 토지를 매입하려고 합니다.
나라에서는 "홍길동"이 사려는 땅이 누구의 소유인지 확인하고,
없으면 "번지"를 매겨 구획을 짓습니다.
그리고 "홍길동"은 해당 "번지" 에 대한 "등기부등본"을 받고 농사를 짓습니다.
그 다음부터는 "홍길동"은 마음대로 자신의 "농장"안에서
"콩"도 심고, "고추"도 심고, "참외"도 심습니다.
"농장"이 모자라게 되면, 추가로 "번지"를 매입하여 "농장"에 편입합니다. 
당연히 "등기부등본"에는 해당 "번지"가 "홍길동"의 "농장"임을 표시합니다.
 

"땅"은 데이터베이스,
"농장"은 테이블스페이스,
"행정구역"은 데이터파일이 들어갈 파일 시스템,
"번지"는 데이터파일,
"등기부등본"은 데이터사전,
"홍길동"은 유저,
"콩밭","고추밭","참외밭"은 테이블 개념으로 이해하시면 되겠습니다.
그럼 인덱스는요?
"콩밭"이나,"고추밭"이나,"참외밭"에서
"완두콩", "풋고추", "개구리참외"를 쉽게 찾기 위한 인식자입니다.
"고랑, 줄" 정도가 인덱스에 해당한다고 보면 되겠군요...
"완두콩은 첫번째 고랑부터 세번째 고랑까지 심었다" 면 말이죠...

----------------------------------------------------------------------------
테이블스페이스의 용량을 알아보는 쿼리문
SELECT
"Check Time"
,TS_INFO.tablespace_name
,TS_INFO."TOTAL SIZE(MB)"
,TS_INFO."USED(MB)"
,TS_INFO."AVAIL(MB)" "Tot_AVAIL(MB)"
,TO_CHAR((MAX(DFS.BYTES)/1024/1024),'999,990.999') "Act_AVAIL(MB)"  -- max Extent size on The tablespace
,TS_INFO."USED %"
,TS_INFO."FREE %"
,TS_INFO."STATUS"
FROM (
SELECT
SYSDATE "Check Time"
,tablespace_name
,sum(total_size)/1024 "TOTAL SIZE(MB)"
,TO_CHAR(round((sum(used)/1024),4),'999,990.999') "USED(MB)"
,TO_CHAR((sum(total_size)/1024)-(round((sum(used)/1024),4)),'999,990.999') "AVAIL(MB)"
,TO_CHAR(round((sum(used)/sum(total_size)),4)*100,'990.99') "USED %"
,TO_CHAR(round(1-(sum(used)/sum(total_size)),4)*100,'909.99') "FREE %"
,CASE WHEN  (round(1-(sum(used)/sum(total_size)),4)*100) <= '10' THEN ' Alert        ☜'
      WHEN  (round(1-(sum(used)/sum(total_size)),4)*100) <= '15' THEN ' Warning   ☜'
      WHEN  (round(1-(sum(used)/sum(total_size)),4)*100) <= '30' THEN ' Normal     △'
      ELSE ' Good        ◎' END "STATUS"
FROM (
SELECT
                  b.tablespace_name , -- tablespace Name
                  b.bytes / 1024 total_size, -- 총 Bytes
                  ((b.bytes - sum(nvl(a.bytes,0)))) / 1024 used, -- 사용한 용량
                  (sum(nvl(a.bytes,0))) / 1024 free_size -- 남은 용량
                  FROM DBA_FREE_SPACE a, DBA_DATA_FILES b
WHERE a.file_id(+) = b.file_id
and
b.tablespace_name in (select tablespace_name from dba_tablespaces)
                  GROUP BY b.tablespace_name, b.file_name, b.bytes

)
GROUP BY tablespace_name
) TS_INFO,
DBA_FREE_SPACE DFS

WHERE TS_INFO.TABLESPACE_NAME = DFS.TABLESPACE_NAME
GROUP BY TS_INFO.tablespace_name,"TOTAL SIZE(MB)","USED(MB)","AVAIL(MB)","USED %","FREE %","STATUS","Check Time"
ORDER BY "FREE %"; 

 
<데이타 파일별 용량 확인 쿼리> 

SELECT            SYSDATE "Check Time",
                  b.file_name "FILE_NAME", -- DataFile Name
                  b.tablespace_name "TABLESPACE_NAME", -- tablespace Name
                  TO_CHAR((b.bytes / 1024),'999,990,999') "TOTAL SIZE(KB)", -- 총 Bytes
                  TO_CHAR((((b.bytes - sum(nvl(a.bytes,0)))) / 1024),'999,990,999') "USED(KB)", -- 사용한 용량
                  TO_CHAR(((sum(nvl(a.bytes,0))) / 1024),'999,990,999') "FREE SIZE(KB)", -- 남은 용량
                  TRUNC(((sum(nvl(a.bytes,0)) / (b.bytes)) * 100),2) "FREE %" -- 남은 %
                  FROM DBA_FREE_SPACE a, DBA_DATA_FILES b
WHERE a.file_id(+) = b.file_id
-- and b.tablespace_name = UPPER('&TS_name') -- 테이블 스페이스별로 보고싶을때 주석지우고 사용
                  GROUP BY b.tablespace_name, b.file_name, b.bytes
ORDER BY b.tablespace_name;
-----------------------------------------------------------------------
1. 해당 데이터파일의 크기를 재조정
ALTER DATABASE DATAFILE 'D:\ORACLE\ORADATA\KIRIO1\A1_CLON\A1.DBF'
RESIZE 1100M;


2. 해당 테이블 스페이스에 새로운 데이터파일 추가
ALTER TABLESPACE DATA ADD DATAFILE 'd:\oracle\oradata\kirio1\data01.dbf'
SIZE 100M;


3. 해당 데이터파일에 AUTOEXTEND ON 설정
ALTER DATABASE DATAFILE 'D:\ORACLE\ORADATA\KIRIO1\A1_CLON\A1.DBF'
AUTOEXTEND ON;

'컴퓨터 > DB' 카테고리의 다른 글

오라클 오류메시지  (0) 2009.01.15
데이터베이스 스키마  (0) 2009.01.15
오라클 초보자를 위한 팁  (0) 2009.01.15
오라클 힌트  (0) 2009.01.14
오라클에서 not exists, not in, minus의 성능차이  (0) 2009.01.13
      
Posted by k_ben


◈ TABLE 구조 보기

SQL>DESC TABLE_NAME
 

◈ 테이블 존재 여부 알아보기

SQL>SELECT TABLE_NAME
        FROM USER_TABLES
        WHERE TABLE_NAME = '찾을 테이블 이름'
        -->찾을 테이블 이름은 대문자여야 됩니다.
 

◈ 모든 유저 보기

SQL>SELECT username
FROM ALL_USERS
 

◈ 테이블 제약조건의 확인

SQL>SELECT table_name, constraint_name, constraint_type

        FROM   USER_CONSTRAINTS

        WHERE TABLE_NAME ='STORM_CONTENT';
 

◈ 선택한 Row만큼만 보여주기

SQL>SELECT name
        FROM storm_board
        WHERE rownum <= 10

---> 이렇게 하면 데이터가 1000건이 있더라도, 1~10건만 보여주게 된다.
 
 
◈ 'LIKE' 연산자를 사용하여 case insensitive search를 할 수 있는 방법
 
필드에 'UPPER' 함수를 사용하시면 됩니다
SQL>SELECT name
        FROM storm_board
        WHERE UPPER(name)
like '%K%'
 

◈ 잠시 host상태로 나가고 싶을 때.


SQL>host
다시 sqlplus로 들어오려면 exit명령
어로 들어오시면 됩니다.
 

◈ 테이블에 새로운 컬럼의 추가

SQL>ALTER TABLE table_name ADD ( column_name DATATYPE )
;
 
ex)SQL>ALTER TABLE storm_board ADD(ip_addr VARCAHR2(15) not null)


◈ 테이블 컬럼의 삭제


SQL>ALTER TABLE table_name DROP COLUMN column_name


ex)SQL>ALTER TABLE storm_board DROP COLUMN ip_addr
-->컬럼의 삭제는 오라클 8i버전부터 되는것으로 알고 있습니다.  
 
 
◈ SQLPLUS에서 SQL문의 실행 속도 알아보기

 
SQL>SET TIMING ON

을 한 후 SELECT문을 수행하면 경과 시간이 나옵니다.
 
SQL> SELECT COUNT(name) FROM storm_board;
 
COUNT(NAME)
-----------
        286
 
경   과: 00:00:00.10


◈ SQLPLUS에서 SELECT문 사용시 데이타만 출력되고 HEADER는 안나오게 하는 방법

 
SQL>SET HEADING OFF
한후 SELECT문을 수행하면 아래와 같은 결과가 나옵니다.
 
SQL> SELECT empno, ename, mgr
         FROM emp
         WHERE rownum < 6;

7369  SMITH            7902
7499  ALLEN            7698
7521  WARD             7698
7566  JONES            7839
7654  MARTIN           7698

'컴퓨터 > DB' 카테고리의 다른 글

데이터베이스 스키마  (0) 2009.01.15
데이터 베이스 테이블스페이스  (0) 2009.01.15
오라클 힌트  (0) 2009.01.14
오라클에서 not exists, not in, minus의 성능차이  (0) 2009.01.13
Analytic Function  (0) 2009.01.13
      
Posted by k_ben

오라클 힌트

컴퓨터/DB : 2009. 1. 14. 22:17


*오라클 힌트 사용예
--------------------------------------------------
select   /*+ index( idx_col_1 ) */
           name, age, hobby
from     member
--------------------------------------------------

select /*+ leading(a) */ .... 인자로 선택된 테이블을 먼저 드라이빙하게 한다.
select /*+ ordered */ .... from 절에 나열된 순서대로 드라이빙하게 한다. 

 
*오라클 힌트 사용표

힌트의 설명 및 사용법
 
ALL_ROWS
             /*+ ALL_ROWS */
-         최소한의 자원을 사용하여 결과값의 전체를 추출하게 합니다.
 
AND_EQUAL
             /*+ AND_EQUAL (table index index [index] [index] [index] ) */
-         복수의 단일 컬럼을 스캔하여 머지 방식으로 처리하게 합니다.
 
APPEND_HINT
             /*+ APPEND */
-         직렬 모드 데이터베이스에서 Direct INSERT를 실행하게 합니다.
-         Enterprise Edition 이 아닌 데이터베이스의 기본 모드는 직렬 모드입니다. 이러한 직렬 모드 데이터 베이스에서의 INSERT 작업은 Conventional를 기본값으로 하고 병렬 처리 시에는 Direct INSERT를 기본값으로 합니다.
 
CACHE_HINT
             /*+ CACHE (table) +/
-         풀 테이블 스캔의 사용 시, 테이블에서 읽어온 블럭을 버퍼의 LRU 리스트 의 MRU 쪽에 위치시킵니다. 작은 테이블의 사용 시 유용합니다.
 
CHOOSE_HINT
             /*+ CHOOSE +/
-         Rule-Based 와 Cost-Based 방식 간의 선택을 유도합니다. 선택 기준은 사용 객체의 분석 정보 존재 여부이며, 사용되는 객체들중 하나라도 분석 정보가 존재한다면 Cost-Based 방식을 사용하게 됩니다.
 
CLUSTER_HINT
             /*+ CLUSTER (table) +/
-         지정 테이블의 클러스터 스캔을 유도합니다. 클러스터된 객체에만 사용할 수 있습니다.
 
CURSOR_SHARING_EXACT
             /*+ CURSOR_SHARING_EXACT +/
-         바인드 변수 값의 교체를 불가능하게 합니다.
-         기본적으로 CURSOR_SHARING 파라미터를 사용하여, 안전하다고 판단될 시 SQL 내의 바인드 변수 값을 교체할 수 있게 되어 있습니다.
 
DRIVING_SITE
             /*+ DRIVING_SITE (table) +/
-         오라클이 선택한 SITE 대신, 지정한 SITE를 사용하여 쿼리를 실행합니다. Rule-Based 와 Cost-Based, 두 모드 다 사용 가능합니다.
 
DYNAMIC_SAMPLING
             /*+ DYNAMIC_SAMPLING ( [table] n ) +/
-         해당 객체의 Selectivity 와 Cardinality 에 대한 보다 자세한 정보를 자동으로 생성시켜 실행합니다.
-         값은 0 부터 10 까지 지정할 수 있으며, 높을 수록 보다 자세한 정보를 생성하게 됩니다. 테이블에 해당 값을 지정하지 않았을 경우, 기본 값은 CURSOR 레벨의 값이 쓰여집니다.
 
EXPAND_GSET_TO_UNION
             /*+ EXPAND_GSET_TO_UNION +/
-         GROUP BY GROUPING SET 혹은 GROUP BY ROLLUP 등과 같은 구문을 포함하는 쿼리에 사용할 수 있습니다.
-         이 힌트는 기존의 쿼리를 개별적인 그룹 생성 후, UNION ALL 방식으로 실행되게 유도합니다.
 
FACT_HINT
             /*+ FACT (table) +/
-         스타 변형 구문에서 사용되며 해당 테이블이 FACT 테이블로 사용되게 유도합니다.
 
FIRST_ROWS
             /*+ FIRST_ROWS (n) +/
-         전체 결과값의 반환 대신 지정한 숫자만큼 로우의 결과값을 반환하는데 집중하게 유도합니다.
 
FULL_HINT
             /*+ FULL (table) */
-         지정한 테이블에 대해 풀 테이블 스캔을 유도합니다.
 
HASH_HINT
             /*+ HASH (table) */
-         지정한 테이블에 대해 hash 스캔을 수행하도록 유도합니다.
-         클러스터 테이블 만을 대상으로 합니다.
 
HASH_AJ
             /*+ HASH_AJ */
-         EXISTS 구문 뒤에 오는 서브 쿼리에 사용되며 HASH_SJ, MERGE_SJ 혹은 NL_SJ 등을 사용할 수 있습니다.
-         HASH_SJ 은 hash semi-join 이고, MERGE_SJ 은 sort merge semi-join 이며 NL_SJ 은 nested loop semi-join 입니다.
 
INDEX
             /*+ INDEX (table index [index] [index] ... ) */
-         지정한 테이블의 인덱스 스캔을 실행하도록 유도합니다.
-         Domain, B-tree, bitmap, bitmap join 인덱스 등이 사용될 수 있으나, bitmap 인덱스 들의 사용 시, INDEX 힌트보다는 INDEX_COMBINE 힌트 사용이 추천됩니다.
 
INDEX_ASC
             /*+ INDEX-ASC (table [index] [index] ... ) +/
-         해당 테이블의 인덱스를 순차적 방식으로 스캔하게 합니다.
-         해당 쿼리가 인덱스 범위 스캔의 사용 시, 인덱스 값의 순차적 방식으로 읽게 됩니다.
 
INDEX_COMBINE
             /*+ INDEX_COMBINE (table [index] [index] ... ) +/
-         해당 테이블에 Bitmap 인덱스의 존재 시, Bitmap 인덱스를 통한 액세스를 유도합니다.
-         힌트 내에 인덱스의 이름이 쓰여지지 않을 시, 해당 인덱스의 Boolean 값을 사용하여 최적의 Cost를 산출하여 실행하게 됩니다.
 
INDEX_DESC
             /*+ INDEX_DESC (table [index] [index] ... ) +/
-         지정한 인덱스에 대해 인덱스 스캔을 역순으로 실행합니다.
-         해당 쿼리가 인덱스 범위 스캔의 사용 시, 인덱스 컬럼의 값을 사용하여 역순으로 실행합니다.
-         파티션 인덱스에서는 파티션 별 개별적인 실행이 이루어집니다.
 
INDEX_FFS
/*+ INDEX_FFS (table [index] [index] ... ) +/
-         풀 테이블 스캔 대신에 빠른 풀 테이블 스캔의 실행을 유도합니다.
 
LEADING_HINT
             /*+ LEADING (table) +/
-         테이블 간의 조인 시에 지정한 테이블을 먼저 수행하도록 유도합니다.
-         두 개 이상의 LEADING 힌트의 사용 시, 힌트 자체가 사용되어 지지 않습니다.
-         ORDERED 힌트와 더불어 사용시, LEADING 힌트는 사용되지 않습니다.
 
MERGE
             /*+ MERGE (table) +/
-         각 쿼리의 결과값을 머지합니다.
-         해당 쿼리 내에 GROUP BY 절의 사용 이나 SELECT 구문에 DISTINCT 가 사용되었을 시, 머지의 실행이 가능할 경우에만 힌트가 실행됩니다.
-         IN 과 서브 쿼리의 사용 시, 서브 쿼리와 상위 쿼리 간의 상호 관계가 없을 때에만 머지의 실행이 가능합니다.
-         이 힌트는 Cost-based 가 아닙니다. 따라서 액세스하는 실행 쿼리 블럭에 MERGE 힌트가 반드시 명시되어야만 합니다. 그렇지 않을 경우 옵티마이저는 다른 실행 계획을 수립합니다.
 
MERGE_AJ
             HASH_AJ 를 참조하십시요.
 
MERGE_SJ
             HASH_AJ 를 참조하십시요.
 
NL_AJ
             HASH_AJ 를 참조하십시요.
 
NL_SJ
             HASH_AJ 를 참조하십시요.
 
NOAPPEND
             /*+ NOAPPEND +/
-         병럴 모드에서의 INSERT 작업을 Conventional 방식으로 수행합니다.
-         병렬 모드에서는 Direct-path INSERT 가, 직렬 모드에서는 Conventional INSERT가 기본값입니다.
 
NOCACHE
             /*+ NOCACHE (table) +/
-         풀 테이블 스캔의 사용 시, 테이블에서 읽어온 블럭을 버퍼의 LRU 리스트 의 LRU 쪽에 위치시킵니다. 기본 모드입니다.
 
NO_EXPAND
             /*+ NO_EXPAND +/
-         실행 쿼리 내에 OR 나 WHERE 절의 IN 이 사용되었을 시, Cost-Based 옵티마이저가 쿼리 처리를위해 OR 를 사용한 확장을 사용하는 것을 방지합니다.
-         일반적으로 옵티마이저는 위와 같은 경우 OR – 확장의 가격이 확장을 사용하지 않는 것보다 적을 시, 확장 방식으로 수행합니다.
 
NO_FACT
             /*+ NO_FACT (table) +/
-         Star 변형 시, 해당 테이블의 FACT 테이블로서의 사용을 방지합니다.
 
NO_INDEX
             /*+ NO_INDEX (table [index] [index] ... ) +/
-         지정 테이블의 인덱스 사용을 방지합니다.
 
NO_MERGE
             /*+ NO_MERGE (table) +/
-         머지 처리 방식의 사용을 방지합니다.
 
NOPARALLEL
             /*+ NOPARALLEL (table) +/
-         지정한 테이블의 병렬 처리를 방지합니다.
-         테이블의 지정된 PARALLEL 값에 대해서 우선권을 가집니다.
-         중첩 테이블에 대해서는 병렬 처리를 할 수 없습니다.
 
NOPARALLEL_INDEX
             /*+ NOPARALLEL_INDEX (table [index] [index] ... ) +/
-         인덱스 스캔 작업의 병렬 처리를 방지합니다.
-         인덱스에 지정된 PARALLEL 값에 우선권을 가집니다.
 
NO_PUSH_PRED
             /*+ NO_PUSH_PRED (table) +/
-         결과값에 대한 조인 방식 서술의 강제적 수행을 방지합니다.
 
NO_PUSH_SUBQ
             /*+ NO_PUSH_SUBQ +/
-         서브 쿼리의 결과값을 머지하지 않는 실행 계획이 실행 계획 설립 단계에서 제일 마지막으로 참조되는 것을 방지합니다.
-         일반적으로 서브 쿼리의 Cost 가 높거나, 처리 로우의 갯수를 크게 줄여주지 못할 때에는 서브 쿼리를 마지막에 참조하는 것이 성능 향상에 도움이 됩니다.
 
NOREWRITE
             /*+ NOREWRITE +/
-         해당 쿼리 블럭의 쿼리 재생성의 실행을 방지합니다.
-         QUERY_REWRITE_ENALBE 파라미터에 대해 우선권을 가집니다.
-         NOREWRITE 힌트의 사용 시, Function-Based 인덱스의 사용이 금지됩니다.
 
NO_UNNEST
             /*+ NO_UNNEST +/
-         해당 서브 쿼리 블럭의 UNNESTING 설정의 사용을 방지합니다.
 
ORDERED
             /*+ ORDERED +/
-         FROM 절에 나열된 테이블의 순서대로 조인 작업을 실행합니다.
 
ORDERED_PREDICATE
             /*+ ORDERED_PREDICATE +/
-         옵티마이저에 의한 조인 관계의 Cost를 산출하기 위해 미리 정해둔 조인 관계 별 실행 순서의 사용을 방지합니다.
n         인덱스 키를 사용한 조인 관계들은 제외됩니다.
-         이 힌트는 쿼리의 WHERE 절에 사용하십시요.
 
PARALLEL
             /*+ PARALLEL (table [ [, n |, DEFAULT |, ] [, n | DEFAULT ] ] ) +/
-         병렬 처리에 사용될 서버 프로세스의 갯수를 설정합니다.
-         병렬 처리 조건에 위배될 시, 힌트는 사용되지 않습니다.
-         임시 테이블에 대한 PARALLEL_HINT 사용 시, 힌트는 사용되지 않습니다.
 
PARALLEL_INDEX
             /*+ PARALLEL_INDEX (table [ [index] [, index]...]
[ [, n |, DEFAULT |, ] [, n | DEFAULT ] ] ) +/
-         파티션 인덱스의 인덱스 범위 스캔 작업의 병렬 처리에 할당될 서버 프로세스의 갯수를 지정합니다.
 
PQ_DISTRIBUTE
             /*+ PQ_DISTRIBUTE (table [,] outer_distribution, inner_distribution) +/
-         병렬 조인 시, Producer 프로세스와 Consumer 프로세스 간의 데이터 전달 방식을 지정합니다.
 
PUSH_PRED
             /*+ PUSH_PRED (table) +/
-         결과값에 대한 조인 방식 서술의 강제적 수행을 실행합니다.
 
PUSH_SUBQ
             /*+ PUSH_SUBQ +/
-         머지가 불가능한 서브 쿼리들의 우선 실행 계획을 실행 계획 수립시 먼저 참조하도록 합니다.
-         서브 쿼리의 사용 객체가 Remote 테이블이거나, 머지 조인의 사용 시 힌트는 실행되지 않습니다.
 
REWRITE
             /*+ REWRITE [ ( [materialized_view] [materialized_view]...) ] +/
-         실행 계획의 가격에 상관없이 Materialized View 를 사용하여 쿼리 재생성을 하도록 합니다.
-         Materialized View 를 지정할 시, 지정한 Materialized View 의 가격에 상관없이 무조건 쿼리 재생성을 실행합니다.
-         Materialized View 를 지정하지 않을 시, 오라클은 사용 가능한 모든 Materialized View 를 참조하여 그 중 가장 가격이 낮은 Materialized View 를 사용하여 쿼리 재생성을 합니다.
-         Materialized View 를 지정하지 않는 힌트의 사용이 권장됩니다.
 
ROW_ID
             /*+ ROWID (table) +/
-         지정한 테이블의 스캔을 ROWID 방식으로 수행하게 합니다.
 
RULE
             /*+ RULE +/
-         실행 계획을 Rule-Based 방식으로 실행하게 합니다.
-         해당 쿼리 블럭에 다른 힌트 또한 사용되었을 경우, 다른 힌트들은 사용되지 않습니다.
 
STAR
             /*+ STAR +/
-         Star 쿼리 계획이 사용 가능하다면, 실행하게 합니다.
-         Star 쿼리 계획이란 가장 큰 테이블이 마지막 순서로 조인되며, 조인될 시 가장 큰 테이블 내의 Concatenated 인덱스에 대해 Nested Loop 조인 방식으로 실행되는 것을 말합니다.
-         최소한 세개 이상의 테이블이 사용되며, 제일 큰 테이블의 Concatenated 인덱스의 생성에 최소한 세 개 이상의 컬럼이 사용되어야 하며, 액세스나 조인 방식에 충돌이 없어야만 이 힌트는 사용됩니다.
 
STAR_TRANSFORMATION
             /*+ STAR_TRANSFORMATION +/
-         옵티마이저가 Star 변형 작업에 최적화된 실행 계획을 수립, 실행하도록 합니다.
-         힌트를 사용하지 않을 시, 옵티마이저는 일반적인 작업에 최적화된 실행 계획을 수행합니다.
-         힌트를 사용하였어도 변형 작업에 맞추어진 실행 계획을 실행한다는 보장은 없습니다. 다른 일반적인 힌트의 사용과 마찬가지로 비교 분석 후, 오라클의 판단에 따라 다른 실행 계획이 실행될 수 있습니다.
 
UNNEST
             /*+ UNNEST +/
-         서브 쿼리 블럭에 대해 인증성 만을 검사하게 합니다.
-         인증이 되었다면 그 이상의 검증 작업없이 서브쿼리에 대한 UNNESTING 의 설정을 가능하게 합니다.
 
USE_CONCAT
             /*+ USE_CONCAT +/
-         WHERE 절의 OR 조인 을 UNION ALL 로 변경하여 수행하게 합니다.
-         일반적으로 이러한 변경은 결과값의 병합 수행의 가격이 수행하지 않을 시의 가격 보다 낮을 때에만 실행됩니다.
 
USE_HASH
             /*+ USE_HASH (table [table]...) +/
-         Hash 조인 방식으로 각 테이블을 조인하게 합니다.
 
USE_MERGE
             /*+ USE_MERGE (table [table]...) +/
-         Sort-Merge 방식으로 각 테이블을 조인하게 합니다.
 
USE_NL
             /*+ USE_NL (table [table]...) +/
- Nested-Loop 방식으로 각 테이블을 조인하게 합니다

'컴퓨터 > DB' 카테고리의 다른 글

데이터베이스 스키마  (0) 2009.01.15
데이터 베이스 테이블스페이스  (0) 2009.01.15
오라클 초보자를 위한 팁  (0) 2009.01.15
오라클에서 not exists, not in, minus의 성능차이  (0) 2009.01.13
Analytic Function  (0) 2009.01.13
      
Posted by k_ben


이 문제는 오라클만의 문제가 아니고 거의 모든 RDBMS 제품들에 대해 공통적인 문제입니다.
일단 SQL 튜닝에서는 모든 상황에 항상 맞는 것은 없습니다. 

즉, SQL 튜닝엔 왕도가 없다는 말입니다. 수학공식 외우듯이 외워서 튜닝을 하는 것은 아니며 그때 그때 데이터의 분포, 서버의 상태, 인덱스의 유무 및 SQL trace나 tkprof결과 등의 각종 참조가능한 수치들을 분석하여 튜닝방향을 정합니다.
상황에 따라 다른 모든 경우엔 가장 안 좋던 방법이 특정 경우엔 최적의 솔루션이 될 수 있습니다.

질문의 3가지 + @ 방법의 두드러진 특징만 구별할 수 있어도 판단에 많은 도움이 되겠지요.

A 집합에서 B집합의 데이터를 제외한 나머지만 구하는 방법은 질문의 3가지를 포함하여 상황에 따라 보통 크게 5가지정도를 주로 쓰게 됩니다. 하나씩 특징만 간단히 적겠습니다...자세한 내용은 직접 공부하세요...;

 

1. not in ...

SELECT *
  FROM A
 WHERE a.key not in (SELECT b.key FROM B)

형태의 구문이며, B쪽을 먼저 access하여 b.key로 a.key에 공급자역할을 하는 서브쿼리로 쓰고 싶을 때 주로 사용합니다.

 

2. not exists ...

SELECT *
  FROM A
 WHERE not exists (SELECT *
                     FROM B
                    WHERE b.key = a.key)

형태의 구문이며, A쪽을 먼저 access하고 나서 a의 각 row들을 not exists로 조사하여 filtering하는 처리를 할 때 주로 사용합니다. 즉, B를 access하기 전에 A쪽의 전체범위가 먼저 access됩니다.

이 때의 서브쿼리는 공급자가 아닌 확인자역할만 해 줄 수 있습니다.

 

3. minus ...

SELECT key, col1, col2 FROM A
MINUS
SELECT key, col1, col2 FROM B

형태의 구문이며, 테스트 해 보면 아시겠지만 MINUS는 특성 상 sort와 중복제거 수행을 동반합니다.
그러므로 가장 이해하기는 간단하나 대용량에서는 사용 시 주의해야 합니다.

A나 B집합의 access대상이 대량인 경우 대량의 sort와 중복제거가 발생하므로 이들 처리에 많은 시간이 소요될 수 있는 쿼리입니다.

 

4. Outer + Null Check ...

SELECT *
  FROM A, B
 WHERE A.key = B.Key(+)
   AND B.Key IS NULL

형태의 구문이며, 위의 not in이나 not exists가 주로 Nested Loop Join 또는 Nested Loop Anti Join 방법을 수행하는데 비해 대용량의 경우 Hash Join이나 Merge Join을 유도하여 성능을 보장받을 수 있는 방법입니다.

단, 각 DBMS 마다 A LEFT OUTER JOIN B ON ~ , (*)등으로 아우터조인에 대한 표현은 약간 씩 다릅니다.

 

5. UNION ALL + Group count 또는 count() over() 분석함수 이용등 ...

SELECT *
 FROM( SELECT a.*,
              COUNT(DISTINCT gbn) OVER(PARTITION BY key) AS cnt
,
              COUNT(DISTINCT DECODE(gbn, 'A', 1)) OVER(PARTITION BY key) AS a_cnt
    
    FROM( SELECT 'A' AS gbn, key, col1, col2
                 FROM A
               UNION ALL
               SELECT 'B' AS gbn, key, col1, col2
                 FROM B
              ) a
     )
 WHERE cnt < 2 AND a_cnt = 1

형태의 구문이며, UNION ALL은 MINUS와 달리 sort나 중복제거를 하지 않고 별다른 조인도 없기 때문에 양쪽집합에 scan할 마땅한 인덱스가 없거나 하는 상황에서 위력을 발휘할 수 있는 솔루션입니다.

GROUP BY와 COUNT 함수로도 위의 의미를 그대로 만들 수 있습니다...분석함수나 통계함수를 지원하지 않는 DBMS들은 COUNT() OVER() 대신 GROUP BY / COUNT로 변경해야겠지요...;

 이외에도 구현할 수 있는 방법들이야 더 있겠지만, 대부분의 상황들에서 위의 예시들이 주로 많이 쓰인다는 것을 거듭 밝힙니다.

 건승하시길...수고하세요~~ 


'컴퓨터 > DB' 카테고리의 다른 글

데이터베이스 스키마  (0) 2009.01.15
데이터 베이스 테이블스페이스  (0) 2009.01.15
오라클 초보자를 위한 팁  (0) 2009.01.15
오라클 힌트  (0) 2009.01.14
Analytic Function  (0) 2009.01.13
      
Posted by k_ben