sql plus

77
sqlplus scott/tiger 접접접 접접접접 접접 Lock 접 접접 접접 접접 접접접 Lock 접접접 접접접 접접접. DBA 접접접접 접접 sqlplus system/접접접접 alter user scott account unlock; connect scott/tiger 접접접 접접접접접 접접접접 접접접접 sqlplus system/change_on_install 접접접접접접 접접접. 1. SQL 접접접 접접접(DQL, Data Query Language) SELECT (접접접 접접) 접접접 접접접(DDL, Data Definition Language) 접접접접접 접접 CREATE (접접 접접) ALTER (접접 접접) DROP (접접 접접) RENAME (접접접접 접접) TRUNCATE (접접접 접접 접접 접접) 접접접 접접접(DML, Data Manipulation Language) INSERT (접접접 접접) UPDATE (접접접 접접) DELETE (접접접 접접) 접접접 접접접(DCL, Data Control Language) GRANT (접접접접접접접 접접 접접접 접접 접접) REVOKE (접접접접접접접 접접 접접접 접접 접접) 접접접접 접접접(TCL, Transaction Control Language) COMMIT (접접접접접 접접접접 접접접접) ROLLBACK (접접접접 접접) SAVEPOINT (접접접접접접 접접 접접접 접접) 접접접접접접 접접접 접접접 - 접접접접접접 접접접, 접접접접접접접, 접접 접접접 DBMS(DataBase Management System) 접접접접접접 접접접 - 접접 접접, 접접 접접 접접접접접접접, 접접 접접접 - 접접 접접, 접접접접 접접

Upload: hijunshi

Post on 22-Nov-2014

70 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: SQL Plus

sqlplus  scott/tiger 접근이  안될경우  주로  Lock이  걸려  있을  경우  이므로  Lock  을  해제해  주어야  합니다.

DBA  계정으로  접근 sqlplus  system/비밀번호

alter  user  scott  account  unlock;

connect  scott/tiger

사용자  초기암호를  변경하지  않으려면 sqlplus  system/change_on_install 을  실행시켜주면  됩니다.

1.  SQL 

데이터  질의어(DQL,  Data  Query  Language) SELECT                        (데이터  검색)

데이터  정의어(DDL,  Data  Definition  Language) 객체생성및  변경 CREATE                        (객체  생성) ALTER                        (객체  변경) DROP                          (객체  삭제) RENAME                        (객체이름  변경) TRUNCATE                    (객체의  저장  공간  삭제)

데이터  조작어(DML,  Data  Manipulation  Language) INSERT                        (데이터  입력) UPDATE                        (데이터  수정) DELETE                        (데이터  삭제)

데이터  제어어(DCL,  Data  Control  Language) GRANT                         (데이터베이스에  대한  일련의  권한  부여) REVOKE                        (데이터베이스에  대한  일련의  권한  취소)

트랜잭션  처리어(TCL,  Transaction  Control  Language) COMMIT                        (트랜잭선의  정상적인  종료처리) ROLLBACK                    (트랜잭션  취소) SAVEPOINT                  (트랜잭션내에  임시  저장점  설정)

데이터베이스  사용자 사용자   -  데이터베이스  관리자,  응용프로그래머,  최종  사용자

DBMS(DataBase  Management  System) 데이터베이스  관리자     - 자료  정의,  저장  관리 응용프로그래머,  최종  사용자  -  질의  처리,  트랜잭션  관리 

저장장치 데이터베이스  관리자                  -  데이터  딕셔너리 응용프로그래머,  최종  사용자  -  데이터베이스 

Page 2: SQL Plus

2.  sql  시작 

모든  테이블  목록  확인하기 select    *  from  tab;

테이블  구조  보기 desc  salgrade;

특정  테이블의  데이터  보기 select  *  from  emp;

특정  데이터에  문자열을  더하고  싶을때 select  ename  ||  '  is  a  '  ||  job  from  emp; 결과  :  tiger  is  a  killer

중복  데이터  제거 select  distinct  deptno  from  emp;

NULL  값을  임시  특정  문자로  보여주기 set  NULL  "널값"; 복구  하려면 set  NULL  "";

3.  오라클  데이터형 

1)  NUMBER

NUMBER(precision,  scale)

precision  :  전체  자리수 scale  :  소수점  이하  자리수,  생략하면  NUMBER(precision)  정수만  표현되며,  소수점이하는  반올림됨.

12345             NUMBER(5) 123456.78        NUMBER(8,  2)

2)  DATE 기본  날짜  형식      -  YY/MM/DD    년/월/일    09/08/19    2009년/08월/19일 영문판  날짜  형식    -  DD/MON/YY   일/월/년    19/Aug/09  19일/8월/2009년 

3)  VARCHAR2 가변적인  길이의  문자열을  저장하기  위한  자료형 CHAR  형은  주어진  공간에  모자르게  입력되더라도  나머지  공간이  남아  있게  되므로  낭비가  발생하지만, VARCHAR2  는  주어진  공간안에  입력된  자료형  만큼만  할당됩니다.

VARCHAR2(20)    실제  입력  문자열    "test"  이면  20자리중  4자리만  사용하므로  나머지  16자리는  자동  할당되지  않습니다.

SQL문은 Relation 이라 불리는 테이블을 저장 단위로 생각하는  RDB(Relational DataBase)에서 저장, 수정, 삭제, 추출을 위해   미국표준협회(ANSI)에서 표준으로 채택한 언어인 반면  SQL Plus

Page 3: SQL Plus

명령어는 오라클사가 그러한 SQL문을 사용자가 데이터베이스에 입력하고 그 결과를 받을 수 있도록 만든 툴입니다.

1.  SQL과 SQL Plus 비교

SQL 문                                          SQL  Plus  명령문 관계형 데이터베이스의 ANSI 표준언어             SQL문을 실행시킬 수 있는 오라클의 툴여러 줄 실행                                    한줄 실행종결문자(;) 필요                                종결문자  불필요연결문자 불필요                                 연결문자(-) 필요키워드 단축 불가                                키워드 단축 가능버퍼에 마지막 명령문 저장                       버퍼 저장 안함

2.  주로 사용되는 명령어

LIST,  SAVE,  GET,  EDIT,  SPOOL              편집 명령과 파일 조작RUN,  @,  /                                     실행HOST,  EXIT                                    데이터베이스 접속 및 종료LINE,  PAGE                                    출력 형식

1)  LIST

SELECT  ename,  sal*12  FROM  emp;

LIST 방금  실행한  쿼리문을  다시한번  보여줍니다. L  이라고  단축으로  실행하셔도  됩니다.

2)  RUNLIST로 버퍼에 저장된 쿼리문을 실행하기 위한 명령어입니다.RUN은 R 이나 / (슬레시)로 단축키를 사용할 수 있습니다.

3)  EDIT 버퍼에 저장된 쿼리문을 편집하기 위한 명령어 EDIT 는 ED 라는 단축키를 사용할 수 있습니다.

편집창이 호출되고 명령문을 편집완료하였다면 창을 닫으면 저장할지 여부를 묻습니다.저장하게 되면 SQL Plus 화면에 편집된 쿼리문을 보여줍니다.실행하시려면 R 이나 / 를 입력하시면 됩니다.

4)  HOST 도스 프롬프트로 나가서 다른 작업을 수행할 수 있습니다.완전히 종료되는 것은 아니고 일시적으로 수행창을 도스 프롬프트로 바꾸어 줍니다.다시 SQL Plus로 돌아가려면 도스 프롬프트 창을 닫으시면 됩니다.

5)  EXIT SQL Plus 를 완전히 종료합니다.

6)  SAVE 마지막에 실행한 명령어를 저장하는 명령어입니다. SAVE  a001

a001.sql 이 생성됩니다.

Page 4: SQL Plus

저장된 파일을 실행하려면 @a001 처럼 @기호와 파일이름을 써주고 엔터키를 누르면 됩니다.

저장된 파일에 새로운 결과를 저장하려면

select  *  from  dept; 라는  명령문을  실행했다고  본다면 

SAVE a001 REPLACE 를 실행합니다.

결과를 다시 확인하려면 불러들이면 되죠... @a001

7)  GET 파일로 저장된 쿼리문을 불러와서 보여줍니다. 실행은 R 이나 / 기호를 이용하여야 합니다.

8)  SPOOL SPOOL b001 b001 로 실행결과를 저장하겠다는 표현이며, select  *  from  emp; select  *  from  dept; 의 실행 결과를 최종 저장하기 위해선SPOOL  OFF 가 최종 실행되어야 합니다.

HOST로 잠시 도스프롬프트창으로 나가서 dir  *.lst 를 실행하시면 결과파일이 생성됨을 보실 수 있습니다.

notepad  b001.lst

exit다시 돌아옵니다.

9)  시스템 변수 설정하기 위한 SET 명령어 

형식: SET  시스템_변수명  값 

SET  HEADING  OFF

select  *  from  emp; 컬럼제목이  나오지  않게  합니다 

SET  HEADING  ON

select  *  from  emp; 다시  복원  합니다.

10) 한 화면에 출력되는 라인의 수를 결정하는 LINESIZE 변수 

SET  LINESIZE  40 desc  emp;

Page 5: SQL Plus

11)  한 페이지에 출력되는 페이지의  크기를  결정하는  PAGESIZE  변수 SET  PAGESIZE  10 select  *  from  emp;

12)  컬럼제목을  설정하기  위한  COLUMN  HEADING COLUMN  empno  HEADING  '사원번호' select  *  from  emp;

13)  컬럼에  대한  설정된  값을  확인하거나  해제하기 확인: COLUMN  empno

해제: COLUMN  empno  CLEAR

14)  컬럼  제목의  출력  형식을  변경하기  위한  COLUMN  FORMAT

COLUMN  dname  FORMAT  A10 해당  컬럼의  크기를  10으로  지정합니다.

숫자  데이터  출력형식  변경 COLUMN  sal  FORMAT  0,000,000

숫자의  경우  다시  복원하려면 COLUMN  dname  FORMAT  999999

1) 날짜형 

select  ename,  hiredate  from  emp  where  hiredate  >=  '82-01-01';

미국식일  경우 select  ename,  hiredate  from  emp  where  hiredate  >=  '01-MAR-01';

2)  와일드  카드(_)를  사용하기 select  empno,  ename  from  emp  where  ename  like  '_A%'; 제일  앞문자가  무엇이든지  두번째  문자는  반드시  A를  포함한  검색식  입니다.

3)  ESCAPE  ESCAPE  뒤에  오는  단  한글자의  와일드  카드문자를  와일드  카드가  아닌  문자  그대로  인식시키도록  합니다.

select  empno,  ename  from  emp  where  ename  like  '%\%%'  ESCAPE  '\';

\  다음의  문자를  그대로  인식  시키게  하는  옵션  입니다.

4)  IN  연산자 select  empno,  ename,  comm  from  emp  where  comm  IN  (300,  400,  500); comm(커미션)이  300,  400,  500  인  사람을  검색  합니다.

5)  BETWEEN  AND  연산자 select  empno,  ename,  sal  from  emp  where  sal  BETWEEN  500  AND  4000; 500  과  4000  사이의  급여대상자  검색식. 500  과  4000  도  범위에  들어갑니다.

Page 6: SQL Plus

일반  식으로는  sal  >=  500  AND  sal  <=  4000  이  됩니다.

6)  논리  연산자 AND OR NOT

AND  와  OR  연산자는  많이  알려진  연산자로  둘다  참이  거나  거짓일  경우와  둘중에  하나만  참이거나  거짓일  경우를  가려내기  위핸  연산자입니다.

select  empno,  ename,  comm  from  emp  where  comm  NOT  IN  (300,  400,  500); comm(커미션)이  300,  400,  500  이  모두  아닌  사람을  검색  합니다.

NOT  연산자는  NOT  IN  이외에도  NOT  like NOT  BETWEEN  A  AND  B IS  NOT  NULL  (  <>  IS  NULL)

1.  DUAL  테이블 select  10*20  from  dual;

산술   연산이나  가상  컬럼  등의  값을  한번만  출력하고  싶을때  많이  사용하는  아주  유용한  테이블입니다.

2.  숫자  함수 숫자  데이터를  처리하기  위한  함수.

1)  ROUND(반올림)  함수 

select  round(45.293,  2)  from  dual; 결과  :  45.29 소수점에서  2  지점은  .  에서  오른편을  말합니다.  즉,  3가  대상이  됩니다. 3은  반올림  대상  숫자가  아니므로  9는  변하지  않습니다.

select  round(45.293,  1)  from  dual; 결과  :  45.3 소숫점에서  1  지점은  .  에서  오른편을  말합니다.  즉,  9가  대상이  됩니다. 9는  반올림  대상  숫자이므로  2가  3으로  반올림되었습니다. 

select  round(45.293,  0)  from  dual; 결과  :  45 소수점에서  0지점은  .  에서  오른편을  말합니다.  즉,  2가  대상이  됩니다. 2는  반올림  대상  숫자가  아니므로  45는  변하지  않습니다.

select  round(45.293,  -1)  from  daul; 결과  :  50 소숫점에서  -1  지점은  .  에서  왼편을  말합니다.  즉,  5가  대상이  됩니다. 5는  반올림  대상  숫자이므로  45  에서  50으로  변경되었습니다.

2)  TRUNC(버림)  함수 select  trunc(45.196,  2)  from  dual;

Page 7: SQL Plus

결과  :  45.19 소숫점에서  2  지점은  .  에서  오픈편을  말합니다.  즉,  6이  대상이됩니다.

3)  MOD(나머지  구하는)  함수 select  sal,  mod(sal,  100)  from  emp;

select  *  from  emp  where  mod(empno,  2)  =  1;

3,  문자  처리  함수 1)  UPPER 대문자로  변환시킨다.

select  upper('aBcD')  from  dual;

2)  LOWER 소문자로  변환시킨다.

select  lower('aBcD')  from  dual;

3)  INITCAP 이니셜만  대문자로  변환시킨다.

select  initcap('Welcome  to  Oracle  10g')  from  dual; 결과  :  Welcome  To  Oracle  10g

select  initcap(ename)  from  emp; 결과  :  영문  이름의  제일  앞자만  대문자로  변환됨.

4)  LENGTH 문자열의  길이를  알려준다.

select  length('Welcome  to  Oracle  10g')  from  dual; 결과  :  21

5)  INSTR 특정문자가  출현하는  위치를  알려준다.

select  instr('Welcome  to  Oracle  10g',  'o',  3,  2)  from  dual; 결과  :  10

영소문자   'o'  를  찾기  위해  3번째  문자열  부터  시작해서   'o'  문자를  찾은  두번째의  위치의  자리수를  구함. 3번째  자리  부터  :  'l' 첫번째  'o'  의  위치  :  5 두번째  'o'  의  위치  :  10

select  ename,  instr(ename,  'A')  from  emp; 이름에  'A'  자가  몇  번째에  위치하는지  출력.

6)  SUBSTR 문자의  일부분을  추출한다.

select  substr('Welcome  to  Oracle  10g',  4,  3)  from  dual;

Page 8: SQL Plus

네번째  문자  'c'  부터  3개  문자인  'com'  을  추출한다.

select  substr('Welcome',  -3,  2)  from  dual; 오른쪽에서  세번째  문자  'o'  부터  2개  문자인  'om'  을  추출한다.

7)  LPAD 오른쪽  정렬  후  왼쪽에  생긴  빈  공백에  특정  문자를  채운다.

select  lpad('Oracle  10g',  20,  '#')  from  dual; 결과  :  ##########Oracle#10g lpad는  기호  문자가  왼쪽에  채워집니다.

8)  RPAD 왼쪽  정렬  후  오른쪽에  생긴  빈  공백에  특정  문자를  채운다.

select  rpad('Oracle  10g',  20,  '#')  from  dual; 결과  :  Oracle#10g########## rpad는  기호  문자가  오론쪽으로  채워집니다.

9)  LTRIM 왼쪽에서  특정  문자를  삭제한다.

select  ltrim('aaaOracle  10gaaa',  'a')  from  dual; 결과  :  Oracle  10gaaa

select  ltrim('      Oracle  10g      ')  from  dual; 결과  :  Oracle  10g              문자열  왼쪽만  삭제됨.

10)  RTRIM 오른쪽에서  특정  문자를  삭제한다.

select  rtrim('aaaOracle  10gaaa',  'a')  from  dual; 결과  :  aaaOracle  10g

select  rtrim('    Oracle  10g      ')  from  dual; 결과  :          Oracle  10g문자열  오른쪽만  삭제됨.

11)  TRIM 앞뒤에서특정  문자를  삭제한다.

select  ename,  trim('A'  from  ename)  from  emp;

select  trim('A'  from  'AaaaA')  from  dual; 결과  :  aaa

12)  BETWEEN  A  AND  B

select  hiredate  from  emp  where  hiredate  between  '17-DEC-80'  and  '09-JUN-99';

4.  날짜  관련  함수 날짜  데니터  타입에  사용되는  함수.

1)  날짜  연산 SYSDATE  +  1      내일  날짜를  구함 

Page 9: SQL Plus

SYSDATE  -  1      어제  날짜를  구함 

select  sysdate  +  1  from  dual; select  sysdate  -  1  from  dual;

직원들의  현재까지  근무  일수를  구하는  쿼리문 select  ename,  hiredate,  sysdate  -  hiredate  from  emp;

2)  MONTHS_BETWEEN 날짜와  날짜  사이의  개월을  계산한다.  (숫자  반환)

select  sysdate,  hiredate,  months_between(sysdate,  hiredate)  from  emp;

3)  ADD_MONTHS 날짜에  개월을  더한  날짜  계산  (날짜  반환)

select  hiredate,  add_months(hiredate,  6)  from  emp;

4)  NEXT_DAY 날짜  후의  첫  요일의  날짜  계산  (날짜  반환)

영문일  경우 

입사일  기준  최초로  도래하는  금요일  검색 select  hiredate,  next_day(hiredate,  'fri')  from  emp;

오늘이  속한  달의  마지막  날짜와  다가오는  금요일의  날짜를  검색 select  sysdate,  last_day(sysdate),  next_day(sysdate,  'fri')  from  dual;

입사  후  6개월이  지난  후  돌아오는  금요일의  날짜를  검색 select  hiredate,  add_months(hiredate,  6)  from  emp; select  next_day(add_moths(hiredate,  6),  'fri')  from  emp;

한글일  경우 select  hiredate,  next_day(hiredate,  '금')  from  emp; 한글이  인식  안될  경우 alter  session  set  NLS_LANGUAGE=K016KSC5601;

select  sysdate,  last_day(sysdate),  next_day(sysdate,  '금')  from  dual;

select  hiredate,  add_months(hiredate,  6)  from  emp; select  next_day(add_moths(hiredate,  6),  '금')  from  emp;

5)  LAST_DAY 월의  마지막  날짜를  계산  (날짜  반환) select  hiredate,  last_day(hiredate)  from  emp;

6)  ROUND 날짜를  반올림  (날짜  반환)

7)  TRUNC 날짜를  절삭  (  날짜  반환)

Page 10: SQL Plus

8)  SYSDATE  함수 시스템에  저장된  현재  날짜를  반환하는  함수.  (숫자  반환)

select  sysdate  from  dual;   

5.  형  변환  함수 

1)  TO_DATE 문자열을  날짜  형으로  변환하는  함수 

TO_DATE('문자열',  'format')

select  sysdate  -  to_date('2006/01/01',  'YYYY/MM/DD')  from  dual; 현재  날짜에서  2006/01/01을  뺀  결과  검색 

2)  TO_CHAR 날짜나  숫자를문자로  변환하는  함수 

TO_CHAR(number  |  date,  'format')

format의  종류 

YYYY   년도  표현(4자리) YY   년도  표현(2자리) MM   월을  숫자로  표현 MON   월을  알파뱃으로  표현 DAY   요일  표현 DY   요일을  약어로  표현 

시간  출력  형식의  종류 

AM,  PM      오전(AM),  오후(PM)  시각  표시 HH,  HH12   시간(1  ~  12) HH24      24시간으로  표현(0  ~  23) MI      분  표현 SS      초  표현 

select  to_char(sysdate,  'YYYY/MM/DD,  HH24:MI:SS')  from  dual; 현재  날짜와  시간을  출력 

select  to_char(sysdate  +  2/24,  'yyyy-mm-dd  hh:mi:ss')  from  dual; 현재  시간에  3시간을  더하여  검색 

숫자  관련  출력  형식 

9   한자리의  숫자  표현      예:  (1111,  '99999')      결과:1111  0   앞부분을  0으로표현      예:  (1111,  '099999')      결과:001111 $   달러기호를  앞에  표현      예:  (1111,  '$99999')      결과:$1111 .   소수점  표현         예:  (1111,  '99999.99')      결과:1111.00 ,   특정  위치에  ,  표시      예:  (1111,  '99,999')      결과:1,111 MI   오른쪽에  -기호  표시      예:  (1111,  '99999MI)      결과:1111-

Page 11: SQL Plus

PR   음수값을  <>으로  표현      예:  (1111,  '99999PR)      결과:<1111> EEEE   과학적표기법으로  표현      예:  (1111,  '9.999EEEE')      결과:1.111E+03 V   10^n을  곱한  값으로  표현      예:  (1111,  '999V99')      결과:111100 B   공백을  0으로  표현      예:  (1111,  'B9999.99')      결과:1111.00 L   지역  통화(Local  currency)   예:  (1111,  'L99999')      결과:\1111

select  ename,  TO_CHAR(sal,  '$999,999')  from  emp;

select  ename,  TO_CHAR(sal,  'L999,999')  from  emp;

3)  NULL  변환  함수인  NVL NULL을  0  또는  다른  값으로  변환하기  위해서  사용하는  함수.

select  ename,  sal,  comm,  sal*12+NVL(comm,  0)  from  emp; 커미션이  null경우  0으로  변경하여  연봉계산에  함산하는  검색식 

select  ename,  NVL(TO_CHAR(mgr,  '9999'),  'CEO')  from  emp; 상관(manager)가  없는  mgr  컬럼값을  문자형  데이터로  형변화해서  CEO  표현하는  검색식 

4)  C언어의  else  if  문과  같은  DECODE  함수 

select  ename,  deptno,     DECODE(deptno,     10,  'ACCOUNTING',                        20,  'RESEARCH',                        30,  'SALES',              40,  'OPERATIONS')  dname from  emp;

select  ename,  job,    DECODE(job,   'CLERK',  sal*1.05,          'MANAGER',  sal*.1.15,             sal)  as  "Up  Sal" from  emp;

직급에  따라  보너를  지급하기  위한  조건식 

직급이  MANAGER인  사원은  15%  인상하고, CLERK인  사원은  5%  인상합니다.

5)  조건에  따라  서로  다른  처리가  가능한  CASE  함수 

select  ename,  deptno,    CASE   WHEN   deptno=10   THEN   'ACCOUNTING'       WHEN   deptno=20   THEN   'RESEARCH'       WHEN   deptno=30   THEN   'SALES'       WHEN   deptno=40   THEN   'OPERATIONS'    END  AS  dname from  emp;

select  job,  sal,    CASE   WHEN   job='CLERK'   THEN   sal*1.20       WHEN   job='ANALYST'   THEN   sal*1.15       WHEN   job='MANAGER'   THEN   sal*1.10       ELSE  sal    END  AS  salary

Page 12: SQL Plus

from  emp;

그룹함수에서는  NULL  값의  결과는  제외  됩니다.

1.  COUNT 행의  갯수를  카운트 

select  count(comm)  from  emp;

select  count(comm)  form  emp  where  deptno=10;

select  count(job)  from  emp;

select  count(distinct  job)  from  emp;

select  count(*)  "total", sum(decode(to_char(hiredate,  'YYYY'),  1980,  1,  0))  "1980", sum(decode(to_char(hiredate,  'YYYY'),  1981,  1,  0))  "1981", sum(decode(to_char(hiredate,  'YYYY'),  1982,  1,  0))  "1982", sum(decode(to_char(hiredate,  'YYYY'),  1999,  1,  0))  "1999" from  emp;

년도  별로  입사한  사원수를  구하는  쿼리 

2.  SUM 해당  열의  총  행의  합계 

select  sum(sal)  from  emp;

3.  AVG 해당  열의  총  행의  평균 

select  avg(sal)  from  emp;

4.  MIN 해당  열의  총  행중에  최소  값  산출 

5.  MAX 해당  열의  총  행중에  최대  값  산출 

select  max(sal),  min(sal)  from  emp;

select  max(ename),  min(ename),  max(hiredate),  min(hiredate)  from  emp;

6.  GROUP  BY  절 select  avg(sal)  from  emp  group  by  deptno;

select  deptno,  avg(sal)  from  emp  group  by  deptno; 부서별로  급여  사항이  출력 

select  deptno,  ename,  avg(sal)  from  emp  group  by  deptno; 오류:  ename  은  group  by  절에  선언되지  않은  컬럼입니다.  sal의  경우  그룹함수를  이용하므로  오류를  발생하지  않습니다.

select  deptno,  count(*),  count(comm)  from  emp  grou  by  deptno;

Page 13: SQL Plus

부서별  전체  사원수와  커미션을  받는  사원들의  수  계산 

select  deptno,  max(sal),  min(sal)  from  emp  group  by  deptno; 부서별  최대  급여와  최소  급여  산출 

7.  HAVING  절 GROUP  BY  절에  의해  생성된  결과  값  중  원하는  조건에  부합하는  자료만  보고자  할  때  사용합니다.

select  deptno,  avg(sal)  from  emp  group  by  deptno  having  avg(sal)  >=  2000; 부서별로  평균을  구하되  평균값이  2000  이상인  자료만  산출

select  empno,  ename,  deptno  from  emp  where  empno=7900;

select  dname  from  dept  where  deptno=30;

1.  EQUI  JOIN 조인  대상이  되는  두  테이블에서  공통적으로  존재하는  컬럼의  값이  일치되는  행을  연결하여  결과를  생성하는  조인  방법.

select  ename,  dname  from  emp,  dept  where  emp.deptno=dept.deptno;

select  ename,  dname,  emp.deptno,  dept.deptno  from  emp,  dept  where  emp.deptno=dept.deptno;

select  e.name,  d.dname,  e.deptno,  d.deptno  from  emp  e,  dept  d  where  e.deptno=d.deptno;

select  ename,  dname  from  emp,  dept  where  emp.deptno=dept.deptno  and  emp.ename='SCOTT';

2.  NON-EQUI  JOIN 조인  조건에  특정  범위  내에  있는지를  조사히기  위해  where  절에  조인  조건을  =  연산자  이외의 비교  연산자를  사용합니다.

select  e.ename,  e.sal,  s.grade  from  emp  e,  salgrade  s  where  e.sal  >=  s.losal  and  e.sal  <=  s.hisal; 급여등급을   5개로   나누어  좋은   salgrade에서   정보를  얻어   와서   각   사원의  급여  등급을  지정하는  쿼리 

select  e.ename,  e.sal,  s.grade  from  emp  e,  salgrade  s  where  e.sal  between  s.losal  and  s.hisal; 위의  쿼리를  BETWEEN  A  AND  B  형식으로  수정한  쿼리문 

select  e.ename,  d.dname,  s.grade  from  emp  e,  dept  d,  salgrade  s where  e.deptno  =  d.deptno and  e.sal  between  s.losal  and  s.hisal;

3.  SELF  JOIN 같은  테이블이지만  별칭으로  다른  테이블을  조인하는  형식을  사용합니다.

select  ename,  mgr  from  emp;

Page 14: SQL Plus

select  e.ename  ||  '의  매니저는  '  ||  m.ename  ||  '입니다.' from  emp  e,  emp  m where  e.mgr=m.empno;

위의  쿼리문은   from  절로  봐서는   SELF  JOIN  이고,  where  절로  봐서는   EQUI  JOIN에도  속합니다.

4.  OUTER  JOIN 사원번호가   NULL  인   사원이   존재할때   조인조건에   만족하지   못할때,  결과에서   배제되는  경우를  해결하기  위해  해당  행을  나타내고  싶을때  사용합니다. (+)  연산자를  사용하여  NULL값이기에  배제된  행을  결과에  포함시킬수  있습니다.

select  e.ename  ||  '  의  매니저는  '  ||  m.ename  ||  '입니다.' from  emp  e,  emp  m where  e.mgr=m.empno(+);

select  e.ename,  d.dname from  emp  e,  dept  d where  e.deptno(+)  =  d.deptno;

부서번호가  없어도  출력하는  쿼리 

select  e.ename,  d.deptno,  d.dname from  emp  e,  dept  d where  e.deptno=d.deptno;

select  e.ename,  e.job,  e.deptno,  d.loc from  emp  e,  dept  d where  e.deptno=d.deptno and  e.deptno=30;

부서번호  30인  사원들을  출력하는  쿼리문 

select  e.ename,  e.comm,  d.dname,  d.loc from  emp  e,  dtpt  d where  e.detpno=d.deptno and  e.comm  IS  NOT  NULL and  e.comm  NOT  IN  (0);

커미션을  받는  사원을  출력하는  쿼리문 

select  e.ename,  e.job,  d.deptno,  d.dname from  emp  e,  dept  d where  e.deptno=d.deptno and  d.loc='DALLAS';

DALLAS에서  근무하는  사원을  출력하는  쿼리문 

select  e.ename,  d.dname from  emp  e,  dept  d where  e.deptno=d.deptno and  e.ename  like  '%A%';

이름에  A가  들어가는  사원들을  출력하는  쿼리문 

Page 15: SQL Plus

select  e.ename,  e.job,  e.sal,  s.grade from  emp  e,  salgrade  s where  e.sal  between  s.losal  and  s.hisal;

사원이름,  직급,  급여,  급여등급  출력  쿼리 

select  e.ename  "자신",  e.deptno,  c.ename  "동료",  c.deptno from  emp  e,  emp  c where  e.ename  <>  c.ename and  e.deptno=c.deptno order  by  e.ename;

SELF  JOIN 사원이름,  부서번호와  해당  사원과  같은  부서에서  근무하는  사원을  출력하는  쿼리

하나의  테이블에서  검색한  결과를  다른  테이블에  전달하여  새로운  결과를  검색하는  경우에  사용합니다.

[서브  쿼리의  예]

select  dname  from  dept  where  deptno=20; select  ename,  deptno  from  emp  where  ename='JONES';

select  dname  from  dept  where  depto=(select  deptno  from  emp  where  ename='JONES');

1.  단일  행  서브  쿼리 

하나의  행만  검색하여  그  결과를  메인  쿼리에  보내는  쿼리. 위의  JONES의  부서명을  구하는  예가  단일  행  서브  쿼리입니다.

select  e.ename,  d.dname from  emp  e,  dept  d where  e.deptno=d.deptno and  d.deptno=10

emp  테이블의  결과는  세개  입니다. 위의  경우는  EQUI  JOIN  문을  이용한  예입니다.

select  e.name,  d.dname from  emp  e, (     select  deptno,  dname      from  dept      where  deptno=10 )  d where  e.deptno=d.deptno;

같은  결과를  낼수  있는  방법중  서브쿼리를  이용하는  방법입니다.

2.  서브  쿼리에서  그룹  함수의  사용 

select  avg(sal)  from  emp; 평균  급여  구하는  쿼리 

Page 16: SQL Plus

select  ename,  sal  from  emp  where  sal  >  (select  avg(sal)  from  emp); 평균  급여보다  더  많은  급여를  받는  사원을  검색하는  쿼리 

select  ename,  sal  from  emp  where  sal  >  (select  avg(sal)  from  emp) order  by  sal  desc; 많이  받는  사람  순으로  출력  쿼리 

select  empno,  ename from  emp where  sal  =  (  select  max(sal)  from  emp  where  deptno=10  );

부서번호가   10인   사원중에서   최대  급여를   받는   사원과   동일한  급여를   받는   사원   번호와  사원명  출력 

3.  다중  행  서브  쿼리 다중  행  연산자(Multiple  Row  Operator)와  함께  사용하여  하는  서브  쿼리.

IN      메인  쿼리의  비교  조건이  서브  쿼리의  결과  중에서  하나라도  일치하면  참입니다. ANY,  SOME   메인  쿼리의  비교  조건이  서브  쿼리의  결과와  하나  이상  일치하면  참입니다. ALL      메인  쿼리의  비교  조건이  서브  쿼리의  결과와  모든  값이  일치하면  참입니다. EXIST      메인   쿼리의   비교   조건이   서브   쿼리의   결과   중에서   만족하는   값이   하나라도  존재하면  참입니다.

1)  IN  연산자 

select  deptno from  emp where  ename  =  'BLAKE';

select  ename,  hiredate,  deptno from  emp where  deptno  IN  (  select  deptno  from  emp  where  ename='BLAKE');

BLAKE의  결과값중  부서번호가  30인  사람들까지  같이  출력  됩니다.

select  ename,  hiredate from  dept where  deptno  IN  (  select  deptno  from  emp  where  ename='BLAKE'); and  ename  !=  'BLAKE'

BLAKE  는  제외하고  출력하는  쿼리 

select  distinct  deptno from  emp where  sal  >=  3000;

급여를  3000  이상  받는  사원이  소속된  부서번호는  10번  20번  입니다.

select  ename,  sal,  deptno from  emp where  deptno  =  10  or  deptno  =  20; 10,  20번  부서의  이름,  급여,  부서번호를  출력하는  쿼리 

Page 17: SQL Plus

위의  검색  조건을  합칠  경우  다음과  같은  서브  쿼리문을  사용하게  됩니다. select  ename,  sal,  deptno from  emp where  deptno  IN  (  select  deptno  from  emp  where  sal  >=  3000  );

3000  이상받는  직원과  관련된  부서의  직원들을  출력  합니다.

2)  ALL  연산자 

select  sal  from  emp  where  deptno=30; 부서번호가  30  인  사원들을  출력  합니다. 가장많은  급여는  2850  입니다.

select  ename,  sal from  emp where  sal  >  ALL(  select  sal  from  emp  where  deptno  =  30  );

30번   부서에서  급여를   가장  많이   받는   사원의  급여인   2850보다   더  높은  급여를   받는  사원들만  출력. 즉,  전체  결과에서  30번  부서에서  가장  높은  급여보다  많이  받는  사람을  구하는  겁니다.

30번  부서의  급여  최대치  2850  과  비교  될때까지  연산하는  것이  ALL  연산자  입니다.

>  ALL은  "모두다  크냐"고  묻는  것이  되므로  최대값보다  더  크면  참이  됩니다.

3)  ANY  연산자 >  ANY  는  "비교값  중  하나보다  크냐"고  묻는  것이  되므로  그  값들  중  어느  하나  보다  더  크면, 값들  중  최소값보다  더  크면  참이  됩니다.

select  ename,  sal from  emp where  sal  >  ANY  (  select  sal  from  emp  where  deptno  =  30  );

4)  싱글과  멀티 

싱글은  =,  >,  >=,  <,  <=,  !=  등  연산자만  사용 멀티는  IN,  ALL,  ANY,  SOME,  EXIST  사용 

4.  예제 1)  SCOTT의  급여와  동일하거나  더  많이  받는  사원명과  급여를  출력 select  ename,  sal from  emp where  sal  >=  (  select  sal  from  emp  where  ename='SCOTT'  );

2)  직급(job)이  사원(CLERK)인  사람의  부서를  검색 select  distinct  deptno from  emp where  job='CLERK';

직급(job)이  사원(CLERK)인  사람의  부서의  부서  번호와  부서명과  지역을  출력 

Page 18: SQL Plus

select  deptno,  dname,  loc from  dept where  deptno  IN  (  select  deptno  from  emp  where  job='CLERK'  );

3)  이름에   T를   포함하고   있는   사람들과   같은   부서에   근무하고   있는   사원의   사원번호와  이름을  출력 select  distinct  deptno  from  emp  where  ename  like  '%T%'; 먼저  T자가  포함된  부서번호를  구합니다.

select  empno,  ename from  emp where  deptno  IN  (  select  deptno  from  emp  where  ename  like  '%T%'  );

4)  부서  위치가  dallas  인  모든  사원의  이름,  부서  번호를  출력 select  ename,  deptno from  emp where  deptno  =  (  select  deptno  from  dept  where  loc='DALLAS'  );

5)  SALES  부서의  모든  사원과  이름과  급여를  출력 select  ename,  sal from  emp where  deptno  =  (  select  deptno  from  dept  where  dname='SALES'  );

6)  KING  에게  보고하는  모든  사원의  이름과  급여를  출력 KING이  매니져(mgr)라는  의미.

select  ename,  sal from  emp where  mgr  IN  (  select  empno  from  emp  where  ename='KING'  );

7)  자신의  급여가  평균  급여보다  많고  이름에  S가  들어가는  사원과  동일한  부서에서  근무하는  모든  사원의  이름,  급여를  출력 

select  empno,  ename,  sal from  emp where  deptno  IN  (  select  deptno           from  emp           where  sal  >  (  select  avg(sal)  from  emp  )           and  ename  like  '%S%'  );

1.  테이블  생성 CREATE  TABLE  테이블명 (   컬럼명  자료형 )

[오라클  자료형]

CHAR(N)      주어진  크기만큼  고정  길이의  문자  저장.  1바이트~2000바이트 VARHCAR2(N)   주어진  크기만큼  가변  길이의  문자  저장.  1바이트~4000바이트 NVARCHAR2(N)   국가별  국가  집합에  따른  크기의  문자  또는  바이트의  가변  길이  문자.  1바이트~4000바이트 NUMBER(P,  S)   정밀도와  스케일로  표현되는  숫자 DATE      날짜  형식을  지정 ROWID      테이블내  행의  고유  주소를  가지는  64진수  문자.  해당  6바이트(제한된  ROWID) 

Page 19: SQL Plus

또는  10바이트(확장된  ROWID)      BLOB      대용량의  바이너리  데이터를  저장,  최대  4GB CLOB      대용량의  텍스트  데이터를  저장,  최대  4GB BFILE      대용량의  바이너리  데이터를  파일  형태로  저장,  최대  4GB TIMESTAMP(n)   DATE형의  확장된  형태 INTERVAL  YEAR  TO  MONTH       년과  월을  이용하여  기간을  저장 INTERVAL  DAY  TO  SECOND       일,  시,  분,  초를  이용하여  기간을  저장,  두  날짜  값의  정확한  차이를  표현하는데  유용.

1)  INTERVAL  YEAR  TO  MONTH

INTERVAL  YEAR(년도에  대한  자리수)  TO  MONTH(달에  대한  자리수) 자리수를  지정하지  않으면  기본적으로  2자리가  할당됩니다.

CREATE  TABLE  sam02 (   year01  INTERVAL  YEAR(3)  TO  MONTH );

일단  잘  만들어졌는지  구조를  확인합니다. desc  sam02;

자료  입력 insert  into  sam02  values  (INTERVAL  '36'  MONTH(3));

자료  검색 select  year01,  sysdate,  sysdate+year01  from  sam02;

003-00  :  3년을  의미 sysdate  :  현재  날짜 sysdate+year01  :  현재  날짜에  3년이  지난  후의  날짜를  계산한  결과 

2)  INTERVAL  DAY  TO  SECOND

INTERVAL  DAY(일수에  대한  자리수)  TO  SECOND(초에  대한  자리수) 자리수를  지정하지  않으면  기본적으로  2자리를  할당합니다.

테이블  만들기 CREATE  TABLE  sam03 (     day01  INTERVAL  DAY(3)  TO  SECOND );

자료  입력 insert  into  sam03  values  (INTERVAL  '100'  DAY(3));

자료  검색 select  day01,  sysdate,  sysdate+day01  from  sam03; 오늘  날짜에서  100  일  후를  검색합니다.

3)  실습용  사원  테이블  생성 

CREATE  TABLE  em01

Page 20: SQL Plus

(     empno  NUMBER(4),     ename  VARCHAR2(20),     sal  NUMBER(7,  2) );

desc  em01;

4)  서브  쿼리를  이용한  테이블  생성 다른  테이블의  구조뿐만  아니라  데이터까지  복사할때  사용.

CREATE  TABLE  emp02  AS  select  *  from  emp;

desc  emp; desc  emp02; select  *  from  emp02;

CREATE  TABLE  em03  AS  select  empno,  ename  from  emp; 원하는  컬럼만  선택적으로  복사.

5)  데이터의  구조만  복사하기 create  table  em04  as  select  *  from  emp  where  1=0; where절에  거짓  조건을  주면  결과는  복사되지  않습니다.

6)  테이블  구조  변경 

create  table  em05  as  select  *  from  emp;

desc  em05;

[컬럼  추가] alter  table  em05  add(email  VARCHAR2(20));

desc  em05; 마지막  부분에  email  컬럼이  추가되었습니다.

[컬럼  변경] alter  table  em05  modify(email  VARCHAR2(40)); 변경시  데이터의  크기와  타입을  고려해야  합니다.

desc  em05;

[컬럼  삭제] alter  table  em05  drop  column  email; 삭제시  데이터까지  지워지므로  복원이  불가능합니다.

desc  em05;

다시  email  컬럼을  VARCHAR2(40)  데이터형으로  삽입합니다.

alter  table  em05  add(email  VARCHAR2(40));

삭제를  하지  않고  컬럼의  사용을  논리적으로  제한하는  방법 alter  table  em05  set  unused(email);

Page 21: SQL Plus

desc  em05; 컬럼  리스트에서  보이지  않습니다.

그후  가장  사용빈도가  적은  시간에  실제적인  삭제  작업을  진행합니다. alter  table  em05  drop  unused  columns;

desc  em05;

[테이블  제거] DROP  TABLE  em04; 자료가  모두  삭제  되므로  주의  해야  합니다. 나중에  찾을지  모르는  자료는  백업을  생활화  해야  합니다.

create  table  em04_bakup  select  *  from  em04; 한후에 drop  table  em04;

이렇게  해야  좋습니다.  ㅋ 

[테이블의  모든  로우(데이터)  제거] select  *  from  em05;

truncate  table  em05;

[데이터  딕셔너리와  데이터  딕셔너리  뷰] Data  Dictionary는  데이터베이스  자원을  효율적으로  관리하기  위한  다양한  정보를  저장하는  시스템  테이블  입니다.  Data  Dictionary는  사용자가  테이블을  생성하거나  사용자를  변경하는  등의  작업을   할   때   데이터베이스   서버에   의해   자동으로   갱신되는   테이블로   사용자는   Data  Dictionary의 내용을  직접  수정하거나  삭제할  수  없습니다.  Data  Dictionary의  내용은  암호화  되어  있습니다. 그렇기  때문에  Data  Dictionary  View가  필요하게  됩니다.

Data  Dictionary  View의  접두어 DBA_XXXX   데이터베이스  관리자만  접근  가능한  객체  등의  정보  조회 ALL_XXXX   자신  계정  소유  또는  권한을  부여  받은  객체  등에  과한  정보  조회 USER_XXXX   자신의  계정이  소유한  객체  등에  관한  정보  조회 

i)  User  데이터  딕셔너리 

show  user; 현재  사용자  계정  출력 

결과: USER  is  "SCOTT"

desc  user_tables; 자신이  소유한  모든  테이블  정보를  조회합니다.

select  table_name  from  user_tables  order  by  table_name  desc;

Page 22: SQL Plus

user_sequences   계정이  소유한  시퀀스의  정보  조회  할  수  있는  데이터  딕셔너리  뷰 user_indexes   계정이  소유한  인덱스  정보  조회  할  수  있는  데이터  딕셔너리  뷰 user_views   계정이  소유한  뷰  정보  조회  할  수  있는  데이터  딕셔너리  뷰 

ii)  ALL_  데이터  딕셔너리 다른  소유자의  객체에  접근  권한이  있는  사람이  그  객체에  접근할  경우  사용하는  뷰 

desc  all_tables; 

select  owner,  table_name  from  all_tables;

user_sequences   현재  계정이  접근  가능한  시퀀스의  정보  조회 user_indexes   현재  계정이  접근  가능한  인덱스  정보  조회 user_views   현재  계정이  접근  가능한  뷰  정보  조회 

iii)  DBA)  데이터  딕셔너리  뷰 DBA만  접근  가능한  객체등을  조회할  수  있는  뷰.

conn  system/manager

select  owner,  table_name  from  dba_tables  where  owner='SYSTEM';

conn  scott/tiger

dba_sequences   데이터베이스에  있는  모든  시퀀스의  정보  조회 dba_indexes   데이터베이스에  있는  모든  인덱스  정보  조회 dba_views   데이터베이스에  있는  모든  뷰  정보  조회

1.  INSERT  문 

INSERT  INTO  테이블명  [컬럼명]  VALUES  [값]

create  table  dept01  as  select  *  from  dept;

desc  dept01;

insert  into  dept01  (deptno,  dname,  loc)  values  (60,  'tester',  'Seoul');

select  *  from  dept01;

컬럼명에  해당되는  자료가  입력된다면  컬럼명을  생략해도  됩니다. insert  into  dept01  values  (61,  'tester2',  'Seoul');

insert  into  dept01  values(62,  'tester3',  NULL);

insert  into  dept01  values(63,  'tester4',  '');

2.  치환  변수 

select  *  from  &talbe_name; 테이블명을  입력  받습니다.

select  &column_name  from  &table_name; 컬럼명과  테이블명을  입력  받습니다.

Page 23: SQL Plus

select  *  from  emp  where  &stmt; 조건을  입력  받습니다.

select  *  from  emp  where  sal  >  &salary_value; 값을  입력  받습니다.

-  &&  연산자 입력받은  치환  변수  값이  메모리에  기억되어  계속  사용가능한  연산자 

select  *  from  emp_where  sal  >  &&salary_value;

처음  입력값을  입력하고  실행한후  위의  쿼리문을  실행하면  입력없이  실행됩니다.

3.  서브  쿼리로  로우  추가 create  table  dept02  as  select  *  from  dept  where  1=0; 1=0  은  거짓으므로  출력  결과  없이  구조만  복사해  옵니다.

insert  into  dept02  select  *  from  dept;

4.  다중  테이블에  다중  로우  입력하기 

desc  emp;

create  table  emp_hir  as  select  empno,  ename,  hiredate  from  emp  where  1=0;

create  table  emp_mgr  as  select  empno,  ename,  mgr  from  emp  where  1=0;

insert  all into  emp_hir  values(empno,  ename,  hiredate) into  emp_mgr  values(empno,  ename,  mgr) select  empno,  ename,  hiredate,  mgr from  emp where  deptno  >  20;

select  *  from  emp_hir; select  *  from  emp_mgr;

5.  조건(WHEN)에  의해  다중  테이블에  다중  로우  입력하기 

create  table  emp_hir02  as  select  empno,  ename,  hiredate  from  emp  where  1=0;

create  table  emp_sal  as  select  empno,  ename,  sal  from  emp  where  1=0;

insert  all WHEN  hiredate  >  '01-JUN-1982'  THEN into  emp_hir02  values  (empno,  ename,  hiredate) WHEN  sal  >  2000  THEN into  emp_sal  value  (empno,  ename,  sal) SELECT  empno,  ename,  hiredate,  sal  FROM  emp;

select  *  from  emp_hir02; select  *  from  emp_sal;

6.  PIVOTING  에  의해  다중  테이블에  다중  행  입력하기 

Page 24: SQL Plus

한  주차  월요일  부터  금요일까지  매일  매일의  판매  실적을  기록하는  테이블  생성 

create  table  sales (   sales_id  NUBER(4),   week_id  NUMBER(4),   mon_sales  NUMBER(8,  2),   tue_sales  NUMBER(8,  2),   wed_sales  NUMBER(8,  2),   thu_sales  NUMBER(8,  2),   fri_sales  NUMBER(8,  2) );

desc  sales;

PIVOTING  INSERT  문의  결과를저장할  sales_data  테이블  생성 

create  table  sales_data (     sales_id  NUMBER(4),     week_id  NUMBER(4),     daily_id  NUMBER(4),     sales  NUMBER(8,  2) );

desc  sales_data;

판매  실적  추가 

insert  into  sales  values  (1001,  1,  200,  100,  300,  400,  500); insert  into  sales  values  (1002,  2,  100,  300,  200,  500,  350);

select  *  from  sales;

각  요일을  구분할  수  있는  컬럼을  추가하여  매일  매일의  판매  실적을  기록합니다. insert  all into  sales_data  values(sales_id,  week_id,  1,  mon_sales) into  sales_data  values(sales_id,  week_id,  2,  tue_sales) into  sales_data  values(sales_id,  week_id,  3,  wed_sales) into  sales_data  values(sales_id,  week_id,  4,  thu_sales) into  sales_data  values(sales_id,  week_id,  5,  fri_sales) select  sales_id,  week_id,  mon_sales,  thu_sales,  wed_sales,  thu_sales,  fri_sales  from  sales;

select  *  from  sales_data;

7.  UPDATE  문 

UPDATE  테이블명  SET  컬럼명=변경할값 WHERE  조건 

create  table  dept02  as  select  *  from  dept;

Page 25: SQL Plus

desc  dept02;

select  *  from  dept02;

dept02  가  이미  생성되었다면  삭제하고  다시  만듭니다. drop  table  dept02;

update  dept02  set  loc='Seoul'  where  deptno=10;

select  *  from  dept02;

create  table  em06  as  select  empno,  ename,  sal  from  emp; select  *  from  em06;

update  em06  set  sal=sal*1.1; 모든  직원의  급여를  10%  인상합니다.

select  *  from  em06;

8.  서브  쿼리를  이용한  데이터  수정 

create  table  dept03  as  select  *  from  dept;

select  *  from  dept03;

update  dept03 set  (dname,  loc)  =  (select  dname,  loc  from  dept  where  deptno=40) where  deptno=20;

부서번호  20의  부서명과  위치가  dept  테이블의  부서번호  40의  결과로  수정되었습니다.

select  *  from  dept03;

9.  delete  문 

DELETE FROM  테이블명 WHERE  조건;

select  *  from  dept  03;

delete  from  dept03  where  deptno=30;

create  table  em07  as  select  *  from  emp;

select  *  from  em07;

delete from  em07 where  deptno=(select  deptno  from  dept  where  dname='SALES');

select  *  from  em07;

10.  MERGE 두개의  테이블을  하나의  테이블로  합치는  기능을  합니다. 기존에  존재하는  행이  있다면  새로운  값으로  갱신되고, 존재하지  않으면  새로운  행으로  추가  됩니다.

Page 26: SQL Plus

create  table  em08  as  select  *  from  emp;

create  table  em09  as  select  *  from  emp  where  job='MANAGER';

update  em09  set  job='test'  where  job='MANAGER';

insert  into  em09  values  (  8000,  'syj',  'top',  7566,  '02-JUN-2005',  1200,  10,  20);

emp08  테이블과    emp09  테이블  합병 

merge  into  em08  e    using  em09  s    on  (e.empno=s.empno) when  matched  then    update  set       e.ename     =  s.ename,       e.job      =  s.job,       e.mgr      =  s.mgr,       e.hiredate   =  s.hiredate,       e.sal      =  s.sal,       e.comm      =  s.comm,       e.deptno   =  s.deptno when  not  matched  then    insert  values  (  s.empno,  s.ename,  s.job,  s.mgr,  s.hiredate,  s.sal,  s.comm,  s.deptno  );

트랜잭션(Transaction)은 데이터의 일관성을 유지하기 위한 일련의 프로세스라고 보시면 됩니다. 트랜잭션은 어느   한단계를 말하는  것이  아니고, COMMIT (성공적으로 반영되거나) ROLLBACK ( 성공적으로 취소되거나) 일련의 단계라고 보시면 됩니다. 즉, 모두 반영되거나 모두 취소되어야 하는 프로세스라고 보시면 됩니다.

두개의 테이블에 입력을 해야 한다고 본다면,

회원정보는 두 개 이상의 테이블을 이용하여 정보를 관리한다고 예를 들죠... 

member 테이블과  member_detail테이블이 있다면, 회원  가입시  member 테이블에  반드시 입력되어야 하는   값이 누락되었거나 잘못된 값일 경우, member_detail 입력에 도달하기도 전에 모든 작업이 취소되어야 한다는 의미이고, member 테이블에 입력되어야 할 값이 정상이지만 member_detail 테이블에 입력될   값이  또한   중요한   값이 누락되었거나 잘못된 값일 경우 입력이   되지  말아야   합니다. 이럴   때, 정보가 누락이 되었으니 다시   입력해  달라는 문구가 사용자에게 피드백되어야 하죠... 어느 하나 입력이 누락이되면 모두 취소되어야 하는 경우는?ROLLBACK모두 정상적으로 입력이 반영되었다면?COMMIT

COMMIT 되고 ROLLBACK 되고 하는 일련의 과정을 트랜잭션이라고 보시면 쉽습니다.

commit; 먼저  이전에  했던  작업을  모두  적용시키기  위해서  커밋을  수행합니다.

delete  from  dept01;

select  *  from  dept01;

Page 27: SQL Plus

rollback;

select  *  from  dept01; 롤백으로  인하여  자료가  다시  이전  상태로  복원되었음을  확인  합니다.

delete  from  dept01  where  deptno=20;

select  *  from  dept01  where  deptno=20;

commit;

rollback;

select  *  from  dept01  where  deptno=20; 복원되지  않습니다.  이미  commit  이  수행된  결과는  롤백되지  않습니다.

[자동  커밋] DDL문에는 CREATE, ALTER, DROP, RRENAME, TRUNCATE 등의 자동 커밋(AUTO COMMIT)이 발생하는 DDL문이  있습니다. 이런 경우에는 ROLLBACK 가 불가능합니다.

create  table  em10  as  select  *  from  emp;

delete  from  em10  where  deptno=10;

select  *  from  em10  where  deptno=10; 결색결과  없음  확인 

truncate  table  emppp; 없는  테이블  명으로  오류를  유발 

rollback;

select  *  from  em10  where  deptno=10 결과가  없습니다. truncate  가  수행되면  현재  수행된  모든  작업이  커밋이  되므로  롤백이  불가능  합니다.

[세이브  포인트]

SAVEPOINT  C3; ... ... ROLLBACK  TO  C3;

롤백이  수행되면  savepoint  c3  으로  복원  됩니다.

COMMIT

CREATE  TABLE  dept05  as  select  *  from  dept;

select  *  from  dept05;

savepoint  A;

delete  from  dept05  where  deptno=20;

Page 28: SQL Plus

select  *  from  dept05  where  deptno=20;

rollback  to  A;

select  *  from  dept05  where  deptno=20; 복원  되었습니다.

주의)

savepoint  A;

명령  수행...

savepoint  B; 명령수행...

rollback  to  A;

이렇게  A  포인트로  롤백될  경우,  B포인트로의  롤백은  불가능합니다. A  포인트로  롤백되었다는  의미는  B포인트의  위치도  함께  사라짐을  의미  합니다.

data integrity constraint rule이란 테이블에 부적절한 자료가 입력되는 것을 방지하기 위해서 테이블을 생성할 때 각 컬럼에 대해서 정의하는 여러가지 규칙을 말합니다.

1.  제약 조건 지정하기

컬럼  단위의  제약  조건 

create  table  dept03 (     deptno    NUMBER(2)  constratint  dept03_deptno_pk  PRIMARY  KEY,     dname      VARCHAR2(15),     loc          VARCHAR2(15) );

테이블  단위의  제약  조건 

create  table  dept03 (       deptno  NUMBER(2),       dname    VARCHAR2(15),       loc        VARCHAR2(15),           constraint  dept03_deptno_pk  PRIMARY  KEY(deptno) );

두개  이상의  컴럼에  제약  조건을  걸  경우 

create  table  dept03 (       deptno  NUMBER(2),       dname    VARCHAR2(15),       loc        VARCHAR2(15),           constraint  dept03_deptno_pk  PRIMARY  KEY(deptno,  dname) );

Page 29: SQL Plus

2.  제약  조건  수정하기 

alter  table  dept03 add  constraint  dept03_deptno_pk  PRIMARY  KEY(deptno);

3.  제약  조건  제거 alter  table  dept03 drop  constraint  dept03_dname_pk;

4.  참조  제약  조건 //  기본  키  지정 create  table  dept07 (     deptno  NUMBER(2),      dname    VARCHAR2(15),     loc        VARCHAR2(15),         constraint  dept07_deptno_pk  PRIMARY  KEY(deptno) );

//  왜래  키  지정 create  table  emp07 (     empno    NUMBER(4),     ename    VARCHAR2(15),     deptno  NUMBER(2),         constraint  emp07_empno_pk  PRIMARY  KEY(empno),         constraint  emp07_deptno_fk  forenign  key(deptno)  references  dept07  (deptno) );

5.  유일  키  제한  조건 //  컬럼  단위로  지정 create  table  dept08 (       deptno  NUMBER(2)  PRIMARY  KEY,       dname    VARCHAR2(15)  UNIQUE,       loc        VARCHAR2(15) );

//  테이블  단위로  지정 drop  table  dept08; create  table  dept08 (       deptno  NUMBER(2),       dname    VARCHAR2(15),       loc        VARCHAR2(15),           constraint  dept08_deptno_pk  PRIMARY  KEY(deptno),           constraint  dept08_dname_uq  UNIQUE(dname) );

UNIQUE  는  중복된  값을  가질  수  없지만,  NULL은  여러개  올수  있습니다.

6.  Check  제한  조건 

create  table  emp08 (     empno      NUMBER(4)  constraint  emp08_empno_pk  PRIMARY  KEY,

Page 30: SQL Plus

    ename      VARCHAR2(15),     sal          NUMBER(7,  2)  constraint  emp08_sal_ch  CHECK(sal  between  500  and  5000),     deptno    NUMBER(2)  constraint  emp08_deptno_fk  references  dept08  (deptno) );

7.  NOT  NULL  제한  조건 create  table  dept09 (     deptno      NUMBER(4)  constraint  dept09_deptno_pk  PRIMARY  KEY,     dname        VARCHAR2(15)  constraint  dept09_dname_nn  NOT  NULL,     loc            VARCHAR2(15) );

//  수정 alter  table  dept09 modify  loc  constraint  dept09_loc_nn  NOT  NULL;

//  제거 alter  table  dept09 drop  loc  constraint  dept09_loc_nn;

//  제약  조건을  참조하는  모든  제약  조건들도  먼저  제거한후  현재  제약  조건을  삭제  시킴 alter  table  dept09 drop  constraint  dept09_deptno_pk  CASCADE;

//  제약  조건을  비활성화 alter  table  dept09 disable  constraint  dept09_deptno_pk;

//  비활성화  된  제약  조건  활성화 alter  table  dept09 enable  constraint  dept09_deptno_pk;

뷰란? 물리적인 테이블을 근거한 논리적인 가상 테이블이라고 정의할 수 있습니다.

create  table  dept_copy as select  *  from  dept;

create  table  emp_copy as select  *  from  emp;

30번 부서에 소속된 사원들의 사번과 이름, 부서번호가 자주 검색된다고 했을때, 뷰가 필요한 이유 설명.

select  empno,  ename,  deptno from  emp_copy where  deptno=30;

위에서 처럼 매번 같은 실행문을 작성해야 한다면 번거로울겁니다.

Page 31: SQL Plus

이럴때 필요한 것이 없을까 생각해서 작성되어야하는 것이 뷰 입니다.

create  view  emp_view30 as select  empno,  ename,  deptno from  emp_copy where  deptno=30;

desc  emp_view30;

뷰의 구조는 기본테이블의 구조를 그대로 상속받습니다.

실행은 select  *  from  emp_view30;

정말  간단하죠?

[뷰를  사용하는  이유] 1)  복잡하고 긴 쿼리문을 뷰로 정의하면 접근을 단순화시킬 수 있습니다. 2)  보안에 유리 합니다.

보안에  유리한  이유는 뷰에 작성된 쿼리 정보에는 급여등 중요한 정보가 제한되어 있기 때문에 중요한 정보를 보호할 수 있습니다.

[뷰의  종류]

1.  단순  뷰와  컨럼  별칭 

create  view  emp_view10(사원번호,  이름,  부서번호) as select  empno,  ename,  deptno from  emp_copy where  deptno=10;

select  *  from  emp_view10;

결과 컬럼명이 한글로 보여집니다.  이것이 컬럼명을 별칭으로 사용한 예입니다.

desc  emp_view10;

create  view  dept_sum as select  deptno,  SUM(sal)  sum_sal from  emp_copy group  by  deptno;

사원테이블에서 부서별 급여 총계를 구하는 뷰 입니다.

select  *  from  dept_sum;

2.  복합  뷰 

create  view  emp_view_join as select  e.empno,  e.ename,  d.dname

Page 32: SQL Plus

from  emp  e,  dept  d where  e.deptno=d.deptno;

select  *  from  emp_view_join;

복잡한 쿼리문을 뷰를 통해서 간단하게 접근할 수 있는 것을 확인할 수 있습니다.

3.  뷰의  제거 drop  view  emp_view30; drop  view  emp_view10; drop  view  emp_view;

4.  뷰의  변경 drop  view  detp_sum;

create  view  dept_sum as select  deptno,  sum(sal)  sum_sal,  avg(sal)  avg_sal from  emp_copy group  by  deptno;

select  *  from  detp_sum;

뷰의  변경은  create  or  replace  view  를  이용합니다.

create  or  replace  view  emp_view_join as select  e.name,  d.name,  d.loc from  emp  e,  dept  d where  e.deptno=d.deptno;

select  *  from  emp_view_join;

5.  뷰의 생성할 때 지정하는 FORCE/NOFORCE  옵션 기본 테이블이 존재하지 않을 경우에도 뷰를 생성할 수 있는데 이 때 사용하는 옵션이 FORCE 입니다.

특별한 설정이 없으면 NOFORCE 옵션이 지정된 것이므로 반드시 존재하는 기본 테이블을 이용한 쿼리문으로 뷰를 생성해야 합니다.

desc employees; 물론 존재하지 않는 기본 테이블이니 오류 메시지를 보여줍니다.

create  or  replace  view  view_employees as select  *  from  employees;

테이블  또는  뷰가  존재하지  않습니다  라는  오류를  보여  줍니다.

이럴때  사용하는  옵션이  FORCE  옵션입니다.

create  or  replace  force  view  view_employees as select  *  from  employees;

Page 33: SQL Plus

컴파일  오류와  함께  뷰가  생성되었습니다.

6.  WITH  CHECK  OPTION

create  or  replace  noforce  view  emp_view20 as select  empno,  ename,  deptno from  emp_copy where  deptno=20;

select  *  from  emp_view20;

update  emp_view20 set  ename='nekr' where  empno=7369;

select  *  from  emp_view20;

update  emp_view20 set  deptno=40 where  empno=7369;

부서번호   20인   사원만   검색되는  뷰인데   40으로   변경되었으니  뷰   검색에는   나오지   않게  됩니다.

create  or  replace  noforce  view  emp_view20 as select  empno,  ename,  deptno from  emp_copy where  deptno=20  with  check  option;

지급부터는  deptno  는  변경이  불가능하게  됩니다.

7.  WITH  READ  ONLY

create  or  replace  noforce  view  emp_chk30 as select  empno,  ename,  deptno from  emp_copy where  deptno=30  with  read  only;

with  read  only  옵션을  지정하게  되면,  기본  테이블의  내용을  변경할수  없게  도비니다.

8.  인라인  뷰 

서브  쿼리문에서  바깥  쪽  select  문이  from  절  내부에  사용된  서브  쿼리문을  말합니다. 내부에  사용되는  서브  쿼리는  별칭이  부여  됩니다.

select  src.empno,  src.ename,  src.hiredate,  src.deptno,  max_hiredte from  emp_copy  src,  (select  deptno,  MAX(hiredate)  max_hiredate               from  emp_copy               group  by  deptno)  des where  src.deptno=des.deptno  and  src.hiredate  <  des.max_hiredate;

9.  Top-N  분석 

Page 34: SQL Plus

select  rowid,  rownum,  empno  from  emp;

rowid  :  주소로서  row  가  실제로  저장되어  있는  공간(Tree형  구조)  테이블  내의  고유주소 rownum  :  번호인데  row의  주소  순서대로  출력되어지는  순서대로  부여됩니다.

이  두개  컬럼을  이용하여  Top-N  쿼리문을  작성할수  있습니다.

select  ename,  sal  from  emp  order  by  sal  desc;

select  rownum,  ename,  sal from  (select  ename,  sal,  from  emp  order  by  sal  desc); 급여를  기준  컬럼으로  내림차순  정렬한  사원  테이블을  인라인  뷰로  구성. 급여를  가장  많이  받는  사원이  첫  행이  됩니다.

select  rownum,  ename,  sal from  (select  ename,  sal,  from  emp  order  by  sal  desc) where  rownum  <=  3;

rownum  값이  3까지만  조회  됩니다.

select  rownum,  empno,  ename,  hiredate from  (  select  empno,  ename,  hiredate  from  emp  order  by  hiredate  desc  ) where  rownum  <=  5; 최근에  입사한  직원  5명에  대한  정보를  출력하는  쿼리문  입니다.

1.  시퀀스란 오라클에서는 행을   구분하기 위해서   기본 키를  두고   있습니다. 기본키는   중복된   값을   가질 수 있으므로 항상 유일한 값을  가져야 합니다. 기본키가 유일한 값을  갖도록 사용자가 직접 값을 생성해내려면 부담이 큽니다.시퀀스는 테이블 내의 유일한 숫자를 자동으로 생성하는 자동번호발생기이므로 시퀀스를 기본 키로 사용하게 되면 사용자의 부담을 줄일 수 있습니다. CREATE  SEQUENCE  sequence_name    [  INCREMENT  BY  n  ]    [  START  WITH  ]    [  {MAXVALUE  n  |  NOMAXVALUE}  ]    [  {MINVALUE  n  |  NOMINVALUE}  ]    [  {CYCLE|  NOCYCLE}  ]    [  {CACHE  n  |  NOCACHE}  ];

1)  INCREMENT  BY  옵션 연속적인  시퀀스  번호의  증가치를  지정할  때  사용됩니다. 만약  1씩  증가하는  시퀀스를  생성하려면  increment  by  1  이라고  지정해주면  됩니다.

2)  START  WITH  옵션 시퀀스  번호의  시작  값을  지정할  때  사용됩니다.  만일  1부터  시작되는  시퀀스를  생성하려면 start  with  1  로  지정해주면  됩니다.

3)  MAXVALUE  옵션 시퀀스가  가질  수  있는  최대값을  지정합니다. nomaxvalue  를  지정하면  ascending  순서일  경우에는  10^27  승이고, descending  순서일  경우에는  -1  로  설정됩니다.

4)  MINVALUE  옵션 

Page 35: SQL Plus

시퀀스가  가질  수  있는  최소값을  지정합니다. nominvalue  를  지정하면  ascending  순서일  경우에는  1이고 descending  순서일  경우에는  10^26  승이  설정됩니다.

5)  CYCLE  옵션 지정된  시퀀스  값이  최대값까지  증가가  완료되게  되면  다시  start  with  옵션에  지정한  시작  값에서  다시  시퀀스를  시작하도록  합니다. nocycle  은  증가가  완료되게  되면  에러를  유발시킵니다.

6)  CACHE  옵션 메모리상의  시퀀스  값을  관리하도록  하는    것인데  기본  값은  20입니다. nocache는  원칙적으로  메모리  상에서  시퀀스를  관리하지  않습니다.

부서번호를  자동으로  부여해주는  시퀀스  객체를  생성 create  sequence  detp_deptno_seq increment  by  10 start  with  10;

2.  CURRVAL  과  NEXTVAL  의  사용 시퀀스의  현재  값을  알아내기  위해  currval  을  사용하고,  다음  값을  알아내기  위해  nextval을  사용합니다.

currval에  새로운  값을  할당하기  위해서는  nextval로  새로운  값을  생성해야  합니다.

select  dept_deptno_seq.nextval  from  dual;

select  dept_deptno_seq.currval  from  dual;

create  sequence  sample_seq;

select  sample_seq.nextval  from  dual; select  sample_seq.currval  from  dual;

3.  시퀀스의  수정과  제거 

alter  sequence  dept_deptno_seq maxvalue  50;

select  dept_deptno_seq.currval  from  dual; select  dept_deptno_seq.nextval  from  dual; select  dept_deptno_seq.currval  from  dual;

nextval를  할당하다  보면  50까지만  할당하고  그  이상은  오류를  발생합니다.

시퀀스의  제거 drop  sequence  sample_seq; drop  sequence  dept_deptno_seq;

4.  시퀀스의  실무  적용 99.9%  insert  연산과  같이  사용되어  컬럼  값을  자동으로  발생시키는  용도로  사용됩니다.

create  table  dept15

Page 36: SQL Plus

(       detpno  NUMBER(4)  PRIMARY  KEY,       dname    VARCHAR2(25),       loc        VARCHAR2(30) );

desc  dept15;

create  sequence  dept_deptno_seq increment  by  10 start  with  10 nocycle;

insert  into  dept15  values  (dept_deptno_seq.nextval,  'test1',  'location1'); insert  into  dept15  values  (dept_deptno_seq.nextval,  'test2',  'location2'); insert  into  dept15  values  (dept_deptno_seq.nextval,  'test3',  'location3'); insert  into  dept15  values  (dept_deptno_seq.nextval,  'test4',  'location4');

select  *  from  dept15;

1.  인덱스란? 검색을 빠른 속도로 하기 위해서 제공됩니다. SQL 명령문의 처리 속도를 향상시키기 위해서 컬럼에 대해서 생성하는 오라클 객체입니다. 오라클에서의 인덱스의 내부 구조는 B트리 형식으로 구성되어 있습니다.

2.  인덱스 생성/제거, 조회 

create  table  e2 as select  *  from  emp;

검색속도의 차이를 현저히 느끼게하려면 데이터가 많아야 합니다. 데어터 부풀리기... inert into  e2  select  *  from  e2; 여러번  실행해서  행을  많이  생성해  놓습니다. 저는 하다보니 917504 rows created 가 되었네요 

시간  체크를  위해 set  timing  on

select  distinct  empno,  ename  from  e2  where  ename='SCOTT'; 01.95  초  약  2초  걸렸네요...

create index idx_e2_ename on e2(ename); 인덱스 생성하는  시간이  좀  걸리는군요. 28.56 초 걸렸습니다.

select distinct  empno,  ename  from  e2  where  ename='SCOTT'; 다시 검색해 봅니다.  ㅋ 개인별 노트북 사양이 틀려서 이겠지만 많은 양의 데이터 검색에서는 차이가 날겁니다.

인텍스  삭제 drop  index  idx_e2_ename;

Page 37: SQL Plus

3.  인덱스의  장/단점,  인덱스  재구성 

1)  인덱스를  사용해야하는  경우 테이블에  행의  수가  많을  때 조건절인  where  문에  해당  컬럼이  많이  사용될  때 검색  결과가  데이터의  2%  ~  4%  정도  일  때 join에  자주  사용되는  컬럼 NULL을  포함하는  컬럼이  많은  경우 

2)  인덱스를  사용하지  말아야  하는  경우 테이블에  행의  수가  적을  때 where  문에  해당  컬럼이  자주  사용되지  않을  때 검색  결과가  전체  데이터의  10%  ~  15%  이상  높을  때 테이블에  DML  작업이  많은  경우(  입력  수정  삭제  등이  자주  발생할  때)

select  *  from  e2  where  deptno=10;

테이블에 전체 행의 수는 10000 건이다. 위의 쿼리문을 전체 쿼리문 들 중 95%  사용된다. 쿼리문의 결과에 구해지는 행은 10건 정도이다. 그래서 인덱스가 필요합니다.

create  index  idx_e2_deptno on  e2(deptno); 생성완료시간:  7.98초 

효율이 떨어지면 인덱스를 재생성해 주어야 합니다. 컬럼의 데이터가 입력, 수정, 삭제될 경우 해당 컬럼에 의해 생성된 인덱스에 대해서 재구성해야 합니다.

인덱스의  재생성 

alter  index  idx_e2_deptno  rebuild;

4.  인덱스의  종류 1)  고유 인덱스(Unique  Index)  -  유일한 값을 갖는 컬럼에 대해서 생성하는 인덱스2)  비고유 인덱스(NonUnique  Index)  -  중복된 데이터를 갖는 컬럼에 대해서 생성하는 인덱스3)  단일 인덱스(Single  Index) 4)  결합 인덱스(Composite  Index) 5)  함수 기반 인덱스(Function  Based  Index)

create  table  d2 as select  *  from  dept;

insert  into  d2  values  (50,  'test50',  'Seoul'); insert  into  d2  values  (60,  'test60',  'Daejeon'); insert  into  d2  values  (70,  'test70',  'Daejeon');

select  *  from  d2;

deptno  에  대해서는  고유인덱스를 

Page 38: SQL Plus

loc  에  대해서는  비고유인덱스를  생성하는것이  좋습니다.

[고유인덱스] crete  unique  index  idx_d2_deptno on  d2(deptno);

[비고유인덱스] create  index  idx_d2_loc on  d2(loc);

[결합  인덱스] create  index  idx_d2_com on  d2(deptno,  loc);

select  index_name,  column_name from  user_ind_columns where  table_name='d2'; 인덱스  구조  확인  합니다.

[함수기반  인덱스]

create  table  e3 as select  * from  emp;

검색   조건으로   sal*12  =  3600  을   지정하는   경우,  이럴경우   sal*12  를   인덱스를  탈수  없을수도  있습니다. 이럴때  구성하는  인덱스가  함수  기반  인덱스  입니다.

create  index  idx_e3_annsal on  e3(sal*12);

select  index_name,  column_name from  user_ind_columns where  table_name='e3'; 인덱스  생성  확인...

1.  사용자  생성 

conn  system/manager

show  user

system  사용자로  접속했는지  확인  

create  user  user01  identified  by  tiger; User  id  :  user01 User  pw  :  tiger 로  유저  생성 

conn  user01/tiger ERROR: ORA-01045:  user  USER01  lacks  CREATE  SESSION  privilege;  logon  denied

Warning:  You  are  no  loger  connected  ORACLE.

Page 39: SQL Plus

권한  문제로  접속이  실패  되었습니다.

2.  시스템  권한 1)  데이터베이스  관리자가  가지는  시스템  권한 CREATE  USER       새롭게  사용자를  생성하는  권한 DROP  USER       사용자를  삭제하는  권한 DROP  ANY  TABLE      임의의  테이블을  삭제할  수  있는  권한 QUERY  REWRITE      질의  재작성을  할  수  있는  권한 BACKUP  ANY  TABLE   임의의  테이블을  백업할  수  있는  권한 

2)  일반  사용자에  데이터베이스를  관리하는  권한 CREATE  SESSION      데이터베이스에  접속할  수  있는  권한 CREATE  TABLE      사용자  스키마에서  테이블을  생성할  수  있는  권한 CREATE  VIEW       사용자  스키마에서  뷰를  생성할  수  있는  권한 CREATE  SEQUENCE       사용자  스키마에서  시퀀스를  생성할  수  있는  권한 CREATE  PROCEDURE   사용자  스키마에서  함수를  생성할  수  있는  권한 

3)  사용자에게  시스템  권한  부여하기  위한  GRANT  명령어 

grant  system_privilege to  user_name

grant  create  session  to  user01;

conn  user01/tiger show  user

성공적으로  접속  되었습니다.  ㅋ 

4)  WITH  ADMIN  OPTION  옵션 사용자에게   시스템   권한을   WITH  ADMIN  OPTION과   함께   부여하면   그   사용자는  데이터베이스  관리자가 아닌데도  불구하고  부여받은  시스템  권한을  다른  사용자에게  부여할  수  있는  권한도  함께  부여받게  됩니다.

conn  system/manager

create  user  user02  identified  by  tiger; create  user  user03  identified  by  tiger;

grant  create  session  to  user02  with  admin  option; grant  create  session  to  user03;

conn  user02/tiger grant  create  session  to  user01; user02  가  시스템  권한행사가  가능함을  볼수  있다.

conn  system/manager

5)  객체  권한 테이블이나  뷰,  시퀀스,  함수등과  같은  객체별로  DML문(select,  insert,  delete)을 사용할  수  있는  권한을  설정.

Page 40: SQL Plus

GRANT  object_privilege ON  object TO  user_name

conn  user01/tiger show  user select  *  from  emp;

검색할수  없습니다.

객체  권한이  없기  때문이죠...

emp는  scott  사용자  소유의  테이블  입니다.

conn  scott/tiger

grant  select  on  emp  to  user01;

conn  user01/tiger

select  *  from  emp; 그래도  검색이  불가능합니다.

select  *  from  scott.emp; 이렇게  해주면  검색가능합니다.

6)  사용자에게  부여된  권한  조회 conn  user01/tiger

select  *  from  user_tab_privs_made;   //user01  사용자가  부여한  권한을  살펴봄 select  *  from  user_tab_privs_recd;   //user01  사용자에게  부여된  권한을  살펴봄 

conn  scott/tiger

select  *  from  user_tab_privs_made;   //scott  사용자가  부여한  권한을  살펴봄 select  *  from  user_tab_privs_recd;   //scott  사용자에게  부여된  권한을  살펴봄 

7)  사용자에게  권한을  빼앗기  위한  REVOKE  명령어 

REVOKE  object_privilege on  object from  user_name

conn  scott/tiger

revoke  select  on  emp  from  user01; select  *  from  user_tab_privs_made;

conn  user01/tiger select  *  from  scott.emp;

검색  불가능...

Page 41: SQL Plus

1. 사전  정의된  롤의  종류 

1)  CONNECT  롤 사용자가   데이터베이스에   접속   가능하도록   하기   위해   다음과  같이   가장   기본적인  시스템  권한 8가지를  묶어  놓았습니다.

ALTER  SESSION,  CREATE  CLUSTER,  CREATE  DATABASE  LINK,  CREATE  SEQUENCE,  CREATE  SESSION,  CREATE  SYNONYM,  CREATE  TABLE,  CREATE  VIEW

2)  RESOURCE  롤 사용자  객체(테이블,  뷰,  인덱스)를  생성할  수  있도록  하기위해서  시스템  권한을  묶어  놓았습니다.

CREATE  CLUSTER,  CREATE  PROCEDURE,  CREATE  SEQUENCE,  CREATE  TABLE,  CREATE  TRIGGER

3)  DBA  롤 사용자들이  소유한  데이터베이스를  관리하고  사용자들을  작성하고  변경하고  제거할  수  있도록  하는 모든  권한을  가집니다.

2.  롤  부여하기 

conn  system/manager

create  user  user04  identified  by  tiger

grant  connect,  resource  to  user04;

conn  user04/tiger

select  *  from  user_role_privs;

3.  사용자가  롤  정의 

conn  system/manager

create  role  mrole;

conn  scott/tiger

grant  select  on  emp  to  mrole;

conn  system/manager

grant  mrole  to  user04;

conn  user04/tiger

select  *  from  scott.emp;

Page 42: SQL Plus

검색  가능하게  되었습니다.

4.  롤에  부여된  권한  알아보고  롤  회수하기 

conn  test04/tiger

select  *  from  role_tab_privs  where  table_name  in  ('EMP');

select  *  from  user_role_privs;

conn  system/manager

revoke  mrole  from  user04; 권한롤을  회수  합니다.

select  *  from  role_tab_privs  where  role  in  ('MROLE'); 회수는  했지만  mrole  은  존재함을  확인할수  있습니다.

mrole  제거 drop  role  mrole; select  *  from  role_tab_privs  where  role  in  ('MROLE'); mrole이  존재하지  않습니다.

5.  롤의  장점 권한을  사용자마다  일일이  부여할  필요가  없어집니다.

conn  system/manager

create  role  def_role; grant  create  session  to  def_role; grant  create  table  to  def_role;

conn  scott/tiger grant  update  on  emp  to  def_role; grant  delete  on  emp  to  def_role; grant  select  on  emp  to  def_role;

수정,삭제,검색  권한을  def_role  에  부여함.

conn  system/manager

create  user  userA1  identified  by  tiger; create  user  userA2  identified  by  tiger; create  user  userA3  identified  by  tiger;

grant  def_role  to  userA1; grant  def_role  to  userA2; grant  def_role  to  userA3;

select  *  from  role_sys_privs  where  role='DEF_ROLE'; 시스템  권한에  대한  정보를  저장한  데이터  딕셔너리  검사 select  *  from  role_tab_privs  where  role='DEF_ROLE'; 객체  권한에  대한  정보를  저장한  데이터  딕셔너리  검사 

각  사용자로  접속해서  사용자에게  def_role  롤이  설정되어  있는지  확인 conn  userA1/tiger

Page 43: SQL Plus

select  *  from  user_role_privs;

conn  userA2/tiger select  *  from  user_role_privs;

conn  userA3/tiger select  *  from  user_role_privs;

1. 동의어  개념과  종류 다른  데이터베이스  객체에  대한  별명을  말합니다.

여러   사용자들이   테이블을   서로   공유하는데,  다른   사용자의   테이블을   접근할   때   [사용자명.테이블명]으로  표현하는  데,  이를  동의어를  적용하면  간단하게  요약해서  기술할  수  있습니다.

CREATE  [PUBLIC]  SYNONYM  synonym_name FOR  user_name.object_name;

synonym_name  :  user_name.Object_name에  대한  별칭입니다. user_name  :  객체를  소유한  오라클  사용자입니다. object_name  :  동의어를  만들려는  데이터베이스  객체  이름입니다.

DUAL  테이블은  공개  동의어입니다.

2.  동의어  생성 

conn  system/manager

create  role  test_role; grant  connect,  resource  to  test_role;

conn  scott/tiger grant  select  on  emp  to  test_role; grant  select  on  dept  to  test_role;

conn  system/manager

create  user  userb1  identified  by  tiger; create  user  userb2  identified  by  tiger;

grant  test_role  to  userb1; grnat  test_role  to  userb2;

create  public  synonym  pub_dept  for  scott.dept;

conn  userb1/tiger select  *  from  pub_dept; 드디어  검색이  가능합니다.

Page 44: SQL Plus

동의어  삭제하기 conn  system/manager drop  public  synonym  pub_dept;

1.  PL/SQL  구조 

PL/SQL  은  파스칼  구조로 DECLARE ~ BEGIN ~ EXCEPTION ~ END 순서를  갖습니다.

DECLARE  SECTION(선언부) PL/SQL에서  사용하는  모든  변수난  상수를  선언하는    부분으로  DECLARE로  시작합니다.

EXECUTABLE  SECTION(실행부) 절차적  형식으로  SQL문을  실행할  수  있도록  절차적  언어의  요소인  제어문,  반복문,  함수정의  등 로직을  기술할  수  있는  부분으로  BEGIN  으로  시작합니다.

EXCEPTION  SECTION(예외  처리부) PL/SQL  문이  실행된는  중에  에러가  발생할  수  있는데  이를  예외  사항이라고  합니다. 이러한  예외  사항이  발생했을  때  이를  해결하기  위한  문장으로  구성됩니다.

ed  sample 를  실행하여  메모장에서  편하게  아래  쿼리문을  작성합니다.

declare    vempno   NUMBER(4);    vename   VARCHAR(20); begin    select  empno,  ename  into  vempno,  vename    from  emp    where  empno=7788; end; /

작성이  완료되면  창을  닫기위해  X  를  클릭합니다. 저장합니다.

Page 45: SQL Plus

작성한것을  실행합니다. @sample

실행결과 PL/SQL  procedure  successfully  completed.  라는  메시지가  출력  됩니다.

desc  dbms_output

출력값이  보이지  않기때문에  sample  을  수정합니다. ed  sample

declare    vempno   NUMBER(4);    vename   VARCHAR(20); begin    select  empno,  ename  into  vempno,  vename    from  emp    where  empno=7788;

   dbms_output.put_line('*****  output  String  *****');    dbms_output.put_line(TO_CHAR(vempno)  ||  '      '  ||  vename); end; /

저장합니다.

실행합니다.

set  serveroutput  on 결과를  볼수  있게  환경변수  수정 

@sample

*****  output  String  ***** 7788  SCOTT

PL/SQL  procedure  successfully  completed.

드디어  결과가  보입니다.

2.  변수  선언과  대입문 

1)  스칼라(scalar)  변수  선언 DECLARE    vempno   NUMBER(4);    vename   VARCHAR2(20);

2)  %TYPE  변수  선언    vdeptno   emp.deptno%TYPE; 컬럼의  데이터타입  및  사이즈를  참조  합니다.

Page 46: SQL Plus

3)  %ROWTYPE    vemp   emp%ROWTYPE; emp  테이블의  ROW  타입(empno,  ename,  job,  mgr,  hiredate,  sal,  comm,  deptno)과  같다는  의미입니다. emp  테이블  안에  들어  있는  8개의  컬럼  및  사이즈를  참조한  8개의  칸으로  나눠진  한  줄의  변수라고  생각  할  수  있습니다.

ed  example03

declare    vemp   emp%ROWTYPE; begin    select  *  into  vemp    from  emp    where  empno=7788;

   dbms_output.put_line('  empno   ename   job   hiredate');    dbms_output.put_line(vemp.empno||'   '||vemp.ename||'   '||vemp.job||'   '||vemp.hiredate); end; /

저장하고  실행  합니다.

@example03 empno   ename   job   hiredate 7788   SCOTT   ANALYST   19-APR-87

PL/SQL  procedure  successfully  completed.

3.  선택문 

1)  IF-THEN-END  IF

ed  ex01

declare    vempno   NUMBER(4);    vename   VARCHAR2(20);    vdeptno   emp.deptno%TYPE;    vdname   VARCHAR2(20)  :=  NULL; begin    select  empno,  ename,  deptno  into  vempno,  vename,  vdeptno    from  emp    where  empno=7788;

   if  (vdeptno  =  10)  then       vdname  :=  'ACCOUNTING';    end  if;

   if  (vdeptno  =  20)  then       vdname  :=  'RESEARCH';

Page 47: SQL Plus

   end  if;

   if  (vdeptno  =  30)  then       vdname  :=  'SALES';    end  if;

   if  (vdeptno  =  40)  then       vdname  :=  'OPERATIONS';    end  if;

   dbms_output.put_line('empno   ename   dname');    dbms_output.put_line(TO_CHAR(vempno)||'   '||vename||'   '||vdname); end; /

@ex01 empno   ename   dname 7788   SCOTT   RESEARCH

PL/SQL  procedure  successfully  completed.

이번  문법은  완벽하게  파스칼  문법이었던것  같습니다. 대입  연산자  :=  만해도  그렇죠  ㅋ 

2)  IF-THEN-ELSIF-END  IF

ed  ex02

declare    vempno   NUMBER(4);    vename   VARCHAR2(20);    vdeptno   emp.deptno%TYPE;    vdname   VARCHAR2(20)  :=  NULL; begin    select  empno,  ename,  deptno  into  vempno,  vename,  vdeptno    from  emp    where  empno=7788;

   if  (vdeptno  =  10)  then       vdname  :=  'ACCOUNTING';    elsif  (vdeptno  =  20)  then       vdname  :=  'RESEARCH';    elsif  (vdeptno  =  30)  then       vdname  :=  'SALES';    elsif  (vdeptno  =  40)  then       vdname  :=  'OPERATIONS';    end  if;

   dbms_output.put_line('empno   ename   dname');    dbms_output.put_line(TO_CHAR(vempno)||'   '||vename||'   '||vdname); end; /

Page 48: SQL Plus

저장하고  실행 

@ex02 empno   ename   dname 7788   SCOTT   RESEARCH

PL/SQL  procedure  successfully  completed.

한가지  주의  할점은 우리가  알고  있는  이반적인  else  if  또는  elseif  와는  같은  의미이지만  ELSIF  를  보시면  영문자  e가  없습니다.  참  별것이  말썽이군요.. 파스칼  문법은  ELSEIF  인데  이상하군요  ㅋ 

3)  IF~THEN~ELSE~END  IF

ed  ex03

declare    vempno   NUMBER(4);    vename   VARCHAR2(20);    vcomm   emp.comm%TYPE; begin    select  empno,  ename,  comm  into  vempno,  vename,  vcomm    from  emp    where  empno=7788;

   if  (vcomm  >  0)  then       dbms_output.put_line(vename||'  comm  :  '||vcom);    else       dbms_output.put_line(vename||'  comm  :  0');    end  if; end; /

저장하고  실행 @ex03 SCOT  comm  :  0

PL/SQL  procedure  successfully  completed.

4)  반복문 ed  ex04

SET  SERVEROUTPUT  ON declare    VDAN   NUMBER(2)  :=  2;    I   NUMBER(2)  default  0;    TOT   NUMBER:=0;

Page 49: SQL Plus

begin    for  I  in  1..9  loop        TOT  :=  VDAN  *  I;        dbms_output.put_line(VDAN||'  *  '||I||'  =  '||TOT);    end  loop; end; /

저장하고  실행 @ex04 곱하기  2단  실행결과  출력됩니다.

PL/SQL  procedure  successfully  completed.

단수를  입력받고  출력하기 ed  ex05

SET  SERVEROUTPUT  ON ACCEPT  PDAN  PROMPT  'INPUT  DAN  :  ' declare    VDAN   NUMBER(2)  :=  &PDAN;    I   NUMBER(2)  default  0;    TOT   NUMBER:=0; begin    for  I  in  1..9  loop        TOT  :=  VDAN  *  I;        dbms_output.put_line(VDAN||'  *  '||I||'  =  '||TOT);    end  loop; end; /

저장하고  실행하기 

@ex05 3을  입력하고  엔터  클릭하시면  3단의  결과가  나옵니다.

PL/SQL  procedure  successfully  completed.

5)  테이블에  저장 

set  serveroutput  off

create  table  a (       A1  NUMBER,       A2  NUMBER,       A3  NUMBER );

Page 50: SQL Plus

desc  a;

ed  ex06

SET  SERVEROUTPUT  ON ACCEPT  PDAN  PROMPT  'INPUT  DAN  :  ' declare    VDAN   NUMBER(2)  :=  &PDAN;    I   NUMBER(2)  default  0;    TOT   NUMBER:=0; begin    for  I  in  1..9  loop        TOT  :=  VDAN  *  I;        dbms_output.put_line(VDAN||'  *  '||I||'  =  '||TOT);        insert  into  A  values(VDAN,  I,  TOT);    end  loop; end; /

저장하고  실행 

@ex06 5를  입력하고  엔터 구구단  5단이  출력되고  DB  A테이블에  입력됩니다.

PL/SQL  procedure  successfully  completed.

select  *  from  A;

6)  시퀀스  생성 

alter  table  A add(a_no  NUMBER);

desc  A;

create  sequence  A_NO_SEQ start  with  1 increment  by  1 nocycle nocache;

ed  ex07

SET  SERVEROUTPUT  ON ACCEPT  PDAN  PROMPT  'INPUT  DAN  :  ' declare    VDAN   NUMBER(2)  :=  &PDAN;    I   NUMBER(2)  default  0;

Page 51: SQL Plus

   TOT   NUMBER:=0; begin    for  I  in  1..9  loop        TOT  :=  VDAN  *  I;        dbms_output.put_line(VDAN||'  *  '||I||'  =  '||TOT);        insert  into  A  values(VDAN,  I,  TOT,  A_NO_SEQ.nextval);    end  loop; end; /

저장하고  실행 @ex07 6을  입력하고  엔터 

6단이  출력되고  db  입력  됩니다.

7)  PL/SQL  테이블과  레코드 

TYPE  type_name  IS  TABLE  OF table_name.column_name%TYPE INDEX  BY  BINARY_INTEGER;

type_name  은  새로  정의할  자료  형의  이름입니다. table_name  테이블의  column_name  컬럼의  자료형을  배열로  사용할  새로운  테이블  형인  type_name  의 기본형이  됩니다.  이렇게  선언된  테이블형으로  변수를  선언합니다. INDEX  BY  절은  몇  번째  배열에  어떤  값을  저장할  것인지를  구분하기  위해서  사용됩니다.

TYPE  E1_TABLE_TYPE  IS  TABLE  OF EMP.ENMAME%TYPE INDEX  BY  BINARY_INTEGER;

ed  ex08

SET  SERVEROUTPUT  ON declare    vename   VARCHAR2(20);

   TYPE  E1_TABLE_TYPE  IS  TABLE  OF    emp.ename%TYPE    index  by  binary_integer;

   TAB1  E1_TABLE_TYPE; begin    select  ename  into  vename    from  emp    where  empno=7788;

   TAB1(0)  :=  vename;

   dbms_output.put_line(TAB1(0)); end;

Page 52: SQL Plus

/

저장하고  실행합니다.

@ex08

SCOTT  라고  나옵니다.

//  부서  테이블을  레코드  배열  형태로  저장하기  위한  새롭게  자료형을  생성 

ed  ex09

SET  SERVEROUTPUT  ON declare    TYPE  D1_RECORD_TYPE  IS  RECORD    (            deptno    NUMBER(2),            dname       VARCHAR2(14),            loc          VARCHAR(13)    );

   REC1  D1_RECORD_TYPE; begin    select  *  into  REC1    from  dept    where  deptno=10;

   dbms_output.put_line('deptno   dname   loc');    dbms_output.put_line(TO_CHAR(REC1.deptno)||'   '||REC1.dname||'   '||REC1.loc); end; /

저장하고  실행합니다. @ex09

deptno   dname      loc 10   ACCOUNTING   NEW  YORK

PL/SQL  procedure  successfully  completed.

1.  커서의  정의 

커서란  SQL  Plus에서  사용자가  실행한  SQL문의  단위를  의미합니다. 오라클렝서  수행한  모든  쿼리문은  커서  단위로  처리합니다.

PL/SQL의  SQL문처럼  하나의  결과를  리턴하는  경우  커서  없이도  SQL문의  실행결과가  암시적으로  커서에  저장되므로  이를  암시적  커서라고  합니다.

SQL문을  수행한  후에  결과로  얻어지는  행이  여러  개일  경우에는  암시적인  커서에  정보를  

Page 53: SQL Plus

저장할   수   없기에   에러가   발생합니다.  이럴   경우에는   반드시   명시적인   커서를   사용해야  합니다.

명시적인  커서는  PL/SQL의  레코드(RECORD)와  PL/SQL의  테이블(TABLE)을  결합한  것으로서 프로그램  언어의  구조체  배열과  유사합니다.

[커서의  사용]

1)  커서를  선언한다. CURSOR  cur_name

2)  커서를  오픈한다. OPEN  cur_name

3)  커서에  조회한  결과를  인출해  지정한다. FECTCH  cur_name  ...

4)  커서를  닫는다 CLOSE  cur_name

2.  20번  부서에  근무하는  사원의  정보를  출력하는  예제 

ed  cur01

SET  SERVEROUTPUT  ON declare    vempno   NUMBER(4);    vename   VARCHAR2(20);    vsal   NUMBER(7,  2);

   CURSOR   C1    IS    select  empno,  ename,  sal    from  emp    where  deptno=20;

begin    OPEN  C1;

   dbms_output.put_line('empno   ename   sal');

   LOOP       FETCH  C1  INTO  vempno,  vename,  vsal;       EXIT  WHEN  C1%NOTFOUND;

      dbms_output.put_line(to_char(vempno)||'   '||vename||'   '||to_char(vsal));    END  LOOP;

Page 54: SQL Plus

end; /

저장하고  실행합니다.

@cur01 empno   ename   sal 7369   SMITH   800 ... ... ... ... ...

PL/SQL  procedure  successfully  completed.

3.  OPEN-FETCH-CLOSE가  없이  커서  처리 

ed  cur02

SET  SERVEROUTPUT  ON declare    vemp   emp%ROWTYPE;

   CURSOR   C1    IS    select  empno,  ename,  sal    from  emp    where  deptno=20;

begin    dbms_output.put_line('empno   ename   sal');

   FOR   vemp   IN   C1   LOOP       EXIT  WHEN  C1%NOTFOUND;

      dbms_output.put_line(to_char(vemp.empno)||'   '||vemp.ename||'   '||to_char(vemp.sal));    END  LOOP;

end; /

정장하고  실행합니다.

@cur02 empno   ename   sal 7369   SMITH   800 ...

Page 55: SQL Plus

...

...

...

...

PL/SQL  procedure  successfully  completed.

4.  커서의  상태 

%NOTFOUND   커서  영역의  자료가  모두  FETCH  됬는가를  알려줌 %FOUND      커서  영역에  FETCH가  되지  않은  자료가  있는가를  알려줌 %ISOPEN      커서가  OPEN된  상태인가를  알려줌 %ROWCOUNT   FETCH된  RECORD가  몇  개  있는지  알려줌 

cur02  예제를  수정합니다.

ed  cur02

SET  SERVEROUTPUT  ON declare    vemp   emp%ROWTYPE;

   CURSOR   C1    IS    select  empno,  ename,  sal    from  emp    where  deptno=20;

begin    dbms_output.put_line('empno   ename   sal   record  count');

   FOR   vemp   IN   C1   LOOP       EXIT  WHEN  C1%NOTFOUND;

      dbms_output.put_line(to_char(vemp.empno)||'   '||vemp.ename||'   '||to_char(vemp.sal)||'   '||C1%ROWCOUNT);    END  LOOP;

end; /

저장하고  실행합니다.

@cur02

결과는  record  count  추가되었습니다.

5.  커서를  활용한  실용  예제 1)  급여  총합을  구하는  예제 ed  cur03

Page 56: SQL Plus

SET  SERVEROUTPUT  ON declare    tot   NUMBER  :=  0;

   CURSOR   emp_cursor    IS    select  ename,  sal    from  emp;

begin    dbms_output.put_line('name   sal');    dbms_output.put_line('------------------------------------------');

   FOR  cur_var  IN  emp_cursor  LOOP       tot  :=  tot  +  cur_var.sal;       dbms_output.put_line(cur_var.ename);       dbms_output.put_line('-   '||cur_var.sal);    END  LOOP;       dbms_output.put_line('------------------------------------------');    dbms_output.put_line('-   '||tot); end; /

저장하고  실행합니다 

@cur03

2)  사원별  급여  현황을  그래포로  표현 ed  cur04

SET  SERVEROUTPUT  ON declare    CURSOR   emp_cursor    IS    select  ename,  sal    from  emp    order  by  sal  desc;

   star   varchar2(100);    cnt   number  :=  0;

begin    dbms_output.put_line('   sal  of  emp');    dbms_output.put_line('------------------------------------------');

   FOR  cur_var  IN  emp_cursor  LOOP       star  :=  NULL;       cnt  :=  round(cur_var.sal/100,  0);

      for  i  in  1..  cnt  loop          star  :=  star||'*';       end  loop;

Page 57: SQL Plus

   dbms_output.put_line(cur_var.ename);    dbms_output.put_line('-   '||star||'('||cur_var.sal||')');    END  LOOP; end; /

저장하고  실행합니다 

@cur04

저장된  PL/SQL을  저장  프로시저라고  합니다.

1.  저장  프로시저  생성 1)  테스트  테이블  생성 crete  table  emp_cp01 as select  *  from  emp;

2)  저장  프로시저  작성 ed  fun01

create  or  replace  procedure  del_all is begin    delete  from  emp_cp01; end; /

저장하고  실행합니다. @fun01

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

실제  실행은 

execute  del_all 입니다.  fun01  은  프로시저를  생성하기  위한  sql문입니다. 프로지저는  fun01.sql에서  정의된  함수명입니다.

실행하게  되면  emp_cp01의  자료를  모두  지웁니다.

확인 select  *  from  emp_cp01;

2.  저장  프로시저  작성시  발생하는  오류  처리 

Page 58: SQL Plus

SHOW  ERROR 를  수행하여  오류메시지를  확인후  편집기를  띄워서  해당  sql문을  수정합니다. 그리고  다시  @fun01  처럼  프로시저를  생성시켜주고,  최종적으로  테스트를  하기위해  execute  del_all  을  수행하면  오류처리가  완료됩니다.

3.  저장  프로시저  조회 저장  프로시저는  데이터  딕셔너리  중에서  user_source라는  뷰에  있습니다.

desc  user_source

select  name,  text  from  user_source;

4.  매개  변수 

1)  테스트  테이블  생성 create  table  emp_cp02 as select  *  from  emp;

2)  PL/SQL  작성 ed  fun02

create  or  replace  procedure  del_ename(vename  emp_cp02.ename%TYPE) is begin    delete  from  emp_cp02  where  ename=vename; end; /

저장하고  PL/SQL  을  실행하여  프로시저를  생성합니다. @fun02

프로시저를  실행합니다.

execute  del_ename('SCOTT');

해당  유저  데이터만  삭제  됩니다.

5.  IN,  OUT,  INOUT  매개  변수 1)  IN  매개  변수 입력만  가능한  매개  변수  입니다.

create  or  replace  procedure  del_ename(vename  emp_cp02.ename%TYPE) 는 create  or  replace  procedure  del_ename(vename  IN  emp_cp02.ename%TYPE) 지정하지  않으면  기본값이  IN  매개변수로  지정됩니다.

Page 59: SQL Plus

2)  OUT  매개  변수 ed  fun03

create  or  replace  procedure  sel_empno (    vempno   IN   emp.empno%TYPE,    vename   OUT   emp.ename%TYPE,    vsal   OUT   emp.sal%TYPE,    vjob   OUT   emp.job%TYPE ) is begin    select  ename,  sal,  job  into  vename,  vsal,  vjob    from  emp    where  empno  =  vempno; end; /

저장하고  프로시저를  생성하기  위해  PL/SQL  문을  실행합니다. @fun03

바인드  변수  선언 variable  var_ename   VARCHAR2(15); variable  var_sal   NUMBER; variable  var_job   VARCHAR2(9);   저장  프로시저를  활용합니다.

execute  sel_empno(7788,  :var_ename,  :var_sal,  :var_job);

print  var_ename; print  var_sal; print  var_job;

3)  INOUT  매개  변수 IN과  OUT  두  가지  용도로  사용할  수  있습니다.

6.  저장  함수 저장  함순는  저장  프로시저와  거의  유사한  용도로  사용됩니다. 차이점  :  함수는  실행  결과를  되돌려  받을수  있습니다.

1)  PL/SQL  작성 ed  fun04

create  or  replace  function  cal_bonus

Page 60: SQL Plus

(    vempno  IN  emp.empno%TYPE )    return  NUMBER is    vsal   NUMBER(7,  2); begin    select  sal  into  vsal    from  emp    where  empno=vempno;

   return  (vsal  *  200); end; /

위의  선언문중  return  NUMBER  라는  부분을  반드시  기억해  두어야  합니다. 리턴  타입이  숫자라는  것이죠...

2)  PL/SQL  실행하여  저장  함수  생성 @fun04

3)  저장함수  호출 저장할  변수  선언 

variable  var_x  NUMBER;

함수  호출 execute  :var_x  :=  cal_bonus(7788);

결과  출력 print  var_x;

4)  저장  함수를  호출하는  문장을  SQL문에  포함 select  sal,  cal_bonus(7788) from  emp where  empno=7788;

1.  패키지  생성과  실행 

ed  pack01

create  or  replace  package  exam_pack is

   procedure  sel_empno    (        vempno   IN   emp.empno%TYPE,        vename   OUT   emp.ename%TYPE,        vsal      OUT   emp.sal%TYPE,        vjob      OUT   emp.job%TYPE    );

Page 61: SQL Plus

   function  cal_bonus    (  vempno   IN   emp.empno%TYPE  )    return  NUMBER; end; /

show  errors

create  or  replace  package  body  exam_pack is    procedure  sel_empno    (        vempno   IN   emp.empno%TYPE,        vename   OUT   emp.ename%TYPE,        vsal      OUT   emp.sal%TYPE,        vjob      OUT   emp.job%TYPE    )    is    begin        select  ename,  sal,  job  into  vename,  vsal,  vjob        from  emp        where  empno=vempno;    end;

   function  cal_bonus    (  vempno   IN   emp.empno%TYPE  )    return  NUMBER    is        vsal   NUMBER(7,  2);    begin        select  sal  into  vsal        from  emp        where  empno=vempno;

       return  (vsal  *  200);    end; end; /

show  errors

@pack01

package  정의  부와  body  부분이  모두  오류가  없어야  합니다.

패키지  실행부  만들기 

ed  exe01

set  serveroutput  on;

Page 62: SQL Plus

create  or  replace  procedure  demo_procedure (  vempno   IN   emp.empno%TYPE  ) is     var_ename   VARCHAR2(15);     var_sal   NUMBER;     var_job   VARCHAR2(9);     var_bonus   NUMBER; begin     exam_pack.sel_empno(vempno,  var_ename,  var_sal,  var_job);

    var_bonus  :=  exam_pack.cal_bonus(vempno);

    dbms_output.put_line('name   sal   job   bonus    ');     dbms_output.put_line(var_ename||'   '||var_sal||'   '||var_job||'   '||var_bonus); end; /

show  errors;

execute  demo_procedure(7788)

저장하고 

실행  합니다. @exe01

오류가  없다면  

name   sal   job   bonus SCOTT   3000   ANALYSY   600000

의  결과가  출력  됩니다.

2.  전역  변수와  프로지서의  오버로딩과  ONE-TIME-ONLY  프로시저 

ed  pack02

create  or  replace  package  exam_pack2 is    gempno   NUMBER(4);  /*  전역  변수  */    procedure  sel_empno    (        vename   OUT   emp.ename%TYPE,        vsal      OUT   emp.sal%TYPE,        vjob      OUT   emp.job%TYPE    );

   procedure  sel_empno    (        vempno   IN   emp.empno%TYPE,

Page 63: SQL Plus

       vename   OUT   emp.ename%TYPE,        vsal      OUT   emp.sal%TYPE,        vjob      OUT   emp.job%TYPE    ); end; /

show  errors

create  or  replace  package  body  exam_pack2 is    procedure  sel_empno    (        vename   OUT   emp.ename%TYPE,        vsal      OUT   emp.sal%TYPE,        vjob      OUT   emp.job%TYPE    )    is    begin        select  ename,  sal,  job  into  vename,  vsal,  vjob        from  emp        where  empno=gempno;  /*  전역  변수에  저장된  사원번호로  조회  */    end;

   procedure  sel_empno    (        vempno   IN   emp.empno%TYPE,        vename   OUT   emp.ename%TYPE,        vsal      OUT   emp.sal%TYPE,        vjob      OUT   emp.job%TYPE    )    is    begin        select  ename,  sal,  job  into  vename,  vsal,  vjob        from  emp        where  empno=vempno;    end;

begin    /*  ONE-TIMR-ONLY  프로시저로서  전역  변수  gempno에  초기값을  설정합니다.  */    select  empno  into  gempno    from  emp    where  ename='SCOTT'; end; /

show  errors

@pack02

package  정의  부와  body  부분이  모두  오류가  없어야  합니다.

패키지  실행부  만들기 

Page 64: SQL Plus

ed  exe02

set  serveroutput  on;

create  or  replace  procedure  demo_procedure2 (  vempno   IN   emp.empno%TYPE  ) is     var_ename   VARCHAR2(15);     var_sal   NUMBER;     var_job   VARCHAR2(9);     var_bonus   NUMBER; begin     exam_pack2.sel_empno(vempno,  var_ename,  var_sal,  var_job);

    var_bonus  :=  exam_pack2.cal_bonus(vempno);

    dbms_output.put_line('name   sal   job   bonus    ');     dbms_output.put_line(var_ename||'   '||var_sal||'   '||var_job); end; /

show  errors;

execute  demo_procedure2(7788)

저장하고 

실행  합니다. @exe02

오류가  없다면  name   sal   job   SCOTT   3000   ANALYSY name   sal   job   SCOTT   3000   ANALYSY

의  결과가  출력  됩니다.

3.  DBMS_OUTPUT  패키지 dbms_output.put_line(String);

conn  system/manager select  object_name  from  dba_objecs where  object_type='PACKAGE'  and  object_name  like  'DBMS_%' order  by  object_name;

결과 OBJECT_NAME -----------------

Page 65: SQL Plus

DBMS_OFFLINE_UTL DBMS_OUTPUT

desc  DBMS_OUTPUT

dbms_output.  에  올수  있는  프로시저명  정리 

DISABLE         화면에  문자열을  출력하는  모드를  해제 ENABLE         화면에  문자열을  출력하는  모드를  설정 GET_LINE/GET_LINES   현재  라인에서  입력한  값을  읽어감 NEW_LINE      GET_LINE에서  읽혀진  행의  다음  라인을  읽음 PUT/PUT_LINE      주어진  데이터를  화면에  출력함 

4.  트리거  생성과  실행 

create  table  emp_tri (     empno  NUMBER(4)  PRIMARY  KEY,     ename  VARCHAR2(10),     sal   NUMBER(7,  2) );

create  or  replace  tigger  trg_sal after  insert on  emp_tri begin     update  emp_tri  set  sal=50; end;

/*  새로운  데이터가  추가  되면  emp_tri  테이블의  신입사원의  급여를  50으로  자동  갱신합니다.  */

insert  into  emp_tri(empno,  ename)  values  (  1111,  'tester'  );

select  *  from  emp_tri;

트리거의  삭제 DROP  trigger  trg_sal;

BEFORE  :  트랜잭션의  일부로  처리되며  실제  삽입이  일어나기  전에  트리거가  동작하는  것으로 

   기본  키  제약  조건에  위반된  데이터를  추가할  경우  이를  방지하기  위한  트리거를  생성    할  때  사용합니다.

AFTER  :  삽입이  일어난  후에  트리거가  작동하도록  하기  위해서  사용됩니다.

Page 66: SQL Plus

5.  예제를  통한  트리거의  적용 

1)  상품  테이블  작성 create  table  item (       idx   CHAR(6)  PRIMARY  KEY,   /*  상품코드  */       item  VARCHAR2(25)  NOT  NULL,   /*  상품명  */       maker  VARCHAR2(25),      /*  제조사  */       salesprice  NUMBER,      /*  소비자가격  */       stock  NUMBER  DEFAULT  0   /*  재고수량  */ );

//  주석은  제거  하세요 

2)  상품  입고  테이블  작성 create  table  warehousing (       widx  NUMBER  PRIMARY  KEY,   /*  입고번호  */       itemcode  CHAR(6)  REFERENCES  ITEM(idx),  /*  상품코드*/       windate  CHAR(8),      /*  입고일자  */       wstock  NUMBER,      /*  입고수량  */       wpartprice  NUMBER,      /*  입고단가  */       wprice  NUMBER      /*  입고금액  */ );

//  주석은  제거  하세요 

3)  자료  입력과  데이터  확인 테이블들이  제대로  생성되었는지  확인합니다. desc  item; desc  warehousing;

자료  입력 

insert  into  item  values  ('A00001',  'item1',  'LG',  500,  0); insert  into  item  values  ('A00002',  'item2',  'TG',  700,  0); insert  into  item  values  ('A00003',  'item3',  'SK',  600,  0);

자료  확인 

select  *  from  item;

4)  입고  트리거  작성과  테스트 

ed  wtrg

create  or  replace  trigger  trg02

Page 67: SQL Plus

   after  insert  on  warehousing    for  each  row DECLARE    v_cnt  NUMBER; BEGIN    select  count(*)    into  v_cnt    from  item    where  idx  =  :new.itemcode;

   if  v_cnt  =  0  then       insert  into  item(idx,  stock)       values  (:new.itemcode,  :new.wstock);    else       update  item       set  stock  =  stock  +  :new.wstock       where  idx  =  :new.itemcode;    end  if; END; /

//  입고트리거  스크립트  실행 @wtrg

Warning:  Trigger  created  with  compilation  errors. 에러가  발생하면..

show  errors  trigger  trg02 실행하면  트리거에  관련된  오류메시지를  보여  줍니다.

//  자료  입력 

isnert  into  warehousing  values  (1,  'A00001',  '20090823',  5,  320,  1600); select  *  from  warehousing; select  *  from  item;

isnert  into  warehousing  values  (2,  'A00002',  '20090823',  10,  600,  6800); select  *  from  warehousing; select  *  from  item;

insert  into  warehousing  values  (3,  'A00003',  '20090823',  3,  220,  660); insert  into  warehousing  values  (4,  'A00003',  '20090823',  5,  220,  1100);

select  *  from  item; select  *  from  warehousing  order  by  widx;

Page 68: SQL Plus

5)  갱신  트리거 이미  입고된  상품에  대해서  입고  수량이  변경되면  상품  테이블의  재고  수량  역시  변경되어야  합니다.

ed  trg03

create  or  replace  trigger  trg03    after  update  on  warehousing    for  each  row begin    update  item    set  stock  =  stock  +  (-:old.wstock+:new.wstock)    where  idx  =  :new.itemcode; end; /

@trg03

update  warehousing  set  wstock=10,  wprice=2000 where  widx=3;

select  *  from  warehousing  order  by  widx;

select  *  from  item;

6)  삭제  트리거 

입고  테이블에서  입고되었던  상황이  삭제되면  상품  테이블의  재고수량에서  삭제된  입고수량  만큼을  빼는  트리거  작성.

ed  trg04

create  or  replace  trigger  trg04    after  delete  on  warehousing    for  each  row begin    update  item    set  stock  =  stock  -  :old.wstock    where  idx  =  :old.itemcode; end; /

실행 @trg04

테스트 

delete  from  warehousing  where  widx=3;

select  *  from  warehousing  order  by  widx;

Page 69: SQL Plus

select  *  from  item;