ORACLE/TUNING2010. 1. 12. 15:45
반응형

EXPLAIN PLAN(실행계획) 이란?

 

 

SQL문의 엑세스 경로를 확인하고 튜닝할 수 있도록 SQL문을 분석하고 해석하여

   실행계획을 수립한 후 실행계획을 PLAN_TABLE에 저장하도록 해주는 명령 입니다.

 

SQL  Trace없이 사용 할 수 있습니다.

 

ORACLE_HOME/rdbms/admin/utlxplan.sql실행

 

statement_id컬럼에 인덱스를 생성해주는것이 수행속도를 향상시켜주고 

    id값이 중복되는 것을 막을 수 있습니다.

 

[Syntax]

 

 

 - statement_id = 'identifiedr' : 1-30자로 부여할 수 있는 해당 실행문의 제목

 - INTO tablename : 출력문을 저장하는 테이블명 PLAN_TABLE을 사용하지 않을경우 사용

 - FOR statement : 실행계획을 수립하고자 하는 SQL(SELECT, INSERT, DELETE, UPDATE)

 

 

 

 

 

1. Plan_table 생성

 

  Explain plan sql에 포함해서 수행하면 옵티마이저가 실행 계획까지만 수립하여

     plan_table에 저장해 둡니다.

  table을 생성하기 위한 script ORACLE_HOME/rdbms/admin/utlxplan.sql 입니다.

 

SQL>@C:\oracle\ora81\rdbms\admin\utlxplan.sql

 

테이블이 생성되었습니다.

 

 

 

 

 

2. Index 생성

 

◈ 테이블 생성 후 수행 속도 향상과 동일한 statement_id가 생성되는 것을  방지하기 위해 

    index를 생성 합니다.

 

SQL> CREATE UNIQUE INDEX plan_index ON PLAN_TABLE(statement_id,id);

 

인덱스가 생성되었습니다.

 

 

 

 

 

3. SQL 문 사용

 

FOR 뒷 부분에 확인하고자 하는 sql을 입력 합니다.

 

SQL>EXPLAIN PLAN SET STATEMENT_ID='a1' FOR

       SELECT /*+ index(emp emp_pk) */ * FROM emp WHERE empno > 0;

 

해석되었습니다.

 

 

 

 

 

4. PLAN_TABLE SELECT 하는 SQL 문을 실행

 

  plan.sql이라고 저장해서 사용하면 편리합니다.

 

SQL>SELECT LPAD(operation,LENGTH(operation)+ 2*(LEVEL-1)) ||DECODE(id,0,'cost  estimate:' ||

       DECODE(position,'0','N/A',position),null) || ' ' ||options || DECODE(object_name,null,null,':') ||

       RPAD(object_owner, LENGTH(object_name)+1,',') || object_name ||

       DECODE (object_type,'UNIQUE' ,'(U) ','NON_UNIQUE','(NU)',null) ||

       DECODE(object_instance,null,null,'('||object_instance||')')  "Explain Plan"

       FROM PLAN_TABLE

       START WITH ID= 0 and STATEMENT_ID = '&&id'

       CONNECT by prior ID=PARENT_ID and STATEMENT_ID='&&id'

 

 

a1을 입력하면 아래와 같은 실행계획을 볼 수 있습니다.

 

 Explain Plan

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

 

SELECT STATEMENTcost  estimate:1

  TABLE ACCESS BY INDEX ROWID:TESTEMP(1)

    INDEX RANGE SCAN:TEST,,,EMP_PK

 

 

 

 

 

PLAN_TABLE 컬럼 설명

 

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

 컬 럼 명                                       

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

 STATEMENT_ID                                EXPLAIN PLAN문에서 사용자가 지정한 제목

 TIMESTAMP                            실행계획이 수립된 날짜와 시간

 REMARKS                                     사용자가 부여한 주석(COMMENT)

 OPERATION                            아래 표에 자세히 설명 되어 있습니다.

 OPTIONS                                     아래 표에 자세히 설명 되어 있습니다.

 OBJECT_NODE                          사용한 데이터베이스 링크

 OBJECT_OWNER                                해당 라인의 오브젝트를 생성한 사용자 그룹

 OBJECT_NAME                          테이블이나 인덱스, 클러스터등의 이름

 OBJECT_INSTANCE                      SQL FROM절에 기술된 오브젝트를 좌에서 우로 부여한 번호

 OBJECT_TYPE                          오브젝트의 종류( non-unique index)

 ID                                          수립된 각 실행단계에 붙여진 일련번호

 PARENT_ID                            해당 ID의 부모가 가진 ID

 POSITION                                    같은 부모 ID를 가지고 있는 자식 ID간의 처리 순서

 OTHER                                       다른 필요한 텍스트를 지정하기 위한 필트

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

 

 

OPERATION의 종류와 OPTIONS에 대한 설명

 

OPERATION(기능)               OPTIONS(옵션)                      

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

AGGREGATE                             GROUP BY                              그룹함수를 사용하여 하나의 로우가 추출되도록 하는 처리(버전 7에서만 표시됨)

AND-EQUAL                                                                   인덱스 머지를 이용하는 경우

CONNECT BY                                                                  CONNECT BY를 사용하여 트리 구조로 전개

CONCATENATION                                                               단위 액세스에서 추출한 로우들의 합집합을 생성

COUNTING                                                                           테이블의 로우스를 센다

FILTER                                                                             선택된 로우에 대해서 다른 집합에 대응되는 로우가 있다면 제거하는 작업

FIRST ROW                                                                          조회 로우 중에 첫번째 로우만 추출한다.

FOR UPDATE                                                                         선택된 로우에 LOCK을 지정한다. 

INDEX                                 UINQUE                                UNIQUE인덱스를 사용한다. (단 한개의 로우 추출)

                                             RANGE SCAN                            NON-UNIQUE한 인덱스를 사용한다.(한 개 이상의 로우)

                                             RANGE SCAN                            RANGE SCAN하고 동일하지만 역순으로 로우를 추출한다.

                                             DESCENDING 

INTERSECTION                                                                교집합의 로우를 추출한다.

MERGE JOIN                            OUTER                                 먼저 자신이ㅡ 조건만으로 액세스한 후 각각을 SORT하여

                                                                                           MERGE해 가는 조인

                                                                                           위와 동일한 방법이지만  outer join을 사용한다.

MINUS                                                                              MINUS 함수를 사용한다.

NESTED LOOPS                  OUTER                                 먼저 어떤 드라이빙 테이블의 로우를 액세스한 후 그 결과를

                                                                                           이용해 다른 테이블을 연결하는 조인

                                                                                           위와 동일하지만 outer join을 사용한다.

PROJECTION                                                                         내부적인 처리의 일종

REMOTE                                                                             다른 분산 데이터베이스에 있는 오브젝트를 추출하기 위해

                                                                                           DATABASE LINK를 사용하는 경우

SEQUENCE                                                                           시퀀스를 액세스 한다.

SORT                                  UNIQUE                                같은 로우를 제거하기 위한 SORT

                                             GROUP BY                              액세스 결과를 GROUP BY 하기 위한 SORT

                                             JOIN                                  MERGE JOIN을 하기 위한 SORT

                                             ORDER BY                              ORDER BY를 위한 SORT

TABLE ACCESS                  FULL                                  전체 테이블을 스캔한다.

                                             CLUSTER                               CLUSTER를 액세스 한다.

                                             HASH                                  키값에 대한 해쉬 알고리즘을 사용(버전 7에서만)

                                             BY ROWID                              ROWID를 이용하여 테이블을 추출한다.

UNION                                                                              두 집합의 합집합을 구한다.(중복없음)

                                                                                           항상 전체 범위 처리를 한다.

UNION ALL                                                                          두 집합의 합집합을 구한다.(중복가능)

                                                                                           UNION과는 다르게 부분범위 처리를 한다.

VIEW                                                                               어떤 처리에 의해 생성되는 가상의 집합에서 추출한다.(주로 서브쿼리에 의해 수행된 결과)

=======================================================================================================

출처 : http://jaehan.tistory.com/92?srchid=BR1http%3A%2F%2Fjaehan.tistory.com%2F92

EXPLAIN PLAN 이란?

 

사용자들이 SQL 문의 액세스 경로를 확인하고
튜닝을 할 수 있도록 SQL 문을 분석하고 해석하여 실행 계획을 수립한 후
실행 계획을 테이블(plan_table)에 저장하도록 해주는 명령 입니다.


1. PLAN TABLE의 생성

Explain plan을 sql 에 포함해서 수행하면 옵티마이저가 실행 계획까지만
수립하여 plan_table에 저장해 둡니다.

PLAN을 사용하고자 하는 USER로 SQLPLUS LOGIN한 후
ORACLE_HOME/RDBMS/ADMIN/utlxplan.sql을 수행하여 plan_table을 생성 합니다.


C:\>SQLPLUS scott/tiger

SQL*Plus: Release 10.2.0.1.0 - Production on 화 10월 10 16:41:26 2006

Copyright (c) 1982, 2005, Oracle.  All rights reserved.


다음에 접속됨:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options

SQL> @C:\oracle\product\10.2.0\db_2\RDBMS\ADMIN\utlxplan.sql

테이블이 생성되었습니다.

SQL>

 

2. PLUSTRACE ROLE의 생성
sqlplus "/ as sysdba"로 접속하여 PLUSTRACE ROLE을 생성 합니다.
ORACLE_HOME/sqlplus/admin/plustrce.sql을 수행하여 plustrace role을 생성 합니다.

 

C:\>sqlplus "/ as sysdba"

SQL*Plus: Release 10.2.0.1.0 - Production on 화 10월 10 17:01:26 2006

Copyright (c) 1982, 2005, Oracle.  All rights reserved.


다음에 접속됨:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options

SQL> @C:\oracle\product\10.2.0\db_2\sqlplus\admin\plustrce.sql
SQL>
SQL> drop role plustrace;
drop role plustrace
          *
1행에 오류:
ORA-01919: 롤 'PLUSTRACE'(이)가 존재하지 않습니다


SQL> create role plustrace;

롤이 생성되었습니다.

SQL>
SQL> grant select on v_$sesstat to plustrace;

권한이 부여되었습니다.

SQL> grant select on v_$statname to plustrace;

권한이 부여되었습니다.

SQL> grant select on v_$mystat to plustrace;

권한이 부여되었습니다.

SQL> grant plustrace to dba with admin option;

권한이 부여되었습니다.

SQL>
SQL> set echo off
SQL>

 

3. PLUSTRACE Role의 부여

PLUSTRACE ROLE을 plan을 사용하고자 하는 유저에게 부여 합니다.

 

SQL> GRANT plustrace TO scott;

권한이 부여되었습니다.


권한을 부여 한다음.
다시 plan을 사용하는 유저로 접속을 합니다.

SQL> conn scott/tiger
연결되었습니다
.


autotrace 상태를 on으로 바꿉니다.

SQL> SET AUTOTRACE ON  ;
SQL>


SQL문을 실행 합니다.

SQL> SELECT a.ename, a.sal, b.dname
  2   FROM emp a, dept b
  3  WHERE a.deptno = b.deptno;

 

ENAME             SAL DNAME
---------- ---------- --------------
SMITH             800 RESEARCH
ALLEN            1600 SALES
WARD             1250 SALES
JONES            2975 RESEARCH
MARTIN           1250 SALES
BLAKE            2850 SALES
CLARK            2450 ACCOUNTING
SCOTT            3000 RESEARCH
KING             5000 ACCOUNTING
TURNER           1500 SALES
ADAMS            1100 RESEARCH

ENAME             SAL DNAME
---------- ---------- --------------
JAMES             950 SALES
FORD             3000 RESEARCH
MILLER           1300 ACCOUNTING

14 개의 행이 선택되었습니다.


Execution Plan
----------------------------------------------------------
Plan hash value: 351108634

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

| Id  | Operation                                        | Name    | Rows  | Bytes | Cost (%CPU)| Time      |

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

|   0 | SELECT STATEMENT                       |               |     14 |    364 |        4       (0)| 00:00:01 |

|   1 |  NESTED LOOPS                             |               |     14 |    364 |        4       (0)| 00:00:01 |

|   2 |   TABLE ACCESS FULL                    | EMP        |     14 |    182 |        3       (0)| 00:00:01 |

|   3 |   TABLE ACCESS BY INDEX ROWID| DEPT       |       1 |     13 |        1       (0)| 00:00:01 |

|*  4 |    INDEX UNIQUE SCAN                 | PK_DEPT  |       1 |          |        0       (0)| 00:00:01 |

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


Predicate Information (identified by operation id):
---------------------------------------------------

   4 - access("A"."DEPTNO"="B"."DEPTNO")


Statistics
----------------------------------------------------------
        626  recursive calls
          0  db block gets
        134  consistent gets
         10  physical reads
          0  redo size
        856  bytes sent via SQL*Net to client
        385  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
         10  sorts (memory)
          0  sorts (disk)
         14  rows processed

SQL>


⊙ 참고


☞ 8.17
@C:\oracle\ora81\RDBMS\ADMIN\utlxplan.sql; 
@C:\oracle\ora81\sqlplus\admin\plustrce.sql;

 

☞ 10g
@C:\oracle\product\10.2.0\db_2\RDBMS\ADMIN\utlxplan.sql
@C:\oracle\product\10.2.0\db_2\sqlplus\admin\plustrce.sql

 

⊙ Golden(골든)의 결과

 - Ctrl + P 키를 누루면 결과 나온다.

 
TOAD(토드)에서 설정방법
- Ctrl + E 키를 누루면 결과 나온다.
 
PLAN 테이블(TOAD_PLAN_TABLE)이 존재한다면 
TOAD 상단 메뉴에서
View 메뉴 > Options 메뉴 내용중 "Oracle > General" 에 Explain Plan Table Name 이 있습니다. 이곳에 "TOAD_PLAN_TABLE" 이라 명시하시고 사용하면 됩니다

반응형

'ORACLE > TUNING' 카테고리의 다른 글

Oracle Hidden Parameter 란  (0) 2010.01.26
FAST_START_MTTR_TARGET  (0) 2010.01.18
Statspack Report 간단 분석 방법  (0) 2009.12.17
cursor_sharing 파라미터에 대한 테스트  (0) 2009.12.16
Literal SQL 조회하는 방법  (0) 2009.12.05
Posted by [PineTree]
ORACLE/INSTALL2010. 1. 11. 17:35
반응형
출처 : http://movestar.egloos.com/1867475

테스트 서버라 서버 안내리고 그냥 해봤는데 이상 없이 잘 되는 군요..^^

오라클을 오라클 공식문서 (quick install guide for linux)를 따라 설치하게 되면

em 화면에서 버튼이 아래 처럼 깨져있다.


http://imagesearch.naver.com/search.naver?where=idetail&rev=4&query=em%20%B1%FA%C1%FC&from=image&ac=1&sort=0&res_fr=0&res_to=0&merge=0&spq=0&start=1&a=pho_l&f=tab&r=1&u=http%3A%2F%2Fcafe.naver.com%2Focmkorea%2F2123 에서 펌 (한글 버튼 깨짐 문제를 해결하기전에 찍은 스샷이 없어서... 퍼왔습니다)


내 작업환경은 IDC에 오라클 서버가 있고 (linux), 내 컴퓨터는 공유기에 연결되어 내부 아이피를 사용하는 windows XP에 cygwin을 깔린 상태이다.

내부아이피를 사용하므로, 공유기에서 내 컴퓨터의 Xserver 포트(6000)로 포드포워딩을 해줘야 한다.

cygwin X server를 뛰우고, X term을 열여서 외부에서 cygwin X server로 들어오는 접속이 가능 하도록 설정 해준다.


이제 원격 오라클 서버에 oracle 계정으로 접속해서 (위 cygwin 터미널 또는 다른 프로그램(putty 등)

# export DISPLAY=내공유기IP:0.0

# (오라클 설치 파일이 있는 디렉토리 에서) ./runinstaller -addLangs $*

위와 같이 실행하면 원격 오라클 서버에 설치되는 과정을 내 컴퓨터에서 확인할 수 있다.



Next 버튼을 클릭하다보면 아래와 같은 화면이 뜨는데, 여기서 "Korean"을 선택해서 추가하면된다.



이게 끝이 아니다.

오라클을 custom으로 설치하는 과정에서 Korean을 추가해주면 ALBANWTK.TTF 파일이 생성되는데,

이미 설치된 오라클에서는 파일이 생성되지 않는다.

ALBAMWTK.TTF 파일을 (아래 첨부)

/u01/app/oracle/product/11.1.0/db_1/jdk/jre/lib/fonts/    디렉토리에 넣어주고,

/u01/app/oracle/product/11.1.0/db_1/oc4j/j2ee/oc4j_applications/applications/em/em/cabo/images/cache/ko/ 에 있는 파일들을 모두 지운다. (깨진 버튼 이미지들)

em을 종료시킨후에 (# emctl stop dbconsole)
재시작하고 (# emctl start dbconsole)
 em주소를 치고 들어가면,

정상적인 한글 버튼을 볼 수 있다.




반응형
Posted by [PineTree]
ORACLE/SQL2010. 1. 4. 14:58
반응형
1. EXECUTE IMMEDIATE를 이용한 Dynamic SQL  


Oracle 8i에서의 Dynamic SQL은 두가지 방법이 있습니다.

첫번째 방법은  "EXECUTE IMMEDIATE" 절을 사용하여 embedded dynamic sql을 구현하는
방법이고,

두번째 방법은 선언되어지는 것 대신에 실행시에 문장을 보내는 ref cursor의 확장된 개념으로
query를 위해 사용되어지는 방법 입니다.


여기서는 EXECUTE IMMEDIATE를 이용한 Dynamic SQL에 대해서 알아보겠습니다.

[Syntax]

        EXECUTE IMMEDIATE dynamic_sql_string
            [INTO {define_var1 [, define_var2] ... | plsql_record }]
            [USING [IN | OUT | IN OUT] bind_arg1 [,
                        [IN | OUT | IN OUT] bind_arg2] ...];

 


2. 간단하게 테이블을 생성하는 예제 입니다 

 
첫번째 예제는 간단하게 테이블을 생성하는 예제 입니다.
 
==========================================================

CREATE OR REPLACE PROCEDURE dynamic_sql_01
IS

    str varchar2(200);

BEGIN

    str := ’CREATE TABLE  total (total number)’;
    EXECUTE IMMEDIATE str;

END;

==========================================================

프로시저가 생성되었습니다.

 
-- 프로시저를 실행해서 테이블을 생성 합니다.
SQL> EXEC dynamic_sql_01;
PL/SQL 처리가 정상적으로 완료되었습니다.
 
 
-- 생성된 테이블을 확인해 봅니다.
SQL> DESC total;
 이름                                      널?      유형
 ----------------------------------------- -------- -----------
 TOTAL                                              NUMBER



* 프로시저 생성시 "ORA-01031: 권한이 불충분합니다" 에러가 발생하면
  system유저로 접속을 해서 EXECUTE IMMEDIATE를 실행하는 유저에게
  CREATE ANY TABLE 권한을 부여 합니다.   

SQL> CONN system/manager  
SQL> GRANT create any table TO scott;

 


3. 테이블 생성 후 INSERT 예제


두번째 예제는 TABLE_ROWS라는 테이블을 생성하고, 다이나믹 하게 테이블명을 입력하면
테이블명과 테이블에 등록된 데이터수를 TABLE_ROWS에 INSERT하고 출력하는 예제 입니다.


=============================================================== 

CREATE OR REPLACE PROCEDURE dynamic_sql_02
 (v_table_name IN VARCHAR2)
IS
   
    v_str VARCHAR2(200);
    v_cnt NUMBER;
    v_temp VARCHAR2(50);
    
    CURSOR cur_exists IS
    SELECT TABLE_NAME
    FROM USER_TABLES
    WHERE table_name = ’TABLE_ROWS’;
    
BEGIN
    
    OPEN cur_exists
    FETCH cur_exists INTO v_temp;
    

   -- 테이블이 존재하면 테이블을 삭제 합니다.
    IF  cur_exists%FOUND THEN     
        v_str := ’DROP TABLE  table_rows’;
        EXECUTE IMMEDIATE v_str;
    END IF;    

    -- 테이블 생성
    v_str := ’CREATE  TABLE  table_rows (total number, table_name varchar2(50))’;
    EXECUTE IMMEDIATE v_str;    


   -- 데이터 카운트 조회
    v_str := ’SELECT COUNT(*) cnt FROM ’||v_table_name ;
    EXECUTE IMMEDIATE v_str INTO v_cnt ;


    -- 데이터 insert
    v_str := ’INSERT INTO table_rows  VALUES (’||v_cnt||’, :A1 )’;   
    EXECUTE IMMEDIATE v_str USING v_table_name;


    DBMS_OUTPUT.PUT_LINE(’ 테이블 명 : ’||v_table_name||’  데이터 수 : ’||v_cnt);    

    CLOSE cur_exists;     

END;
/
=============================================================== 

프로시저가 생성되었습니다.
 
SQL> SET SERVEROUTPUT ON:

-- emp 테이블명과 테이블의 데이터카운트를 INSERT합니다.
SQL> EXEC dynamic_sql_02(’emp’);
테이블 명 : emp  데이터 수 : 14

PL/SQL 처리가 정상적으로 완료되었습니다.


-- 정상적으로 처리되었는지 확인해 봅니다.
SQL> SELECT * FROM table_rows;
 
     TOTAL TABLE_NAME
---------- --------------
        14 emp

  ================================================
    * 데이터베이스 정보공유 커뮤니티 oracleclub.com
    * 강좌 작성자 : 김정식 (oramaster _at_ naver.com)
  ================================================
※ oracleclub 강좌를 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
※ oracleclub 강좌는 개인의 학습용으로만 사용 할 수 있습니다. 학원 홍보용이나 수익을 얻기 위한 용도로
    사용을 하시면 안됩니다. ^^
반응형

'ORACLE > SQL' 카테고리의 다른 글

Oracle EXISTS Versus IN  (0) 2010.06.18
NOT IN과 NOT EXISTS의 차이점  (0) 2010.04.02
SQL *Plus 명령어와 SQL문 구분하기  (0) 2010.01.03
DB 최적화를 고려한 다건조회 페이징처리  (0) 2010.01.03
SQL TIP  (0) 2010.01.03
Posted by [PineTree]
ORACLE/SQL2010. 1. 3. 14:13
반응형

┌──────────────┬─────────────────────┬────────┐
│구분 │ 설명 │ 예 │
├──────────────┼─────────────────────┼────────┤
│DML │데이터를 조회하거나 변경 │insert,update │
│(Data Manipulation Language)│ │delete,select │
│ │ │commit,rollback │
├──────────────┼─────────────────────┼────────┤
│DDL │데이터의 구조를 정의 │create,drop │
│(Data Definition Language) │ │alter,rename, │
│ │ │truncate │
├──────────────┼─────────────────────┼────────┤
│DCL │데이터베이스 사용자에게 부여된 권한을 정의│grant,revoke │
│(Data Control Language) │ │ │
└──────────────┴─────────────────────┴────────┘

SQL> select * from tab;

TNAME TABTYPE CLUSTERID
------------------------------ ------- ----------
ACCOUNT TABLE
BONUS TABLE
DEPARTMENT TABLE
DEPT TABLE
EMP TABLE
EMPLOYEE TABLE
RECEIPT TABLE
SALGRADE TABLE

SQL> desc emp -- desc(ribe)는 테이블 정의를 나타내는 명령어

이름 널? 유형
----------------------------------------- -------- ------------
EMPNO NOT NULL NUMBER(4)
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
MGR NUMBER(4)
HIREDATE DATE
SAL NUMBER(7,2)
COMM NUMBER(7,2)
DEPTNO NUMBER(2)


▶ 명령어 버퍼
-- SQL *Plus는 명령어 버퍼(command buffer)에서 현재의 SQL문을 보관한다.
-- 이 명령어 버퍼의 각각의 줄은 번호가 부여되어 있다.
-- 사용자는 명령어 버퍼의 내용을 편집하고, 호출하고 저장할 수 있으며,
-- SQL*Plus의 프롬프트에 list나 그의 축약표현인 L을 입력하여 버퍼의 내용을 나타내게 할 수 있다.


--------------------------------------------------------------------------------
명령어 설명
--------------------------------------------------------------------------------
L(LIST) SQL명령어 버퍼의 내용을 나열
L(LIST) n SQL명령어 버퍼의 내용중 n번째줄만 나열
L(LIST) m n SQL명령어 버퍼의 내용중 m번째 부터 n번째줄까지 나열
R(RUN) SQL명령어 버퍼에 있는 SQL문을 실행시킴
N(N은 숫자) N을 편집될 현재의 줄로 만듦
I(INSERT) 현재의 줄 다음에 새로운 줄을 삽입
새로운 줄이 현재의 줄이 됨
DEL(DELETE) 현재의 줄을 삭제
DEL n n번째 줄을 삭제
DEL m n m번째 부터 n번째 까지 줄을 삭제
A(APPEND) text 현재의 줄에 텍스트를 첨가
C(CHANGE)/string1/string2/ 문자열1(string1)의 내용을 문자열2(string2)로 변경함
CL(CLEAR) BUFF(BUFFER) SQL명령어 버퍼에 있는 SQL문을 삭제
CL(CLEAR) SCR(SCREEN) SQL*Plus 에디터 화면을 지움
--------------------------------------------------------------------------------

SQL> select empno,ename
2 from emp
3 where sal > (select avg(sal) from emp);

EMPNO ENAME
---------- ----------
7566 JONES
7698 BLAKE
7782 CLARK
7788 SCOTT
7839 KING
7902 FORD

6 개의 행이 선택되었습니다.


1. 방금했던 질의의 내용을 다시 나타내게 하고 싶다면 즉, 현재 버퍼에 있는 내용을 나타내 보는것

SQL> l
1 select empno,ename
2 from emp
3* where sal > (select avg(sal) from emp)


2. 이번에는 평균 급여보다 적게 받는 사원들을 알고 싶어서 3번째 줄을 편집하고자 한다면 SQL프롬프트에서 3을 입력한다.

SQL> 3
3* where sal > (select avg(sal) from emp)

3. 3번째 줄이 현재의 줄이 되었고(라인 번호 옆에 * 표시가 있는 곳이 현재의 줄이다), '>'을 '<'로 변경하기 위해서
change명령(축약 c)을 사용한다.
SQL> c/>/<
3* where sal < (select avg(sal) from emp)

4. 다시 현재 버퍼의 내용을 확인해본다.
SQL> l
1 select empno,ename
2 from emp
3* where sal < (select avg(sal) from emp)

5. 이 질의 결과가 사원들의 이름순으로 정렬되기를 원한다. 그래서 현재 버퍼의 내용의 끝에 새로운 줄을 입력하기 위해서
input명령(축약어 i)을 사용한다.
SQL> i
4 order by ename
5

6. 다시 현재 버퍼의 내용을 확인한다.
SQL> l
1 select empno,ename
2 from emp
3 where sal < (select avg(sal) from emp)
4* order by ename

7. 그런데, 이들의 구체적인 급여도 알고 싶어서 첫번째 줄의 뒤에 찾는 컬럼 sal을 추가해야 한다.
먼저 위의 버퍼 내용에서는 현재의 줄이 4번째 줄이므로, 첫번째 줄로 현재의 줄을 바꾸기 위해서 1을 입력한다.
SQL> 1
1* select empno,ename

8. ,sal을 이 줄의 뒤에 추가시키기 위해 append명령(축약 a)을 사용한다.
SQL> a ,sal
1* select empno,ename,sal

9. 다시 현재 버퍼의 내용을 확인한다.
SQL> l
1 select empno,ename,sal
2 from emp
3 where sal < (select avg(sal) from emp)
4* order by ename

10. 현재 버퍼에 있는 SQL문을 run 이나 /을 입력하여 실행시킨다.
SQL> /

EMPNO ENAME SAL
---------- ---------- ----------
7876 ADAMS 1100
7499 ALLEN 1600
7900 JAMES 950
7654 MARTIN 1250
7934 MILLER 1300
7369 SMITH 800
7844 TURNER 1500
7521 WARD 1250

8 개의 행이 선택되었습니다.


11. 편집명령어 ==> ed

SQL> select * from 사원
2 where 부서펀호=20;
where 부서펀호=20
*
2행에 오류:
ORA-00904: 열명이 부적합합니다


SQL> ed

select * from 사원
where 부서번호=20 ==> 메모장에서 펀을 번으로 수정한 후 alt+f , x , 엔터
/

file afiedt.buf(이)가 기록되었습니다

1 select * from 사원
2* where 부서번호=20

SQL> / ==> /으로 실행함



▶------ SQL문을 파일로 저장하기 -------◀

★★★
1. save 명령어를 사용하여 명령어 버퍼의 현재 내용만을 사용자가 명시하는 파일로 저장한다.
기본적으로 save 명령어는 .sql 이라는 확장자를 사용한다. 사용자는 다른 파일 확장자를 사용할 수 있다.
save 명령어는 자동적으로 덮어쓰기를 하지 않으므로
기존의 파일 위에 덮어쓰기를 하려면 replace 라는 옵션을 사용해야 한다.

SQL> l
1 select empno,ename,sal
2 from emp
3 where sal < (select avg(sal) from emp)
4* order by ename

SQL> save c:\test\lowsal
file c:\test\lowsal(이)가 생성되었습니다

SQL> save c:\test\lowsal
SP2-0540: "c:\test\lowsal.sql" 파일은 이미 존재합니다.
"SAVE 파일명[.ext] REPLACE"을 사용합니다.

SQL> save c:\test\lowsal replace
file c:\test\lowsal(이)가 기록되었습니다

★★★
2. get을 사용하여 save 명령어를 사용하여 파일로 저장된 명령어 버퍼의 내용을 조회하고, r을 입력하여 SQL문을 실행시킨다.

SQL> get c:\test\lowsal
1 select empno,ename,sal
2 from emp
3 where sal < (select avg(sal) from emp)
4* order by ename
SQL> r
1 select empno,ename,sal
2 from emp
3 where sal < (select avg(sal) from emp)
4* order by ename

EMPNO ENAME SAL
---------- ---------- ----------
7876 ADAMS 1100
7499 ALLEN 1600
7900 JAMES 950
7654 MARTIN 1250
7934 MILLER 1300
7369 SMITH 800
7844 TURNER 1500
7521 WARD 1250

8 개의 행이 선택되었습니다.


★★★
3. 출력을 파일로 저장하기
spool 명령어는 질의 결과를 파일로 저장해주는 것이다.
spool off 명령어는 스풀링을 중단하는 SQL *Plus 명령어이다.

SQL> spool c:\test\spool_1
SQL> select empno,ename,sal
2 from emp
3 where sal < (select avg(sal) from emp)
4 order by ename;

EMPNO ENAME SAL
---------- ---------- ----------
7876 ADAMS 1100
7499 ALLEN 1600
7900 JAMES 950
7654 MARTIN 1250
7934 MILLER 1300
7369 SMITH 800
7844 TURNER 1500
7521 WARD 1250

8 개의 행이 선택되었습니다.

SQL> select empno,ename,sal
2 from emp
3 where sal = (select max(sal) from emp);

EMPNO ENAME SAL
---------- ---------- ----------
7839 KING 5000

SQL> spool off

============================================================
c:\test\spool_1.lst 파일을 메모장에서 열어 보았을 때의 내용
SQL> select empno,ename,sal
2 from emp
3 where sal < (select avg(sal) from emp)
4 order by ename;

EMPNO ENAME SAL
---------- ---------- ----------
7876 ADAMS 1100
7499 ALLEN 1600
7900 JAMES 950
7654 MARTIN 1250
7934 MILLER 1300
7369 SMITH 800
7844 TURNER 1500
7521 WARD 1250

8 개의 행이 선택되었습니다.

SQL> select empno,ename,sal
2 from emp
3 where sal = (select max(sal) from emp);

EMPNO ENAME SAL
---------- ---------- ----------
7839 KING 5000

SQL> spool off
============================================================

★★★
4. 스크립트를 실행하기

c:\test\script1.sql 이라는 파일로 아래의 내용을 저장한다.

select empno,ename,job,sal
from emp
where job='CLERK';

SQL> @ c:\test\script1.sql

EMPNO ENAME JOB SAL
---------- ---------- --------- ----------
7369 SMITH CLERK 800
7876 ADAMS CLERK 1100
7900 JAMES CLERK 950
7934 MILLER CLERK 1300

SQL> start c:\test\script1.sql

EMPNO ENAME JOB SAL
---------- ---------- --------- ----------
7369 SMITH CLERK 800
7876 ADAMS CLERK 1100
7900 JAMES CLERK 950
7934 MILLER CLERK 1300


★★★
5. 출력의 포맷팅
SQL *Plus 명령어를 통해서 사용자가 형식, 총계와 소계를 명시할 수 있고 반복되는 값을 통제할 수 있다.
포맷팅 명령어는 임시적이다. 이것들은 동일한 SQL *Plus 세션 기간중 처리되는 SQL문에 대해서만 그 효력을 유지한다.

※ SQL*Plus 세션이란?
-- SQL *Plus에 연결할 때부터 SQL *Plus에서 연결을 끊을 때까지 발생하는 명령어와 그에 대한 반응을 말한다.

------------------------------------------------------------------------------------------------
명령어 목적
------------------------------------------------------------------------------------------------
col[umn] 컬럼의 옵션 컬럼의 형식을 바꾼다.
tti[tle] [문장|off|on] 보고서 각 페이지 상단의 머릿글을 나타낸다.
bti[tle] [문장|off|on] 보고서 각 페이지 하단의 머릿글을 나타낸다.
bre[ak] [on 반복을 배제할 리스트] 라인을 넘겨 중복값을 통제한다.
comp[ute] [함수 of{컬럼명} on {컬럼명}] 합계를 계산한다.
------------------------------------------------------------------------------------------------

------------------------------------------------------------------------------------------------
포맷 지정 요소 내용
------------------------------------------------------------------------------------------------
An (n은 폭을 나타내는 숫자) 문자와 날짜 컬럼에 대해서 n폭 만큼 출력 설정
9 자리수 표현
0 앞에 0을 붙임
$ 달러 사인 표시
L 국내 통화 표시
. 소숫점의 위치
, 천 단위 구분자
------------------------------------------------------------------------------------------------

1). emp 테이블에서, 사원들의 급여를 세 자리마다 콤마를 찍고 앞에 달러 사인($)을 표시하고 싶다면 다음과 같이 한다.

SQL> col sal format $9,999
SQL> select empno, ename, sal
2 from emp;

EMPNO ENAME SAL
---------- ---------- -------
7369 SMITH $800
7499 ALLEN $1,600
7521 WARD $1,250
7566 JONES $2,975
7654 MARTIN $1,250
7698 BLAKE $2,850
7782 CLARK $2,450
7788 SCOTT $3,000
7839 KING $5,000
7844 TURNER $1,500
7876 ADAMS $1,100

EMPNO ENAME SAL
---------- ---------- -------
7900 JAMES $950
7902 FORD $3,000
7934 MILLER $1,300

14 개의 행이 선택되었습니다.


2). 문자 컬럼의 경우, 사용자는 Format 명령어를 사용하여 컬럼의 넓이를 명시할 수 있다.
부서명을 한 줄에 다섯글자만 표현하고 다음줄에 나타내는 보고서를 만든다면 다음과 같이 한다.

SQL> col dname format a5
SQL> select * from dept;

DEPTNO DNAME LOC
---------- ----- -------------
10 ACCOU NEW YORK
NTING

20 RESEA DALLAS
RCH

30 SALES CHICAGO
40 OPERA BOSTON
TIONS

3). 위의 결과를 보기에 좋지 않은 형식이다. 그래서 포맷지정을 다시 원상복귀 시키기 위해서
현재의 포맷지정을 clear 옵션을 사용하여 지운다.
SQL> col dname clear
SQL> select * from dept;

DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON


4). clear 옵션을 사용하지 않으면, SQL*Plus 세션을 끝낼때 까지 지정한 포맷형식이 계속 출력에 이용된다.
이번에는 부서의 지역명을 7자리의 포맷으로 맞추어 본다.

SQL> col loc format a7
SQL> select * from dept;

DEPTNO DNAME LOC
---------- -------------- -------
10 ACCOUNTING NEW YOR
K

20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON


5). 사용자는 NEW YOR와 K처럼 단어 중간이 잘리는 것을 원치 않을 수도 있다.
단어가 토막나는 것을 막기 위하여, column명령어에 word_wrap을 추가한다.

SQL> col loc format a7 word_wrap
SQL> select * from dept;

DEPTNO DNAME LOC
---------- -------------- -------
10 ACCOUNTING NEW
YORK

20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON


6). 워드래핑(Wrapping) 대신에, 사용자는 한 컬럼의 내용 끝을 잘라버리기 위하여
trunc 명령어를 사용할 수 있다.

SQL> col loc format a7 trunc
SQL> select * from dept;

DEPTNO DNAME LOC
---------- -------------- -------
10 ACCOUNTING NEW YOR
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON

※ column 명령어로 컬럼의 형식을 설정한다면, SQL*Plus는 컬럼들이 다른 테이블에 있을지라도,
동일한 이름을 가진 모든 컬럼에 대하여 그 형식을 사용하게 된다.
사용자는 각각의 select문 앞에 다른 형식으로 column명령어를 재실행하거나,
Alias를 명시하여 각각의 컬럼명이 유일하게 할 수 있다.

7). 각 사원의 연봉을 구하기 위한 다음의 예는 컬럼 수식 sal*12에 대해 annual_salary라는 별칭을 사용한다.

SQL> select empno,ename,
2 sal*12 annual_salary
3 from emp;

EMPNO ENAME ANNUAL_SALARY
---------- ---------- -------------
7369 SMITH 9600
7499 ALLEN 19200
7521 WARD 15000
7566 JONES 35700
7654 MARTIN 15000
7698 BLAKE 34200
7782 CLARK 29400
7788 SCOTT 36000
7839 KING 60000
7844 TURNER 18000
7876 ADAMS 13200

EMPNO ENAME ANNUAL_SALARY
---------- ---------- -------------
7900 JAMES 11400
7902 FORD 36000
7934 MILLER 15600

14 개의 행이 선택되었습니다.

8). 사용자가 컬럼의 표제로 한 단어 이상을 사용하거나 대소문자를 반드시 구분하고자 한다면,
컬럼의 표제를 " "로 묶어야 한다. 이와 같은 경우에, Annual 과 Salary라는 단어 사이에 _를 사용하지 않아도 된다.

SQL> select empno,ename,
2 sal*12 "Annual Salary"
3 from emp;

EMPNO ENAME Annual Salary
---------- ---------- -------------
7369 SMITH 9600
7499 ALLEN 19200
7521 WARD 15000
7566 JONES 35700
7654 MARTIN 15000
7698 BLAKE 34200
7782 CLARK 29400
7788 SCOTT 36000
7839 KING 60000
7844 TURNER 18000
7876 ADAMS 13200

EMPNO ENAME Annual Salary
---------- ---------- -------------
7900 JAMES 11400
7902 FORD 36000
7934 MILLER 15600

14 개의 행이 선택되었습니다.


9). format 명령어로 컬럼의 표제를 변경하기 위해서 HEADING 옵션을 사용하는 방법이다.

SQL> col dname format a15 heading "Department Name"
SQL> select * from dept;

DEPTNO Department Name LOC
---------- --------------- -------
10 ACCOUNTING NEW YOR
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON

※ format 명령어로 컬럼 헤딩을 변경할 때 변경하려는 헤딩의 길이를 충분히 포함할 정도의 폭 넓이를 지정해 줘야 한다.
지정 폭이 충분치 않으면 변경이 제대로 되지 않고, 자릿수에 맞춰 짤리게 된다.
즉, 아래의 예에서는 "Department Name"이라는 컬럼 헤딩이 a10 자릿수 때문에 "Department"까지만 나타난다.

SQL> col dname format a10 heading "Department Name"
SQL> select * from dept;

DEPTNO Department LOC
---------- ---------- -------
10 ACCOUNTING NEW YOR
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON

★★★
10). 총계와 소계
오라클 자체내에서도 총계를 계산하기 위하여 sum함수를 내장하고 있지만,
SQL*Plus도 소계, 평균과 총계를 포함하는 요약 줄을 출력하기 위한 break 와 compute 명령어를 제공하고 있다.

comp[ute] 함수(avg,count,max,min,std,sum,var) [lab[el] 텍스트]...
of 계산을 수행할 대상 컬럼명
on 구분이 되는 (break에 사용되는) 컬럼명, 식, 별칭
report

compute 명령에 사용되는 함수
----------------------------------------------
함수 설명
----------------------------------------------
avg 평균값
cou[ut] Null이 아닌 값의 갯수
max[imum] 최대값
min[imum] 최소값
std 표준편차
sum 값의 합계
var[iance] 분산값
----------------------------------------------

emp 테이블의 부서별로 급여 합계를 구하고, 보고서 끝에는 전체 합계를 구하는 보고서를 작성하고 싶다.
부서번호와 사원번호 순서로 정렬을 한다. 부서별 합계를 구한 후에 한줄을 건너뛰게 하고,
부서번호가 중복해서 인쇄되는 것을 막고자 한다.

10-1. 먼저 deptno별로 한 줄을 건너 뛰게 하기 위해서 다음과 같이 한다.
SQL> break on deptno skip 1 on report
10-2. 부서별 급여 합계를 구하고 라벨을 'Subtotal'로 하기 위해선 다음과 같이 한다.
SQL> compute sum label 'Subtotal' of sal on deptno
10-3. 보고서 끝 부분에 한 번 전체 합계를 구해서 라벨을 "Grand Total"로 하기 위해선 다음과 같이 한다.
SQL> compute sum label 'Grand Total' of sal on report
10-4. 그리고, 앞에서 지정한 급여 sal의 포맷 '$9,999'는 합계액에는 부족하므로 늘리도록 한다.
SQL> col sal format $999,999
10-5. 보고서 형식 준비가 끝났으므로, 적당한 질의를 실행시켜 본다.
SQL> select deptno, empno, ename, sal
2 from emp
3 order by deptno, empno;

DEPTNO EMPNO ENAME SAL
---------- ---------- ---------- ---------
10 7782 CLARK $2,450
7839 KING $5,000
7934 MILLER $1,300
********** ---------
Subtotal $8,750

20 7369 SMITH $800
7566 JONES $2,975
7788 SCOTT $3,000
7876 ADAMS $1,100
7902 FORD $3,000

DEPTNO EMPNO ENAME SAL
---------- ---------- ---------- ---------
********** ---------
Subtotal $10,875

30 7499 ALLEN $1,600
7521 WARD $1,250
7654 MARTIN $1,250
7698 BLAKE $2,850
7844 TURNER $1,500
7900 JAMES $950
********** ---------
Subtotal $9,400

DEPTNO EMPNO ENAME SAL
---------- ---------- ---------- ---------

---------
Grand Tota $29,025

14 개의 행이 선택되었습니다.


11). SQL*Plus 출력에 제목달기
---- 다른 포맷팅 명령어와 관련되어, SQL*Plus는 제목을 만들기 위해 두개의 명령어를 제공한다.
ttitle은 각 페이지의 상위에 제목을 명시하기 위한 것이며, btitle은 각 페이지의 하단 부분에
제목을 명시하기 위한 명령어이다.
다음의 예에서, ttitle과 btitle은 제목, 날짜와 현재의 페이지 번호를 나타낸다.

11-1. 우선 보기 좋은 출력을 위해서 적당한 페이지 사이즈와 라인 사이즈를 지정한다.

SQL> set pages 35 ==> pagesize(축약어 pages)는 한 페이지에서의 줄의 수
SQL> set line 50 ==> linesize(축약어 line)는 출력의 한줄에 나타나는 문자의 최대수
SQL> ttitle left '2001-12-17' center 'EMP table'|'Salary Report' - 공백-(하이픈) : SQL*Plus에서 긴 명령을 다음 줄에 쓰기 위해서
> right 'Page' format 99 sql.pno ==> sql.pno는 현재의 페이지번호를 나타내는 SQL*Plus 변수
SQL> btitle '예제' ==> ttile과 btitle에서 위치를 따로 지정하지 않으면 기본적으로 가운데(center)에 위치하게 된다.
SQL> select deptno,empno,ename,sal
2 from emp
3 order by deptno,empno;


2001-12-17 EMP table|Salary Report> Page 1
DEPTNO EMPNO ENAME SAL
---------- ---------- ---------- ---------
10 7782 CLARK $2,450
7839 KING $5,000
7934 MILLER $1,300
********** ---------
Subtotal $8,750

20 7369 SMITH $800
7566 JONES $2,975
7788 SCOTT $3,000
7876 ADAMS $1,100
7902 FORD $3,000
********** ---------
Subtotal $10,875

30 7499 ALLEN $1,600
7521 WARD $1,250
7654 MARTIN $1,250
7698 BLAKE $2,850
7844 TURNER $1,500
7900 JAMES $950
********** ---------
Subtotal $9,400

---------
Grand Tota $29,025





예제

14 개의 행이 선택되었습니다.


★★★ SQL*Plus 시스템 변수 ★★★

SQL*Plus는 각각의 SQL*Plus 세션의 특성을 통제하는 많은 시스템 변수를 채택하고 있다.
예를 들어, SET명령어는 특정 값으로 시스템 변수를 설정하며, SHOW명령어는 시스템 변수의
현재 설정을 볼 수 있다. 또한 사용자는 모든 시스템 변수 설정을 보기 위하여 SHOW ALL명령어를 사용한다.

SQL> show all

▶ autocommit
autocommit(축약어 auto)은 SQL*Plus의 트랜잭션을 실행완료(commit)하는 방법을 통제한다.
autocommit이 on으로 설정되어 있으면, SLQ*Plus는 각각의 SQL문이 처리된 후에 실행완료된다.
즉, autocommit이 on으로 설정된 상태에서, 사용자가 실수로 테이블에서 일부 레코드들을 삭제했다면
사용자는 트랜잭션을 rollback 할 수 없다.
사용자는 일반적으로 autocommit을 off로 설정하는 것이 좋다.

SQL> show autocommit
autocommit OFF

▶ echo
SQL*Plus가 처리하는 SQL문을 반복하지 않으려면, echo를 off로 설정한다. 일반적으로 결과물을 만들어낸 SQL문 없이,
원하는 결과문만을 보고싶은 보고서를 준비하는 경우에 off로 설정한다.

SQL> show echo
echo OFF

▶ feedback
시스템 변수 feedback(축약어 feed)은 질의가 반환하는 레코드 수를 SQL*Plus가 나타내는 시기를 통제한다.
feedback의 기본적인 설정은 6이다. 즉, 질의가 6개 이상의 레코드를 조회하면, SQL*Plus는 레코드의 수를 보여준다.
질의가 6개 미만을 반환하면, SQL*Plus는 이 feedback 기능을 제공하지 않는다.
사용자는 feedback을 유발하는 레코드의 수를 설정할 수 있다.

SQL> show feedback
6 또는 그 이상의 행에 대한 FEEDBACK ON
SQL> select * from emp where deptno=10;

EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7782 CLARK MANAGER 7839 2572.5
10

7839 KING PRESIDENT 5500
10

7934 MILLER CLERK 7782 920
10


SQL> set feedback 2
SQL> select * from emp where deptno=10;

EMPNO ENAME JOB MGR HIREDATE SAL COMM
---------- ---------- --------- ---------- -------- ---------- ----------
DEPTNO
----------
7782 CLARK MANAGER 7839 2572.5
10

7839 KING PRESIDENT 5500
10

7934 MILLER CLERK 7782 920
10


3 개의 행이 선택되었습니다. <--- feedback이 나타나는 것을 볼 수 있다.

▶ heading
--- heading(축약어 head)은 기본적으로 SQL*Plus는 컬럼 표제를 나타낸다.
표제를 보지 않으려면, heading을 off로 설정하면 된다.

SQL> show heading
heading ON
SQL> set heading off
SQL> select * from dept;

10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON

▶ linesize
--- linesize(축약어 line)는 출력의 한 줄에 나타나는 문자의 최대수를 통제한다.

SQL> show line
linesize 80
SQL> set line 150

그러나 사용자가 linesize를 증가시키면, 메뉴바에서 '옵션--환경'을 선택한 후
윈도우 스크린 버퍼의 너비도 늘려야 한다.

SQL> select * from emp where deptno=10;

EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- -------- ---------- ---------- ----------
7782 CLARK MANAGER 7839 2572.5 10
7839 KING PRESIDENT 5500 10
7934 MILLER CLERK 7782 920 10

▶ long
사용자가 한 컬럼에 2,000자 이상을 반드시 저장해야 한다면, 사용자는 오라클의 long 데이터형을 사용하여
컬럼을 정의해야 할 것이다. SQL*Plus는 사용자가 long 시스템 변수를 늘리지 않는 한,
long 컬럼의 80자 이상은 나타내지 않을 것이다. 사용자가 예를 들어 5,000자 까지 나타내야 한다면,
long을 5,000으로 설정해야 한다. 이밖에도 사용자는 arraysize(축약어 array)를 1로 줄여야 한다.
arraysize는 데이트베이스의 데이터 인출 크기를 가리키는 환경 변수이다.

SQL> show long
long 80
SQL> show arraysize
arraysize 15

▶ pagesize
pagesize(축약어 pages)는 한 페이지에서의 줄의 수를 정의하며, 컬럼의 표제와 페이지 제목이 표현되어야
할 시기를 결정한다. 사용자가 모든 제목과 컬럼 표제를 없애려면, pagesize를 0으로 설정한다.

SQL> show pagesize
pagesize 14
SQL> set pagesize 0
SQL> select * from dept;
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON

SQL> set pages 24

▶ pause
사용자가 많은 레코드를 조회하는 질의를 실행하면, SQL*Plus의 기본적인 행동은 스크린에 그 결과를 쉴새 없이 보낸다.
사용자가 pause(축약어 pau)를 on 또는 문자열로 설정하면, SQL*Plus는 사용자가 리턴키를 누른 후에 다음 결과를 스크린에
계속 보내게 된다.

SQL> select * from user_tables;

SQL> show pause
PAUSE는 OFF
SQL> set pause on
SQL> select * from user_tables;

▶ time
사용자는 time(축약어 ti)을 on으로 설정하여, SQL*Plus 프롬프트에 현재 시각을 포함시킬 수 있다.
사용자는 출력을 파일로 spooling 할 때, 이 설정이 유용하다는 것을 알게 될 것이다.

SQL> show time
time OFF
SQL> set time on
12:08:37 SQL> set time off
SQL>

▶ timing
timing(축약어 timi)은 각각의 SQL명령어에 대한 게시(timing) 통계의 표현을 on 또는 off로 설정한다.
SQL> show timing
timing OFF
SQL> set timing on
SQL> select * from dept;

DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON

경 과: 00:00:00.10

SQL> set timing off


▶ 대입변수를 사용한 질의 작성하기

-- SQL*Plus 내에서, 사용자는 SQL문에서 대입 변수를 참조할 수 있다.
대입 변수로 사용자는 다른 값으로 동일한 SQL문을 재실행할 수 있다.
한 개 또는 두개의 &로 사용자 변수명 앞에 두어 대입 변수를 표시한다.

SQL> select empno,ename,job,sal
2 from emp
3 where sal > &sal_value;
sal_value의 값을 입력하십시오: 3000
구 3: where sal > &sal_value
신 3: where sal > 3000

EMPNO ENAME JOB SAL
---------- ---------- --------- ----------
7839 KING PRESIDENT 5500
7566 JONES MANAGER 3123.75
7658 CHAN ANALYST 3450

그런데, sal이 4000 보다 큰 사원들도 결과로 얻고 싶다. 이 때에는 질의문을 두 번 작성하지 않고,
대입변수를 사용하면 간단히 해결할 수 있다.

SQL> /
sal_value의 값을 입력하십시오: 4000
구 3: where sal > &sal_value
신 3: where sal > 4000

EMPNO ENAME JOB SAL
---------- ---------- --------- ----------
7839 KING PRESIDENT 5500

<예제2>
SQL> select empno,ename,job,sal
2 from emp
3 where sal > &sal_value
4 and lower(job) like '%&job_value%'; -- 문자열 변수에는 반드시 ' '를 한다.
sal_value의 값을 입력하십시오: 3000
구 3: where sal > &sal_value
신 3: where sal > 3000
job_value의 값을 입력하십시오: manager
구 4: and lower(job) like '%&job_value%'
신 4: and lower(job) like '%manager%'

EMPNO ENAME JOB SAL
---------- ---------- --------- ----------
7566 JONES MANAGER 3123.75


▶ 사용자 변수를 설정하는 다른 방법
SQL*Plus는 사용자 변수를 설정하는 define과 accept 명령어가 있다.
define 명령어로 사용자는 사용자 변수를 만들고 문자 값을 여기에 부여할 수 있다.
특히, define명령어는 char 데이터형을 정의하고 싶을 때 많이 사용한다.

SQL> define job_value = 'MANAGER'
SQL> select empno,ename,job,sal
2 from emp
3 where upper(job) like '%&job_value%';
구 3: where upper(job) like '%&job_value%'
신 3: where upper(job) like '%MANAGER%'

EMPNO ENAME JOB SAL
---------- ---------- --------- ----------
7782 CLARK MANAGER 2572.5
7566 JONES MANAGER 3123.75

define으로 정의된 변수는 undefine 명령을 사용할 때까지 그 상태를 유지하게 된다.

SQL> undefine job_value

=============================================================
d:\g\db\oracle\new_mine\대입변수.sql의 내용

accept job_value prompt '직업명을 입력하세요: '

select empno,ename,job,sal
from emp
where lower(job) = '&job_value'
/
=============================================================

SQL> @ d:\g\db\oracle\new_mine\대입변수.sql
직업명을 입력하세요: clerk
구 3: where lower(job) = '&job_value'
신 3: where lower(job) = 'clerk'

EMPNO ENAME JOB SAL
---------- ---------- --------- ----------
7934 MILLER CLERK 920


원문: http://blog.naver.com/lyjiny/60002865980
반응형

'ORACLE > SQL' 카테고리의 다른 글

NOT IN과 NOT EXISTS의 차이점  (0) 2010.04.02
EXECUTE IMMEDIATE를 이용한 Dynamic SQL  (0) 2010.01.04
DB 최적화를 고려한 다건조회 페이징처리  (0) 2010.01.03
SQL TIP  (0) 2010.01.03
nvl2  (0) 2010.01.03
Posted by [PineTree]
ORACLE/SQL2010. 1. 3. 14:10
반응형

오라클(Oracle)을 사용하여 다건조회(페이징) 처리를 해야하는 경우가 종종 있습니다.

물론 SQL 쿼리는 여러가지 방식으로 만들수 있고
다양한 방식이 존재하기에 어느하나가 정답이라고 할 수는 없습니다.


다만 실제 업무에서 개발중인 노하우를 공유하는 일환으로
다건조회(페이징) 처리시 DB의 성능 (대부분은 검색 속도와 관련된 부분이겠지요..)과 관련한 최적화된 쿼리 방식을 알려드리도록 하겠습니다.

이는 실제 DBA에게서 권고 받은 것이기 때문에 검증을 거쳤다고 할 수 있습니다.

자 그럼 아래를 참고하시어 최적화된 다건조회 쿼리 작성에 도움이 되시길 바랍니다.

## 1개 컬럼으로 페이징처리

SELECT *
FROM (
 SELECT ...
 WHERE ...
 AND A >= : io_nx_a
 ORDER BY A
)
WHERE ROWNUM <= 51

## 2개 컬럼으로 페이징처리

SELECT *
FROM (
SELECT ...
WHERE ///
AND A >= :io_nx_a
AND ( A > :io_nx_a
    OR ( A = :io_nx_a AND B >= :io_nx_b)
)
ORDER BY A, B)
WHERE ROWNUM <= 51

## 3개 이상의 다수개 컬럼으로 페이징처리

예) 5개 컬럼일 경우

SELECT *
FROM (
SELECT ...
WHERE ///
AND A >= :io_nx_a
AND (  A > :io_nx_a
     OR ( A = :io_nx_a AND B > :io_nx_b) )
     OR ( A = :io_nx_a AND B = :io_nx_b AND C > :io_nx_c)
     OR ( A = :io_nx_a AND B = :io_nx_b AND C = :io_nx_c AND D > :io_nx_d)
     OR ( A = :io_nx_a AND B = :io_nx_b AND C = :io_nx_c AND D = :io_nx_d AND E >= :io_nx_e)
)
ORDER BY A, B, C, D, E)
WHERE ROWNUM <= 51

(*) 제일 마지막의 OR에서만 '>='이고 나머지 OR에서는 '>'입니다.
반드시 ORDER BY에 기술된 컬럼들이 UNIQUE여야 하고 UNIQUE가 아닐 경우 이미 가이드 했던 것처럼 ROWID를 이용하셔야 합니다. SQL 가이드 참조

DBA의 말에 따르면 위와같은 방식으로
페이징 처리를 해주는 것이 DB(데이타베이스)의 성능향상에 도움이 된다더군요.

실제 예제는 아래처럼 사용됩니다.

SELECT /*+TB_CS_JH_CH_MCHTGRP_VS0001*/ *
 FROM
(
 SELECT
         a.mcht_grp_no,
         b.mcht_grpnm,
         a.mcht_no,
         c.mcht_mtalnm,
         a.apl_st_dt,
         a.apl_ed_dt
 FROM
       tb_cs_jh_ch_mchtgrp  a,
       tb_cs_jh_cm_mchtgrp  b,
       tb_cs_mc_cm_bsc      c
 WHERE a.mcht_no >= :mcht_no
   AND ( a.mcht_no > :mcht_no
          OR ( a.mcht_no = :mcht_no AND a.mcht_grp_no > :mcht_grp_no )
          OR ( a.mcht_no = :mcht_no AND a.mcht_grp_no = :mcht_grp_no  AND a.apl_st_dt >= :apl_st_dt )
           )

  AND  b.mcht_grp_no  =  a.mcht_grp_no 
     AND  b.apl_st_dt    <=  a.apl_st_dt
      AND  b.apl_ed_dt    >=  a.apl_ed_dt
     AND  c.mcht_no      =  a.mcht_no
 ORDER BY
       a.mcht_no, a.mcht_grp_no, a.apl_st_dt
)
WHERE ROWNUM <= 16

설명을 덧붙이자면
페이징시  메인 키가 되는 A >= :io_nx_a 의 인덱스서칭 시간만큼
OR을 동반한 올 시퀀스 서치시간을 줄여줄 수 있기 때문에 실제로 DB 검색시 속도향상 효과를 기대할 수 있습니다.

유용하게 사용하시기 바랍니다. ^^
반응형

'ORACLE > SQL' 카테고리의 다른 글

EXECUTE IMMEDIATE를 이용한 Dynamic SQL  (0) 2010.01.04
SQL *Plus 명령어와 SQL문 구분하기  (0) 2010.01.03
SQL TIP  (0) 2010.01.03
nvl2  (0) 2010.01.03
UNION  (0) 2010.01.03
Posted by [PineTree]
ORACLE/SQL2010. 1. 3. 13:19
반응형
* 이 팁들은 oracleclub.com의 질문과 답변에 올라온 글을 제가 정리했습니다.
 
1. 10%를 랜덤하게 가져옵니다.(오라클 8.1.7 이상부터 지원이 됩니다.) [하얀그림자님 답변글]

SQL> SELECT *
        FROM table_name
        SAMPLE (10);

 

2. 오라클에서 CASE문 사용 예제 [하얀그림자님 답변글]

SQL>SELECT col,
           CASE
             WHEN col >= 0  AND col < 6  THEN ’A’
             WHEN col >= 6  AND col < 14 THEN ’B’
             WHEN col >= 14 AND col < 22 THEN ’C’
             WHEN col >= 22 THEN ’D’
           END
      FROM table_name;




3. 해당년도의 선택된 주의 첫번째 날자를 구하고 싶습니다.[석철희님 답변글]

[질문]
해당년도의 선택된 주의 첫번째 날자를 구하고 싶습니다.
 
예로 2002년 36번째 주의 첫번째 날자는 2002/09/02입니다.
2002년 36번째주를 가지고 ’2002/09/02’이란 해당주의 첫번째 날자를 구하고 싶습니다.
 

[답변][석철희님 답변글]

SQL> SELECT NEXT_DAY(TO_DATE(해당년도||’0101’,’RRRRMMDD’) + (선택한주 - 2) * 7, 2)
         FROM DUAL;
 

SQL> SELECT NEXT_DAY(TO_DATE(2003||’0101’,’RRRRMMDD’) + (2 - 2) * 7, 2)
         FROM DUAL;
NEXT_DAY
--------
03/01/06
 
 
==> FROM 앞에 2 는 월요일을 그 주에 첫번째로 선택한 거니깐 일요일을
    그 주의 첫번째 날로 바꾸시려면 1로 바꾸시면 됩니다.
 


4. DB 테이블 내용 복사 대해서[하얀그림자님 답변글] 

1). Table A와 Table B 가 있는데. A의 내용을 B로 복사하는 방법

SQL>INSERT INTO b SELECT * FROM a;
 
 
2). Table A가 있고 Table B를 생성하면서 복사하는 방법

SQL>CREATE TABLE b AS SELECT * FROM a;


3). Table A가 있고 Table A와 구조가 같고 내용은 복사하지 않는 Table B 생성 방법
 
SQL>CREATE TABLE b AS SELECT * FROM a WHERE 1 = 2;



5.점수별로 몇명씩 있는지 알고 싶습니다 .[배경열님 답변글]
 
[질문]
이름 점수
===============
홍길동 90
김길동 98
이길동 75
성춘향 60
이동국 30
최성국 100
김남일 85
 
일때 .....
점수별로 몇명씩 있는지 알고 싶습니다 ..
 
원하는 결과값
=============
점수대 명수
===============
90-100 3
80-89 1
0-79 3


[답변 ]
Sign Function을 쓰세요.
SELECT
        DECODE(SIGN(점수-89),1,’90-100’,
        DECODE(SIGN(점수-79),1,’80-89’,’0-79’)),
        COUNT(*)
FROM
        성적
GROUP BY
        DECODE(SIGN(점수-89),1,’90-100’,
        DECODE(SIGN(점수-79),1,’80-89’,’0-79’))
ORDER BY 1 DESC




6. 컬럼에 해당하는 테이블명 알아내기..
 
SQL>SELECT TABLE_NAME
        FROM  USER_TAB_COLS
        WHERE COLUMN_NAME =’BOARD_ID’
 
이렇게 하시면 됩니다..
컬럼관련 정보는 USER_TAB_COLS 데이터사전을 통해 확인할 수 있습니다.
COLS라는 시노님을 이용해도 됩니다.


SQL>SELECT COUNT(COLUMN_NAME) "Column Count"
    FROM COLS
    WHERE TABLE_NAME =’STORM_BOARD’



시간날때마다 틈틈히 추가하겠습니다.      

  ================================================
    * 데이터베이스 정보공유 커뮤니티 oracleclub.com
    * 강좌 작성자 : 김정식 (oramaster _at_ naver.com)
  ================================================
※ oracleclub 강좌를 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
※ oracleclub 강좌는 개인의 학습용으로만 사용 할 수 있습니다. 학원 홍보용이나 수익을 얻기 위한 용도로
    사용을 하시면 안됩니다. ^^
반응형

'ORACLE > SQL' 카테고리의 다른 글

SQL *Plus 명령어와 SQL문 구분하기  (0) 2010.01.03
DB 최적화를 고려한 다건조회 페이징처리  (0) 2010.01.03
nvl2  (0) 2010.01.03
UNION  (0) 2010.01.03
case  (0) 2010.01.03
Posted by [PineTree]
ORACLE/SCRIPT2010. 1. 3. 13:12
반응형
1. 테이블에 걸려있는 제약 조건의 확인

- USER_CONS_COLUMNS : 컬럼에 할당된 제약 조건을 볼 수 있습니다.

- USER_CONSTRAINTS : 유저가 소유한 모든 제약 조건을 불 수 있습니다.  

이 두개의 데이터사전을 참조 하면 됩니다.
 

 SQL> SELECT  SUBSTR(A.COLUMN_NAME,1,15) COLUMN_NAME,        -- 컬럼명
               DECODE(B.CONSTRAINT_TYPE,
                                         ’P’,’PRIMARY KEY’,
                        ’U’,’UNIQUE KEY’,
                      ’C’,’CHECK OR NOT NULL’,
                                        ’R’,’FOREIGN KEY’) CONSTRAINT_TYPE,      -- 제약조건 TYPE
              A.CONSTRAINT_NAME   CONSTRAINT_NAME             -- 제약 조건 명
        FROM  USER_CONS_COLUMNS  A,  USER_CONSTRAINTS  B  
        WHERE  A.TABLE_NAME = UPPER(’&table_name’)  
            AND  A.TABLE_NAME = B.TABLE_NAME  
            AND  A.CONSTRAINT_NAME = B.CONSTRAINT_NAME  
        ORDER BY 1;  

-- 테이블 명을 입력 하면 됩니다.
table_name의 값을 입력하십시오: emp2

 
COLUMN_NAME             CONSTRAINT_TYPE   CONSTRAINT_NAME
------------------------------ ----------------- -------------------------
DEPTNO                   CHECK OR NOT NULL      SYS_C001362   
                               FOREIGN KEY                EMP2_FK_DEPTNO
EMPNO                     PRIMARY KEY               EMP2_PK_EMPNO
ENAME                     CHECK OR NOT NULL     EMP2_NN_ENAME
MGR                        UNIQUE KEY                  EMP2_UP_MGR

  emp2 테이블의 모든 제약조건을 보여주고 있습니다.

  SYS로 시작하는 CONSTRAINT명은 USER가 CONSTRAINT NAME을 지정하지 않아
  SYSTEM에서 DEFAULT로 생성한 경우를 보여 줍니다.

 

 


2. 테이블의 특정 컬럼에 걸려있는 제약 조건의 확인

USER_CONS_COLUMNS : 컬럼에 할당된 제약 조건을 볼 수 있습니다.

SQL>SET LINESIZE 300

SQL>SELECT SUBSTR(TABLE_NAME,1,15)    TABLE_NAMES,  
              SUBSTR(COLUMN_NAME,1,15)   COLUMN_NAME,  
            SUBSTR(CONSTRAINT_NAME,1,25) CONSTRAINT_NAME  
    FROM USER_CONS_COLUMNS  
    WHERE TABLE_NAME = UPPER(’&table_name’)  
        AND COLUMN_NAME = UPPER(’&column_name’);  
   
 
table_name의 값을 입력하십시오: emp2
column_name의 값을 입력하십시오: empno
 
TABLE_NAMES        COLUMN_NAME    CONSTRAINT_NAME
-----------------     -------------         -----------------
EMP2                     EMPNO                EMP2_PK_EMPNO

emp2테이블의 empno 컬럼의 제약조건을 보여 줍니다.


  ================================================
    * 데이터베이스 정보공유 커뮤니티 oracleclub.com
    * 강좌 작성자 : 김정식 (oramaster _at_ naver.com)
  ================================================
※ oracleclub 강좌를 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
※ oracleclub 강좌는 개인의 학습용으로만 사용 할 수 있습니다. 학원 홍보용이나 수익을 얻기 위한 용도로
    사용을 하시면 안됩니다. ^^

반응형
Posted by [PineTree]
ORACLE/SQL2010. 1. 3. 13:11
반응형

NVL2라는 함수 DECODE랑 조금 비슷한 놈 같기도 하고요..
참 편한놈이네용..

문법
NVL2(expr,expr1,expr2);


expr의 값이 null이 아닐 경우에는  expr1의 값을 반환 하고요 null일 경우에는 expr2의 값을 반환 합니다.



예제)

-- 보통 SQL문을 실행 했을 경우
SQL>  SELECT ename, comm FROM emp;

ENAME                      COMM
---------------- ----------
SMITH              
ALLEN                        300
WARD                        500
JONES              
MARTIN                     1400
BLAKE               
CLARK               
SCOTT              
KING                
TURNER                        0
ADAMS            



-- NVL함수를 사용 했을 경우

SQL>SELECT ename, NVL(comm, 0) comm  FROM emp;

ENAME                      COMM
---------------- ----------
SMITH                           0
ALLEN                        300
WARD                         500
JONES                           0
MARTIN                     1400
BLAKE                            0
CLARK                            0
SCOTT                           0
KING                               0
TURNER                         0
ADAMS                           0



-- NVL2함수를 사용 했을 경우

SQL>SELECT ename, NVL2(comm, 1, 0) FROM emp;


ENAME                      COMM
--------------- ----------
SMITH                          0
ALLEN                          1
WARD                          1
JONES                          0
MARTIN                        1
BLAKE                          0
CLARK                          0
SCOTT                         0
KING                             0
TURNER                        1
ADAMS                         0


  ================================================
    * 데이터베이스 정보공유 커뮤니티 oracleclub.com
    * 강좌 작성자 : 김정식 (oramaster _at_ naver.com)
  ================================================
※ oracleclub 강좌를 다른 웹 페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^^
※ oracleclub 강좌는 개인의 학습용으로만 사용 할 수 있습니다. 학원 홍보용이나 수익을 얻기 위한 용도로
    사용을 하시면 안됩니다. ^^
반응형

'ORACLE > SQL' 카테고리의 다른 글

DB 최적화를 고려한 다건조회 페이징처리  (0) 2010.01.03
SQL TIP  (0) 2010.01.03
UNION  (0) 2010.01.03
case  (0) 2010.01.03
NVL,DECODE  (0) 2010.01.03
Posted by [PineTree]
ORACLE/SQL2010. 1. 3. 10:50
반응형

- 유니온(UNION)

SELECT * FROM A
UNION (ALL)
SELECT * FROM B

A 와 B 의 테이블의 해당하는 컬럼들을 연결하여 보여줍니다.
OR과 유사하다고 생각하면 되며 실제로 OR을 사용하는 쿼리를 UNION ALL으로 대체시 수행속도를 향상할 수 있습니다.
UNION은 중복된 데이타를 제거하며 UNION ALL은 중복된 데이타를 모두 보여 줍니다.
가능하다면 UNION ALL을 사용하는 것이 좋습니다.
(DISTINCT를 사용하는 것보다는 UNION만 쓰는것이 더 효율적이라 생각됩니다.)

** 유니온(UNION) 서브쿼리 중복제거 최신건 다건조회 활용 쿼리문 **

SELECT *
FROM(

    SELECT
          ug_lim_mbdy_dsc
       ,ug_lim_mbdc
       ,apl_st_dt
       ,apl_ed_dt
       ,sp_rgn_dsc
       ,sp_rgn_tpc
       ,mcht_mtalnm
       ,mcht_bzcnm
       ,provnm
       ,ccwnm
    FROM (

     -- 가맹점일 경우
         SELECT
            a.ug_lim_mbdy_dsc
           ,a.ug_lim_mbdc
           ,a.apl_st_dt
           ,a.apl_ed_dt
           ,' ' AS sp_rgn_dsc
           ,' ' AS sp_rgn_tpc
           ,b.mcht_mtalnm
           ,' ' AS mcht_bzcnm
           ,' ' AS provnm
           ,' ' AS ccwnm
         FROM tb_cs_jh_ch_cduglimbrk a
                   ,tb_cs_mc_cm_bsc b
                   ,(
                   SELECT        -- 현재일자 이후건 모두 조회
             tup_c
            ,ug_lim_mbdy_dsc
                        ,ug_lim_mbdc
                        ,apl_st_dt
                    FROM  tb_cs_jh_ch_cduglimbrk
                    WHERE tup_c = :tup_c
                     AND apl_ed_dt >= :now_dt      /* 현재일자 */
      
        UNION    --중복제거 데이타 제거해야함
     
        SELECT         -- 과거포함 가장 최신건 조회
                tup_c
               ,ug_lim_mbdy_dsc
               ,ug_lim_mbdc
                            ,max(apl_st_dt) apl_st_dt
        FROM  tb_cs_jh_ch_cduglimbrk
         WHERE tup_c = :tup_c
         GROUP BY tup_c, ug_lim_mbdy_dsc, ug_lim_mbdc
        ) c          
         WHERE a.tup_c = :tup_c
              
         AND a.tup_c = c.tup_c
         AND a.ug_lim_mbdy_dsc = c.ug_lim_mbdy_dsc
         AND a.ug_lim_mbdc = c.ug_lim_mbdc
         AND a.apl_st_dt = c.apl_st_dt

              
          AND a.ug_lim_mbdc = b.mcht_no
          AND a.ug_lim_mbdy_dsc = '1'
      
         UNION ALL
      
         -- 업종일 경우
         SELECT
            a.ug_lim_mbdy_dsc
           ,a.ug_lim_mbdc
           ,a.apl_st_dt
           ,a.apl_ed_dt
           ,' ' AS sp_rgn_dsc
           ,' ' AS sp_rgn_tpc
           ,' ' AS mcht_mtalnm
           ,b.mcht_bzcnm
           ,' ' AS provnm
           ,' ' AS ccwnm
         FROM tb_cs_jh_ch_cduglimbrk a
                   ,tb_cs_mc_cc_bzc_c b
                  ,(
                  SELECT        -- 현재일자 이후건 모두 조회
                             tup_c
                 ,ug_lim_mbdy_dsc
                 ,ug_lim_mbdc
                   ,apl_st_dt
        FROM  tb_cs_jh_ch_cduglimbrk
         WHERE tup_c = :tup_c
              AND apl_ed_dt >= :now_dt      /* 현재일자 */
      
        UNION    --중복제거 데이타 제거해야함
     
        SELECT         -- 과거포함 가장 최신건 조회
                tup_c
               ,ug_lim_mbdy_dsc
                ,ug_lim_mbdc
               ,max(apl_st_dt) apl_st_dt
        FROM  tb_cs_jh_ch_cduglimbrk
        WHERE tup_c = :tup_c
        GROUP BY tup_c, ug_lim_mbdy_dsc, ug_lim_mbdc
        )                     
         WHERE a.tup_c = :tup_c

             AND a.tup_c = c.tup_c
             AND a.ug_lim_mbdy_dsc = c.ug_lim_mbdy_dsc
             AND a.ug_lim_mbdc = c.ug_lim_mbdc
             AND a.apl_st_dt = c.apl_st_dt

             AND a.ug_lim_mbdc = b.mcht_bzcc
             AND a.ug_lim_mbdy_dsc = '2'
               
         UNION ALL
        
         -- 특정지역일 경우
         SELECT
           a.ug_lim_mbdy_dsc
          ,a.ug_lim_mbdc
           ,a.apl_st_dt
           ,a.apl_ed_dt
           ,a.sp_rgn_dsc
           ,a.sp_rgn_tpc
           ,' ' AS mcht_mtalnm
           ,' ' AS mcht_bzcnm
           ,a.provnm
           ,a.ccwnm
         FROM tb_cs_jh_ch_cduglimbrk a
                ,(
                 SELECT        -- 현재일자 이후건 모두 조회
                 tup_c
                 ,ug_lim_mbdy_dsc
                 ,ug_lim_mbdc
                 ,apl_st_dt
      FROM  tb_cs_jh_ch_cduglimbrk
      WHERE tup_c = :tup_c
          AND apl_ed_dt >= :now_dt      /* 현재일자 */
      
        UNION    --중복제거 데이타 제거해야함
     
        SELECT         -- 과거포함 가장 최신건 조회
                  tup_c
                 ,ug_lim_mbdy_dsc
                 ,ug_lim_mbdc
     ,max(apl_st_dt) apl_st_dt
        FROM  tb_cs_jh_ch_cduglimbrk
        WHERE tup_c = :tup_c
        GROUP BY tup_c, ug_lim_mbdy_dsc, ug_lim_mbdc
                    ) b                              
         WHERE a.tup_c = :tup_c

 AND a.tup_c = b.tup_c
 AND a.ug_lim_mbdy_dsc = b.ug_lim_mbdy_dsc
 AND a.ug_lim_mbdc = b.ug_lim_mbdc
 AND a.apl_st_dt = b.apl_st_dt

 AND a.ug_lim_mbdy_dsc = '3'
    )
    WHERE ug_lim_mbdy_dsc >= :ug_lim_mbdy_dsc
      AND ((ug_lim_mbdy_dsc > :ug_lim_mbdy_dsc)
          OR (ug_lim_mbdy_dsc = :ug_lim_mbdy_dsc AND sp_rgn_dsc > :sp_rgn_dsc)
          OR (ug_lim_mbdy_dsc = :ug_lim_mbdy_dsc AND sp_rgn_dsc = :sp_rgn_dsc AND provnm > :provnm)
          OR (ug_lim_mbdy_dsc = :ug_lim_mbdy_dsc AND sp_rgn_dsc = :sp_rgn_dsc AND provnm = :provnm AND ug_lim_mbdc > :ug_lim_mbdc)
          OR (ug_lim_mbdy_dsc = :ug_lim_mbdy_dsc AND sp_rgn_dsc = :sp_rgn_dsc AND provnm = :provnm AND ug_lim_mbdc = :ug_lim_mbdc AND apl_st_dt >= :apl_st_dt)
          )

    ORDER BY ug_lim_mbdy_dsc, sp_rgn_dsc, provnm, ug_lim_mbdc, apl_st_dt

)
WHERE ROWNUM <= 16

길지만 하나의 조회 쿼리문 입니다. (이때까지 사용해본 조회 쿼리 중에서 가장 길군요.^^)

조회시 유용한 쿼리가 많이 포함되어 있으므로 천천히 읽어보시고
유용하게 활용하시기 바랍니다.

보시고 이해가 가지 않는 부분은 댓글로 질문해 주시면 성의껏 답변해 드리겠습니다.  
반응형

'ORACLE > SQL' 카테고리의 다른 글

SQL TIP  (0) 2010.01.03
nvl2  (0) 2010.01.03
case  (0) 2010.01.03
NVL,DECODE  (0) 2010.01.03
constraint 제약조건 (primary, foreign , unique,check, default)  (0) 2009.11.02
Posted by [PineTree]
ORACLE/SQL2010. 1. 3. 10:00
반응형
개별적인 값일 경우 A <> B 를 하면 C에서 A != B 와 같은 뜻으로 동작합니다.
다만 개별값이 아닌 SELECT를 이용한 조회된 그룹 혹은 조회값들이라면 아래와 같이 NOT EXISTS 쿼리문을 WHERE 절에 사용해 줌으로써 여집합의 결과를 얻을 수 있습니다.

            AND   NOT EXISTS  (   
             SELECT
              DISTINCT(b.tup_c) AS tup_c 
             FROM tb_cs_jh_ch_tupcodesvc b
             WHERE substr(b.cd_svc_c,1,2) = '60'
                 AND A.tup_c = b.tup_c
                )

위와 같은 역할을 하는 IS NULL을 사용한 다른 사용법입니다.


  AND   (
          SELECT  DISTINCT(b.tup_c) AS tup_c 
         FROM tb_cs_jh_ch_tupcodesvc b
         WHERE substr(b.cd_svc_c,1,2) = '60'
           AND A.tup_c = b.tup_c) IS NULL

SELECT를 사용한 단건 혹은 다건조회시 여러가지 옵션을 제공하며 그 옵션을 체크하여 적용시키는 경우.
즉, 여러가지 조건을 동시에 만족하는 것만의 결과값을 구해야 하는 경우 CASE 함수를 활용하여 구할 수 있습니다.

먼저 CASE 함수의 기본 형식을 알아두세요.

* CASE 함수

[ 형식 ]
               CASE 컬럼명|표현식 WHEN 조건식1 THEN 결과1
                                              WHEN 조건식2 THEN 결과2
                                              ......
                                              WHEN 조건식n THEN 결과n
                                              ELSE 결과
               END


아래는 CASE WHEN 조건 분기를 사용하여 여러조건을 동시에 만족하는(교집합) 특정 값들을 얻고, NOT EXISTS 를 써서 특정 결과를 뺀(여집합) 결과를 구하는 쿼리 예제 입니다.

  SELECT
             A.tup_c                                  AS tup_c
  FROM
  (
             SELECT A.tup_c                     AS tup_c
                        , MAX(CASE WHEN B.svc_bzcc = '00' AND :io_all_mcht = '1'  THEN '1' ELSE '0' END) AS io_all_mcht  
                        , MAX(CASE WHEN B.svc_bzcc = '01' AND :io_oiling = '1'   THEN '1' ELSE '0' END) AS io_oiling  
                        , MAX(CASE WHEN B.svc_bzcc = '02' AND :io_movie = '1'   THEN '1' ELSE '0' END) AS io_movie 
                        , MAX(CASE WHEN B.svc_bzcc = '99' AND :io_etc = '1' THEN '1' ELSE '0' END) AS io_etc 
            FROM TB_CS_JH_CH_TUPCODESVC A 
                     ,TB_CS_JH_CM_CARDSVC    B 
            WHERE A.tup_c      >=      :tup_c

AND   NOT EXISTS  (
             SELECT
              DISTINCT(b.tup_c) AS tup_c 
             FROM tb_cs_jh_ch_tupcodesvc b
             WHERE substr(b.cd_svc_c,1,2) = '60'
                 AND A.tup_c = b.tup_c
                )

             
             GROUP BY A.tup_c
            
        ) A

  WHERE a.tup_c >= :tup_c
    AND A.io_all_mcht       = :io_all_mcht  
    AND A.io_oiling         = :io_oiling 
    AND A.io_movie          = :io_movie  
    AND A.io_golf           = :io_golf 
    AND A.io_etc             = :io_etc


 GROUP BY A.tup_c
 ORDER BY A.tup_c


유용하게 사용하시기 바랍니다.
반응형

'ORACLE > SQL' 카테고리의 다른 글

nvl2  (0) 2010.01.03
UNION  (0) 2010.01.03
NVL,DECODE  (0) 2010.01.03
constraint 제약조건 (primary, foreign , unique,check, default)  (0) 2009.11.02
char 와 varchar 그리고 VARCHAR2 와 NVARCHAR2  (0) 2009.09.11
Posted by [PineTree]