[Day15] Oracle15 [10/18]

 

문제 1)tbl_score ν…Œμ΄λΈ”μ— μƒˆλ‘œμš΄ ν•™μƒμ˜ 성적 정보λ₯Ό μ €μž₯ν•˜λŠ” ν”„λ‘œμ‹œμ € : up_insScore
    p :   num, name, kor, eng, mat   μž…λ ₯ν•˜μ§€ μ•ŠμœΌλ©΄ 0 μ²˜λ¦¬
    μ΄μ , ν‰κ· , λ“±κΈ‰ κΉŒμ§€λŠ” μ²˜λ¦¬κ°€ λ˜λ„둝 .. 

CREATE OR REPLACE PROCEDURE up_insScore
(
      pnum   IN    tbl_score.num%type
    , pname  IN    tbl_score.name%type
    , pkor   IN    tbl_score.kor%type
    , peng   IN    tbl_score.eng%type
    , pmat   IN    tbl_score.mat%type
)
IS
   vtot tbl_score.tot%type;
   vavg tbl_score.avg%type;
   vgrade tbl_score.grade%type;
   -- vrank insa.rank%type;
BEGIN
   vtot := pkor + peng + pmat;
   vavg := vtot / 3;
   vgrade := CASE 
                       WHEN vavg >= 90 THEN 'A'
                       WHEN vavg >= 80 THEN 'B'
                       WHEN vavg >= 70 THEN 'C'
                       WHEN vavg >= 60 THEN 'D'
                       ELSE 'F'
              END;
    INSERT INTO tbl_score ( num, name, kor, eng, mat, tot, avg, grade )
       VALUES ( pnum, pname, pkor, peng, pmat, vtot, vavg, vgrade );
    
    up_rankScore;   --  또 λ‹€λ₯Έ μ €μž₯ ν”„λ‘œμ‹œμ € 호좜/μ‹€ν–‰
    COMMIT;
-- EXCEPTION
END;

 

EXEC UP_INSSCORE( 1102, 'λ°•μ‹ μž…', 99,88,67);

SELECT * 
FROM tbl_score;





문제 5) λ“±μˆ˜λ₯Ό μ²˜λ¦¬ν•˜λŠ” ν”„λ‘œμ‹œμ €  : up_rankScore

CREATE OR REPLACE PROCEDURE up_rankScore
IS 
  vrank tbl_score.rank%type;
BEGIN
    UPDATE tbl_score t
    SET rank = (  SELECT COUNT(*)+1 FROM tbl_score WHERE tot > t.tot ) ;
    -- WHERE
-- EXCEPTION
END;

EXEC UP_RANKSCORE;



-- κ° νŒ€μ—μ„œ ν’€μ΄~~ 

문제 2) tbl_score ν…Œμ΄λΈ”에 μƒˆλ‘œμš΄ ν•™μƒμ˜ μ„±μ  μ •λ³΄λ₯Ό μˆ˜μ •ν•˜λŠ” ν”„λ‘œμ‹œμ € : up_updScore     
   p  : num,   kor, eng, mat  μž…λ ₯ν•˜μ§€ μ•ŠμœΌλ©΄  μˆ˜μ • μ „μ˜ μ μˆ˜λ‘œ μ²˜λ¦¬
     μ΄μ , ν‰κ· , λ“±κΈ‰ κΉŒμ§€λŠ” μ²˜λ¦¬κ°€ λ˜λ„둝 .. 

문제 3)      tbl_score ν…Œμ΄λΈ”에  μ‚­μ œν•˜λŠ” ν”„λ‘œμ‹œμ € : up_delScore
  p  : num  

문제 4)   tbl_score ν…Œμ΄λΈ”에  λͺ¨λ“  ν•™μƒ μ •λ³΄λ₯Ό μ‘°νšŒν•˜λŠ” ν”„λ‘œμ‹œμ € : up_selScore



-------------------------------------------------------------------------------------
-- PLSQL  λ¬Έλ²• :  IF/WHILE/FOR λ¬Έ := INTO

-- μ˜ˆ) μ €μž₯ ν”„λ‘œμ‹œμ € 
--     νšŒμ›κ°€μž…   μ€‘    "ID μ€‘볡 μ²΄ν¬"
--    ID [         keni      ]  [ID μ€‘볡체크 λ²„νŠΌ]
     μ΄λ―Έ μ‚¬μš© μ€‘인 μ•„이디 μž…λ‹ˆλ‹€.
     μ‚¬μš© κ°€λŠ₯ν•œ μ•„이디 μž…λ‹ˆλ‹€.

CREATE OR REPLACE PROCEDURE up_idCheck
(
    pempno  IN emp.empno%type
    ,pempnoCheck OUT NUMBER --  μ‚¬μš©κ°€λŠ₯ 0,   μ‚¬μš©λΆˆκ°€λŠ₯ 1
)
IS
BEGIN
   SELECT COUNT(*) INTO pempnoCheck
   FROM emp
   WHERE empno = pempno;
-- EXCEPTION
END;

 

     
-- ν”„λ‘œμ‹œμ € ν…ŒμŠ€νŠΈ μš©λ„μ˜ μ΅λͺ… ν”„λ‘œμ‹œμ €.

DECLARE 
   vempno  emp.empno%type;
   vempnoCheck NUMBER(1);
BEGIN
    vempno := 7369;
   up_idCheck( vempno, vempnoCheck );
   -- DBMS_OUTPUT.PUT_LINE( vempnoCheck );  --0 , 1
   IF vempnoCheck = 0 THEN
      DBMS_OUTPUT.PUT_LINE( 'μ‚¬μš© κ°€λŠ₯ν•œ 아이디 μž…λ‹ˆλ‹€.' );
   ELSE
      DBMS_OUTPUT.PUT_LINE( '이미 μ‚¬μš© 쀑인 아이디 μž…λ‹ˆλ‹€.' );
   END IF;
END;



-- λ¬Έμ œ) ID/PWD μž…λ ₯ν•΄μ„œ λ‘œκ·ΈμΈ μ²˜λ¦¬
--      empno/ename
--    λ‘œκ·ΈμΈ μ„±κ³΅/ ID쑴재X / ID쑴재O PWD X
        0            1          -1
--        μ €μž₯ ν”„λ‘œμ‹œμ € μƒμ„± + ν…ŒμŠ€νŠΈ  up_logon

CREATE OR REPLACE PROCEDURE up_logon
(
    pempno    emp.empno%type
    , pename  emp.ename%type
    , plogonCheck OUT  NUMBER  -- 크기 X  성곡 0  ID X -1            1
)
IS
   vename emp.ename%type;
BEGIN
    SELECT COUNT(*)  INTO plogonCheck -- 1,  0
    FROM emp
    WHERE empno = pempno;  -- AND ename = pename
    
    IF plogonCheck = 1  THEN  -- ID μ‘΄μž¬ν•œλ‹€.
        SELECT ename INTO vename
        FROM emp
        WHERE empno = pempno;        
        IF  vename = pename THEN
            plogonCheck := 0;
        ELSE
            plogonCheck := 1;
        END IF;        
    ELSE 
       plogonCheck := -1;
    END IF;
-- EXCEPTION
END;
DECLARE
  vlogonCheck NUMBER;
BEGIN
   --UP_LOGON( 7369, 'SMITH', vlogonCheck);
   UP_LOGON( 7369, 'KENIK', vlogonCheck);
   --UP_LOGON( 9999, 'SMITH', vlogonCheck);
   
   IF vlogonCheck=0 THEN
       DBMS_OUTPUT.PUT_LINE('둜그인 성곡');
   ELSIF vlogonCheck=1 THEN
      DBMS_OUTPUT.PUT_LINE('IDλŠ” μ‘΄μž¬ν•˜μ§€λ§Œ pwdκ°€ 잘λͺ»λ˜μ—ˆλ‹€.');
   ELSE
      DBMS_OUTPUT.PUT_LINE('IDλŠ” 쑴재 X.');
   END IF;
END;


-- μ €μž₯ ν•¨μˆ˜( Stored Function )
-- μ£Όλ―Όλ²ˆν˜Έ -> λ‚¨μž/μ—¬μž λ°˜ν™˜ν•˜λŠ” uf_gender μ €μž₯ ..

-- λ¬Έμ œ) μ£Όλ―Όλ²ˆν˜Έ -> μƒλ…„월일(yyyy.mm.dd) λ°˜ν™˜ν•˜λŠ” uf_birth()
-- λ¬Έμ œ) μ£Όλ―Όλ²ˆν˜Έ -> λ§Œλ‚˜μ΄ λ°˜ν™˜ν•˜λŠ” uf_age()
SELECT num, name, ssn
   , uf_birth(ssn)
   , uf_age( ssn )  -- 
FROM insa;

CREATE OR REPLACE FUNCTION uf_age
(
  prrn VARCHAR2
)
RETURN NUMBER 
IS
   vischeck number(1);
   vt_year  number(4);
   vb_year  number(4);
   vage     number(3);
BEGIN
   vischeck :=  SIGN(  TRUNC( SYSDATE ) -  TO_DATE(  SUBSTR( prrn, 3,4), 'MMDD') );
   vt_year  := TO_CHAR( SYSDATE  , 'YYYY');
   vb_year  := CASE  
                 WHEN SUBSTR( prrn, 8, 1 ) IN (1,2,5,6) THEN '1900' + SUBSTR( prrn, 1,2)
                 WHEN SUBSTR( prrn, 8, 1 ) IN (3,4,7,8) THEN '2000' + SUBSTR( prrn, 1,2)
                 ELSE                                       '1800'  + SUBSTR( prrn, 1,2)
             END;
   vage     :=  CASE  VISCHECK
                WHEN -1 THEN  -- 생일 μ•ˆμ§€λ‚œκ²ƒ
                 vt_year - vb_year-1
                ELSE   -- 0, 1
                 vt_year - vb_year
            END  ;        
   RETURN vage;         
--EXCEPTION
END;
CREATE OR REPLACE FUNCTION uf_birth
(
   pssn insa.ssn%type
)
RETURN VARCHAR2
IS
    -- 1900,1800,2000
    vcentry NUMBER(2);
    vgender NUMBER(1);
    vbirth VARCHAR2(20);
    vssn6 VARCHAR2(6);
BEGIN

   vssn6 := SUBSTR( pssn, 0, 6 );
   vgender := SUBSTR( pssn, -7, 1);
   vcentry := CASE 
                   WHEN vgender IN (1,2,5,6) THEN 19
                   WHEN vgender IN ( 3,4,7,8) THEN 20
                   ELSE      18
              END;
              -- 19911223
  vbirth :=  TO_CHAR(  TO_DATE(  CONCAT( vcentry,  vssn6) ), 'YYYY.MM.DD' );

  RETURN vbirth;
--EXCEPTION
END;



--예)  IN, OUT,                IN OUT μž…μΆœλ ₯ νŒŒλΌλ―Έν„° X

DECLARE 
   vphone VARCHAR2(9) := '8765-8653';
BEGIN
   up_phone( vphone );
   
   DBMS_OUTPUT.PUT_LINE( vphone );  -- '8765'
END;
CREATE OR REPLACE PROCEDURE up_phone
(
   pphone IN OUT VARCHAR2  -- μž… 좜λ ₯용 νŒŒλΌλ―Έν„°
)
IS
BEGIN
   pphone :=  SUBSTR( pphone, 0, 4);
--EXCEPTION
END;

-- [트리거] / μ˜ˆμ™Έμ²˜λ¦¬ / νŒ¨ν‚€μ§€ --
PL/SQL 6가지 μ’…λ₯˜
1) μ΅λͺ… ν”„λ‘œμ‹œμ €
2) μ €μž₯ ν”„λ‘œμ‹œμ €
3) μ €μž₯ ν•¨μˆ˜
4) νŠΈλ¦¬κ±°
5) νŒ¨ν‚€μ§€
6) X

[ 트리거 ( trigger ) ]
1. νŠΈλ¦¬κ±° ? λ°©μ•„μ‡   -> μžλ™ -> μ΄μ•Œ~
2. μ–΄λ–€ μž‘μ—… μ „(befor) λ˜λŠ” ν›„( after) νŠΈλ¦¬κ±°μ— μ •μ˜ν•œ λ‘œμ§μ„ μ‹€ν–‰ν•˜λŠ” PL/SQL의 ν•œ μ’…λ₯˜
3. λŒ€μƒ ν…Œμ΄λΈ”에 λ―Έλ¦¬ νŠΈλ¦¬κ±°λ₯Ό μ§€μ •ν•˜λ©΄ 
   μ–΄λ–€ μ΄λ²€νŠΈ(DML)κ°€ λ°œμƒν•  λ•Œ μžλ™μœΌλ‘œ μ§€μ •λœ νŠΈλ¦¬κ±°κ°€ μž‘λ™ν•˜λ„λ‘ ν•œ κ°μ²΄λ₯Ό νŠΈλ¦¬κ±°λΌ ν•œλ‹€. 
4. μ˜ˆ)

[νŠΈλžœμž­μ…˜μ²˜λ¦¬ ]

        1)   μž…κ³ ν…Œμ΄λΈ”(λŒ€μƒν…Œμ΄λΈ”) + DML(insert)
           PK     μƒν’ˆ      μž…κ³ λ‚ μ§œ    μž…κ³ μˆ˜λŸ‰
           1     P001      22.10.18     10
           
           μžλ™μœΌλ‘œ    
        2)  μž¬κ³ ν…Œμ΄λΈ”   μž¬κ³ μˆ˜λŸ‰   μˆ˜μ •(update)
           1     P001    60


5. 트리거 μ˜ˆμ•½μ–΄

  1) before  μž‘μ—… μ „에 νŠΈλ¦¬κ±°κ°€ μžλ™ μ²˜λ¦¬.
  2) after        ν›„
  3) for each row : ν–‰λ§ˆλ‹€ μ²˜λ¦¬ λ˜λŠ” νŠΈλ¦¬κ±°( ν–‰ νŠΈλ¦¬κ±° )
  4) referencing : μ˜ν–₯λ°›λŠ” ν–‰μ˜ κ°’ μ°Έμ‘°
  5) :old    μ°Έμ‘° μ „ 컬럼의 κ°’
       :new  μ°Έμ‘° ν›„ 컬럼의 κ°’


6. νŠΈλ¦¬κ±° μ„ μ–Έ ν˜•μ‹

CREATE OR REPLACE TRIGGER 트리거λͺ…
[ before λ˜λŠ” after ]
트리거이벀트  ON λŒ€μƒν…Œμ΄λΈ”
[for each row  [ when trigger 쑰건] ]
DECLARE
     -- λ³€μˆ˜ μ„ μ–Έ
BEGIN
     -- μ‹€ν–‰ λΈ”λŸ­
EXCEPTION
    -- μ˜ˆμ™Έ μ²˜λ¦¬λΈ”λŸ­
END;


7. νŠΈλ¦¬κ±° ν™•μΈ

SELECT *
FROM user_triggers;


8. νŠΈλ¦¬κ±° μƒμ„±, μ‚­μ œ, ν™œμ„±ν™”/λΉ„ν™œμ„±ν™”.

9. νŠΈλ¦¬κ±° μ˜ˆμ œ)
   A ν…Œμ΄λΈ” : insert, update, delete μ΄λ²€νŠΈκ°€ λ°œμƒμ„ ν•˜λ©΄     
   B ν…Œμ΄λΈ” : λ‘œκ·Έ κΈ°λ‘μ„ μžλ™μœΌλ‘œ λ‚¨κΈ°λŠ” νŠΈλ¦¬κ±° μƒμ„±..

CREATE TABLE tbl_trigger1(
  id   number primary key
  , name varchar2(20)
);
CREATE TABLE tbl_trigger2(
  memo  varchar2(100)  -- 둜그 기둝
  , ilja date  default sysdate
);


  AFTER νŠΈλ¦¬κ±° μ„ μ–Έ)

-> tbl_trigger1에 insertκ°€ μΌμ–΄λ‚œ ν›„ begin μ‹€ν–‰ 

  CREATE OR REPLACE TRIGGER ut_ex01
  AFTER
  INSERT ON tbl_trigger1
  --FOR EACH ROW ν–‰νŠΈλ¦¬κ±°
  --DECLARE
  BEGIN
     INSERT INTO tbl_trigger2 ( memo ) VALUES ( 'TBL_TRIGGER1 INSERT...' );     
     -- COMMIT/ROLLBACK X
  --EXCEPTION
  END;
INSERT INTO tbl_trigger1 VALUES ( 1 , '홍길동' );
INSERT INTO tbl_trigger1 VALUES ( 2 , '김길동' );
INSERT INTO tbl_trigger1 VALUES ( 3 , '졜기수' );
INSERT INTO tbl_trigger1 VALUES ( 4 , 'λ°•κΈ°μˆ˜' );

 

--  νŠΈλ¦¬κ±° + UPDATE
 

CREATE OR REPLACE TRIGGER ut_ex02
  AFTER
  UPDATE ON tbl_trigger1
  --FOR EACH ROW ν–‰νŠΈλ¦¬κ±°
  --DECLARE
  BEGIN
     INSERT INTO tbl_trigger2 ( memo ) VALUES ( 'TBL_TRIGGER1 UPDATE...' );     
     -- COMMIT/ROLLBACK X
  --EXCEPTION
  END;
  UPDATE tbl_trigger1
  SET name = 'κ΄€λ¦¬μž'
  WHERE id = 1;

 

ν•©μ³μ„œ 트리거 생성 κ°€λŠ₯! (IF / ELSEIF)

CREATE OR REPLACE TRIGGER ut_ex01
  AFTER
  INSERT OR UPDATE OR DELETE ON tbl_trigger1
  --FOR EACH ROW ν–‰νŠΈλ¦¬κ±°
  --DECLARE
  BEGIN
        
     -- COMMIT/ROLLBACK X
     
     IF  INSERTING THEN
        INSERT INTO tbl_trigger2 ( memo ) VALUES ( 'TBL_TRIGGER1 INSERT...' );  
     ELSIF UPDATING THEN      
         INSERT INTO tbl_trigger2 ( memo ) VALUES ( 'TBL_TRIGGER1 UPDATE...' );  
     ELSIF DELETING THEN      
         INSERT INTO tbl_trigger2 ( memo ) VALUES ( 'TBL_TRIGGER1 DELETE...' );       
     END IF;
     
  --EXCEPTION
  END;



 --예제2) λ§Œμ•½μ—
 --   tbl_trigger1 ν…Œμ΄λΈ”에 I/U/D μž‘업은 κ·Όλ¬΄μ‹œκ°„μ—λ§Œ ν•  μˆ˜ μžˆλ„둝 ν•˜κ² λ‹€.
 --       ν† /일 X    κ·Όλ¬΄μ‹œκ°„은 μ£Όλ§(ν† /일)μ œμ™Έ ν•˜κ³   ν‰μΌ(  9:00~18:00 )

-- BEFORE 트리거둜 μ„ μ–Έ--

CREATE OR REPLACE TRIGGER ut_ex03
BEFORE  -- AFTER
INSERT OR UPDATE OR DELETE ON tbl_trigger1
-- FOR EACH ROW ν–‰νŠΈλ¦¬κ±°
-- DECLARE
BEGIN
   IF  TO_CHAR(SYSDATE, 'DY')  IN ('ν† ','일')  
   OR   NOT (TO_CHAR(SYSDATE, 'HH24') BETWEEN 9 AND 12 )  THEN
       -- κ°•μ œλ‘œ μ—λŸ¬ λ°œμƒ -> I,U,D  DML 문도 μ·¨μ†Œ.
       -- JAVA    throw λ¬Έ new Exception();
       -- RAISE_APPLICATION_ERROR(μ—λŸ¬μ½”λ“œ, μ—λŸ¬λ©”μ‹œμ§€);
       RAISE_APPLICATION_ERROR(-20000, 'μ§€κΈˆμ€ κ·Όλ¬΄μ‹œκ°„μ΄ μ•„λ‹ˆκΈ° λ•Œλ¬Έμ— μž‘μ—…μ€ μ•ˆλ©λ‹ˆλ‹€.');
   END IF;
-- EXCEPTION
END;

 

였λ₯˜ 보고 
--ORA-20000: μ§€κΈˆμ€ κ·Όλ¬΄μ‹œκ°„이 μ•„λ‹ˆκΈ° λ•Œλ¬Έμ— μž‘업은 μ•ˆλ©λ‹ˆλ‹€.
--ORA-06512: at "SCOTT.UT_EX03", line 7
--ORA-04088: error during execution of trigger 'SCOTT.UT_EX03'


-- μ˜ˆμ œ3)

create table tbl_trg1
(
    hak varchar2(10) primary key
  , name varchar2(20)
  , kor number(3)
  , eng number(3)
  , mat number(3)
);
create table tbl_trg2
(
  hak varchar2(10) primary key
  , tot number(3)
  , avg number(5,2)
  , constraint fk_test2_hak foreign key(hak)   references tbl_trg1(hak)
);


-- μžλ™μœΌλ‘œ tbl_trg2 ν…Œμ΄λΈ”  1, tot, avg μ²˜λ¦¬... μ €μž₯. (트리거)
-- ORA-04082: NEW or OLD references not allowed in table level triggers
-- ν…Œμ΄λΈ” λ ˆλ²¨ νŠΈλ¦¬κ±°μ—μ„œλŠ” :NEW,   :OLD μ‚¬μš©ν•  μˆ˜ μ—†λ‹€. 
-- ν–‰ λ ˆλ²¨ νŠΈλ¦¬κ±° FOR EACH ROWλŠ” 
-- UPDATE 10λ²ˆλΆ€μ„œ 사원 3λͺ… -> 트리거 1번(ν…Œμ΄λΈ”λ ˆλ²¨) /  3번(둜우레벨)

 

CREATE OR REPLACE TRIGGER ut_trg1dml
AFTER
INSERT ON tbl_trg1
FOR EACH ROW    -- ν–‰ 레벨 트리거
DECLARE
  vtot NUMBER(3) ;
  vavg NUMBER(5,2) ;
BEGIN
   -- 1, 'hong', 90,78, 99 
   vtot := :NEW.kor + :NEW.eng + :NEW.mat;
   vavg := vtot / 3;
   INSERT INTO tbl_trg2 ( hak, tot, avg ) VALUES ( :NEW.hak , vtot , vavg );
-- EXCEPTION
END;
INSERT INTO tbl_trg1 ( hak, name, kor, eng, mat ) VALUES ( 1, 'hong', 90,78, 99 );

 


 2) 1   hong   90   7 8   99   μˆ˜μ •λœκΈ° 전에 μ›λž˜ κ°’   :OLD
     1   hong   87   67    100  μƒˆλ‘œ μˆ˜μ •λ  κ°’         :NEW   

UPDATE TBL_TRG1
SET kor = 87, eng = 67, mat = 100
WHERE hak = 1;


μžλ™   tot/avg μˆ˜μ • λ˜μ–΄μ•Όν•¨
  

CREATE OR REPLACE TRIGGER ut_trg1dml
AFTER
UPDATE OR INSERT ON tbl_trg1
FOR EACH ROW    -- ν–‰ 레벨 트리거
DECLARE
  vtot NUMBER(3) ;
  vavg NUMBER(5,2) ;
BEGIN
   -- 1   hong   87   67    100
   vtot := :NEW.kor + :NEW.eng + :NEW.mat;
   vavg := vtot / 3;
   
   IF  INSERTING THEN
           -- 1, 'hong', 90,78, 99            
           INSERT INTO tbl_trg2 ( hak, tot, avg ) VALUES ( :NEW.hak , vtot , vavg );
   ELSIF UPDATING THEN
       UPDATE tbl_trg2
       SET tot = vtot , avg = vavg
       WHERE hak = :OLD.hak;  -- :NEW.hak
   END IF;   
-- EXCEPTION
END;


 λ¬Έμ œ3) tbl_trg1 ν…Œμ΄λΈ”μ˜ 1번 ν•™μƒμ˜ μ •λ³΄λ₯Ό μ‚­μ œν•˜λ©΄
    μžλ™ tbl_trg2 ν…Œμ΄λΈ”μ˜  1번 μ •λ³΄(λ ˆμ½”λ“œ) μ‚­μ œ....ν•˜λŠ” νŠΈλ¦¬κ±° μƒμ„±, ν…ŒμŠ€νŠΈν•˜μ„Έμš”.. 
  

  DELETE FROM   tbl_trg1
  WHERE hak = 1;


-- ORA-02292: integrity constraint (SCOTT.FK_TEST2_HAK) violated - child record found
-- tbl_trg2 ν…Œμ΄λΈ”μ—μ„œ μ°Έμ‘°
    

CREATE OR REPLACE TRIGGER ut_trg102
BEFORE
DELETE ON tbl_trg1
FOR EACH ROW    -- ν–‰ 레벨 트리거
BEGIN
     DELETE FROM tbl_trg2
     WHERE hak = :OLD.hak ;   -- :NEW.hak X
-- EXCEPTION
END;


--DELETE FROM dept
--WHERE deptno = 10;
--ORA-02292: integrity constraint (SCOTT.FK_DEPTNO) violated - child record found



-- νŒ¨ν‚€μ§€(package )-- 
1. κ΄€κ³„λ˜λŠ” νƒ€μž…, ν”„λ‘œκ·Έλž¨ κ°μ²΄, μ„œλΈŒν”„λ‘œκ·Έλž¨(procedure, function)을 λ…Όλ¦¬μ μœΌλ‘œ λ¬Άμ–΄ λ†“은 κ²ƒ.
2. νŒ¨ν‚€μ§€λŠ” specification( λͺ…μ„Έ, μ‚¬μ–‘ )κ³Ό body( λͺΈμ²΄ ) λΆ€λΆ„μœΌλ‘œ κ΅¬μ„± 
--dbms_output  .  put_line()
--νŒ¨ν‚€μ§€λͺ….ν•¨μˆ˜λͺ…()

-- specificationλΆ€λΆ„ --

CREATE OR REPLACE PACKAGE employee_pkg 
as 
   procedure print_ename(p_empno number); 
   procedure print_sal(p_empno number); 
end employee_pkg; 
-- Package EMPLOYEE_PKG이(κ°€) μ»΄νŒŒμΌλ˜μ—ˆμŠ΅λ‹ˆλ‹€.

 

-- body λΆ€λΆ„

CREATE OR REPLACE PACKAGE BODY employee_pkg
as 
   
       procedure print_ename
       (
         p_empno number
       ) 
       is 
        l_ename emp.ename%type; 
      begin 
        select ename 
          into l_ename 
          from emp 
          where empno = p_empno; 
       dbms_output.put_line(l_ename); 
     exception 
       when NO_DATA_FOUND then 
         dbms_output.put_line('Invalid employee number'); 
     end print_ename; 
  
  procedure print_sal(p_empno number) is 
     l_sal emp.sal%type; 
   begin 
     select sal 
       into l_sal 
       from emp 
       where empno = p_empno; 
     dbms_output.put_line(l_sal); 
   exception 
     when NO_DATA_FOUND then 
       dbms_output.put_line('Invalid employee number'); 
   end print_sal; 
  
   end employee_pkg;
exec employee_pkg.print_ename(1234); 
exec employee_pkg.print_ename(7369); 
exec employee_pkg.print_sal(7369);



-- μ˜€μ „)  id μ€‘볡체크, λ‘œκ·ΈμΈ μ €μž₯ν”„λ‘œμ‹œμ €.....

  1) specification λΆ€λΆ„

CREATE OR REPLACE PACKAGE   logon_pkg
AS
    PROCEDURE up_idCheck
    (
       pempno IN emp.empno%TYPE  -- ID
       , pempnoCheck OUT NUMBER  --  0(μ‚¬μš©κ°€λŠ₯)     1(μ‚¬μš©λΆˆκ°€λŠ₯)
    );
    PROCEDURE up_logon
    (
       pempno IN emp.empno%TYPE    -- ID
       , pename IN emp.ename%TYPE  -- PWD
       , plogonCheck OUT NUMBER  --  0(λ‘œκ·ΈμΈμ„±κ³΅)     1(IDμ‘΄μž¬ν•˜μ§€μ•ŠμœΌλ©΄)  -1(ID o, PWD X)
    );
    FUNCTION uf_age
    (
      prrn VARCHAR2
    )
    RETURN NUMBER ;
    
END logon_pkg;

 

2) body λΆ€λΆ„

CREATE OR REPLACE PACKAGE BODY   logon_pkg
AS
    PROCEDURE up_idCheck
    (
       pempno IN emp.empno%TYPE  -- ID
       , pempnoCheck OUT NUMBER  --  0(μ‚¬μš©κ°€λŠ₯)     1(μ‚¬μš©λΆˆκ°€λŠ₯)
    )
    IS
    BEGIN
      SELECT COUNT(*) INTO pempnoCheck
      FROM emp
      WHERE empno = pempno;
    --EXCEPTION
    END up_idCheck;
    
    PROCEDURE up_logon
    (
       pempno IN emp.empno%TYPE    -- ID
       , pename IN emp.ename%TYPE  -- PWD
       , plogonCheck OUT NUMBER  --  0(λ‘œκ·ΈμΈμ„±κ³΅)     1(IDμ‘΄μž¬ν•˜μ§€μ•ŠμœΌλ©΄)  -1(ID o, PWD X)
    )
    IS
      vename emp.ename%TYPE;
    BEGIN
      SELECT COUNT(*) INTO plogonCheck  -- 1   , 0
      FROM emp
      WHERE empno = pempno;
    
      IF plogonCheck = 1  THEN  -- ID μ‘΄μž¬ν•œλ‹€λ©΄ 
        SELECT ename INTO vename
        FROM emp
        WHERE empno = pempno; 
        IF vename = pename THEN  -- PWD μΌμΉ˜ν•œλ‹€λ©΄
          plogonCheck := 0;  -- 둜그인 성곡
        ELSE
          plogonCheck := -1;  -- 둜그인 μ‹€νŒ¨
        END IF;
      ELSE 
         plogonCheck := 1;  -- ID μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ”κ²½μš°
      END IF;
    --EXCEPTION
    END up_logon;
    
    FUNCTION uf_age
    (
      prrn VARCHAR2
    )
    RETURN NUMBER 
    IS
       vischeck number(1);
       vt_year  number(4);
       vb_year  number(4);
       vage     number(3);
    BEGIN
       vischeck :=  SIGN(  TRUNC( SYSDATE ) -  TO_DATE(  SUBSTR( prrn, 3,4), 'MMDD') );
       vt_year  := TO_CHAR( SYSDATE  , 'YYYY');
       vb_year  := CASE  
                     WHEN SUBSTR( prrn, 8, 1 ) IN (1,2,5,6) THEN '1900' + SUBSTR( prrn, 1,2)
                     WHEN SUBSTR( prrn, 8, 1 ) IN (3,4,7,8) THEN '2000' + SUBSTR( prrn, 1,2)
                     ELSE                                       '1800'  + SUBSTR( prrn, 1,2)
                 END;
       vage     :=  CASE  VISCHECK
                    WHEN -1 THEN  -- 생일 μ•ˆμ§€λ‚œκ²ƒ
                     vt_year - vb_year-1
                    ELSE   -- 0, 1
                     vt_year - vb_year
                END  ;        
       RETURN vage;         
    --EXCEPTION
    END uf_age;
    
END logon_pkg;
SELECT num, name , ssn, logon_pkg.uf_age(ssn) age
FROM insa;


-- PL/SQL μž‘μ„± 제좜 (νšŒμ‚¬,싀무) : VIEW, SP, SF, T, P--
-- μ»€μ„œ( CURSOR ) + νŒŒλΌλ―Έν„°λ₯Ό μ΄μš©ν•˜λŠ” λ°©λ²• --

EXEC UP_SelDeptEmp(   20   );   -- 6λͺ…  + μ»€μ„œ μ‚¬μš©(λͺ…,μ•”)

-- 1) λ°©λ²•

CREATE OR REPLACE PROCEDURE UP_SelDeptEmp
(
   pdeptno IN dept.deptno%type
)
IS
    vdeptno emp.deptno%type;
    vename emp.ename%type;
    vsal emp.sal%type;    
     CURSOR c_emp IS     (
                             SELECT deptno, ename, sal
                             FROM emp 
                             WHERE deptno = pdeptno
                         );
BEGIN
     OPEN c_emp;     
     LOOP
        FETCH c_emp INTO vdeptno, vename, vsal;
       EXIT WHEN c_emp%NOTFOUND;
       DBMS_OUTPUT.PUT_LINE( vdeptno || ', ' || vename || ', ' || vsal);
     END LOOP;
     
     CLOSE c_emp;
--EXCEPTION
END;



-- 2) λ°©λ²•

CREATE OR REPLACE PROCEDURE UP_SelDeptEmp
(
   pdeptno IN dept.deptno%type
)
IS
    vdeptno emp.deptno%type;
    vename emp.ename%type;
    vsal emp.sal%type;    
     CURSOR c_emp( cpdeptno dept.deptno%type ) IS     (
                             SELECT deptno, ename, sal
                             FROM emp 
                             WHERE deptno = cpdeptno
                         );
BEGIN
     OPEN c_emp ( pdeptno );     
     LOOP
        FETCH c_emp INTO vdeptno, vename, vsal;
       EXIT WHEN c_emp%NOTFOUND;
       DBMS_OUTPUT.PUT_LINE( vdeptno || ', ' || vename || ', ' || vsal);
     END LOOP;
     
     CLOSE c_emp;
--EXCEPTION
END;



-- 3) UP_좜λ ₯ν•˜λŠ” ν”„λ‘œμ‹œμ €λ“€μ€ μ§€κΈˆκΉŒμ§€ DBMS_OUPUT.PUT_LINE() μ—¬λŸ¬ λ ˆμ½”λ“œλ₯Ό 화면에  μΆœλ ₯
--     μžλ°” ν”„λ‘œκ·Έλž¨ μ—°λ™ <-  μ»€μ„œ(데이터 μ €μž₯ κ°μ²΄) μžμ²΄λ₯Ό μΆœλ ₯용 λ§€κ°œλ³€μˆ˜ λ°˜ν™˜.
--        [ SYS_REFCURSOR, 였라클9i 이후~  ] 이걸둜 κΈ°μ–΅ ***
--        REF CURSORS ( μ˜€λΌν΄ 9i μ΄μ „ )

CREATE OR REPLACE PROCEDURE  up_selInsa
(
   pcursor IN SYS_REFCURSOR
)
IS
   vname insa.name%type;
   vcity insa.city%type;
   vbasicpay insa.basicpay%type;
BEGIN
  LOOP
     FETCH pcursor INTO vname, vcity, vbasicpay;
     EXIT WHEN pcursor%NOTFOUND;
     DBMS_OUTPUT.PUT_LINE( vname || ', ' || vcity  || ', ' || vbasicpay);
  END LOOP;
END;

 

γ„΄ μ—¬κΈ΄ OPEN이 μ—†μŒ

[μ €μž₯ ν”„λ‘œμ‹œμ €]

CREATE OR REPLACE PROCEDURE up_test_selInsa
IS
  vcursor SYS_REFCURSOR;  -- μ»€μ„œ λ³€μˆ˜ μ„ μ–Έ
BEGIN   
   OPEN vcursor FOR SELECT name, city, basicpay FROM insa;   
   UP_SELINSA( vcursor );  -- LOOP   FETCH   
   CLOSE vcursor;   
-- EXCEPTION
END;
EXEC up_test_selInsa;


--  + μ˜€λΌν΄ μ €μž₯ ν”„λ‘œμ‹œμ € μ‹€ν–‰ ν›„ μ»€μ„œ μΆœλ ₯용 λ§€κ°œλ³€μˆ˜λ‘œ λ„˜κ²¨μ£Όλ©΄ 
--   μžλ°”μ—μ„œ  μ»€μ„œλ₯Ό λ°›μ•„μ„œ μ‚¬μš©ν•˜λŠ” μ½”λ”©.  ( κΈ°μ–΅ , μ•”κΈ° )

CREATE OR REPLACE PROCEDURE up_ex05
(
    pcursor  OUT  SYS_REFCURSOR
)
IS
BEGIN
    OPEN pcursor FOR SELECT name, city, basicpay FROM insa;
    
    -- LOOP~ FETCH X
    -- CLOSE X
END;

 


-- PL/SQL λΈ”λŸ­( EXCEPTION λΈ”λŸ­ ) - μ˜ˆμ™Έ 처리 방법  
  1) λ―Έλ¦¬ μ •μ˜λœ μ—λŸ¬ μ²˜λ¦¬λ°©λ²• ( 7가지 )

SELECT ename, sal  
FrOM emp
WHERE sal = 1250;

 

--

EXEC up_emplist(  sal );
EXEC up_emplist(  10000 );  -- 0  ORA-01403: no data found
EXEC up_emplist(  5000 );   -- 1
EXEC up_emplist(  1250 );   -- 2  ORA-01422: exact fetch returns more than requested number of rows

 

--

CREATE OR REPLACE PROCEDURE up_emplist
(
   psal emp.sal%type
)
IS 
   vename emp.ename%type;
BEGIN
   SELECT ename  INTO vename
   FROM emp
   WHERE sal = psal;
   
   DBMS_OUTPUT.PUT_LINE(  psal || ' ==> '  || vename );   
EXCEPTION  -- μ˜ˆμ™Έμ²˜λ¦¬ 절
   WHEN no_data_found THEN
     RAISE_APPLICATION_ERROR(-20002, '> QUERY DATA NOT FOUND.');  -- JAVA 연동 + μ˜ˆμ™Έμ²˜λ¦¬.
   WHEN TOO_MANY_ROWS THEN
     RAISE_APPLICATION_ERROR(-20003, '> QUERY TOO MANY ROWS FOUND.');
   WHEN OTHERS THEN
      RAISE_APPLICATION_ERROR(-20004, '> QUERY OTHERS EXCEPTION FOUND.');
END;
-- Procedure UP_EMPLIST이(κ°€) μ»΄νŒŒμΌλ˜μ—ˆμŠ΅λ‹ˆλ‹€.


--2) λ―Έλ¦¬ μ •μ˜ λ˜μ§€ μ•ŠλŠ” μ˜ˆμ™Έ μ²˜λ¦¬ λ°©λ²•

DELETE FROM dept WHERE deptno >= 50;  
COMMIT;


SELECT * FROM dept;

--

INSERT INTO dept  VALUES ( 40, 'QC', 'SEOUL');
ORA-00001: unique constraint (SCOTT.PK_DEPT) violated


-- λ―Έλ¦¬ μ •μ˜λ˜μ§€ μ•ŠλŠ” μ˜ˆ   -02291
-- ORA-02291: integrity constraint (SCOTT.FK_DEPTNO) violated - parent key not found

INSERT INTO emp ( empno, ename, deptno ) VALUES ( 9999, 'kenik', 90 );

 

CREATE OR REPLACE PROCEDURE up_insEmp
(
   pempno  emp.empno%type
   , pename emp.ename%type
   , pdeptno emp.deptno%type
)
IS
    v_invalid_deptno EXCEPTION;
    PRAGMA EXCEPTION_INIT( v_invalid_deptno,-02291);
BEGIN
   INSERT INTO emp ( empno, ename, deptno ) VALUES ( pempno, pename, pdeptno );
   COMMIT;
EXCEPTION
   WHEN v_invalid_deptno THEN 
      RAISE_APPLICATION_ERROR(-20999, '> QUERY DEPTNO FK NOT FOUND.');
   WHEN OTHERS THEN
     RAISE_APPLICATION_ERROR(-20004, '> QUERY OTHERS EXCEPTION FOUND.');
END;
EXEC UP_INSEMP( 9999, 'KENIK', 90 );

-- ORA-20999: > QUERY DEPTNO FK NOT FOUND.

3) μ‚¬μš©μžκ°€ μ •μ˜ν•œ μ—λŸ¬ μ²˜λ¦¬λ°©λ²• 

μžλ°”μ—μ„œ throw 와 λΉ„μŠ·

--μžλ°” -  class  STUDNENT{
--           int kor;           0~100   κ΅­μ–΄μ μˆ˜ λ²”μœ„λ²—μ–΄λ‚«λ‹€ μ˜ˆμ™Έ μ²˜λ¦¬
--}
--class ScoreOutOFBoundException extends Exception{
--}
-- throw new ScoreOutOFBoundException();
SELECT COUNT(*) INTO vempcount
FROM emp
WHERE sal BETWEEN  (psal-100) AND (psal+100) ;

 

λ§Œμ•½ 400~600 사원 X COUNT(*) INTO vempcount == 0 κ°•μ œλ‘œ μ‚¬μš©μž μ •μ˜ν•œ μ˜ˆμ™Έ λ°œμƒμ‹œν‚€κ³ 
EXCEPTION 
WHEN μ˜ˆμ™Έ THEN
         μ²˜λ¦¬~ 

-- ORA-20011: > QUERY EMP COUNT = 0 .... <
EXEC UP_EXCEPTION02( 500 );
EXEC UP_EXCEPTION02( 1200 );

CREATE OR REPLACE PROCEDURE up_exception02
(
   psal IN emp.sal%type
)
IS
   vempcount NUMBER;
   
   ve_no_emp_returned EXCEPTION;  -- μ˜ˆμ™Έ λ³€μˆ˜ μ„ μ–Έ
BEGIN
   SELECT COUNT(*) INTO vempcount
   FROM emp
   WHERE sal BETWEEN  (psal-100) AND (psal+100) ;
   
    IF  vempcount = 0 THEN
--      -- κ°•μ œ μ˜ˆμ™Έ λ°œμƒ         throw  new MyScoreException();
      RAISE ve_no_emp_returned;  -- μ˜ˆμ™Έ κ°•μ œ λ°œμƒ
    ELSE
      DBMS_OUTPUT.PUT_LINE('>처리 결과 : ' || vempcount );
     END IF;
EXCEPTION
   WHEN ve_no_emp_returned THEN
      RAISE_APPLICATION_ERROR(-20011, '> QUERY EMP COUNT = 0 .... <');
   WHEN OTHERS THEN
     RAISE_APPLICATION_ERROR(-20004, '> QUERY OTHERS EXCEPTION FOUND <');
END;

 



-- [ λ™μ  SQL  ] --
JAVA λ™μ  λ°°μ—΄

int [] m ; -- λ°°μ—΄ν¬κΈ° X
n = new int[n];


PL/SQL
1. λ™μ  SQL ? [컴파일 μ‹œ]에 SQLλ¬Έμž₯이 ν™•μ •μ΄ λ˜μ§€ μ•Šμ€ κ²½μš° -> μ‹€ν–‰λ  λ•Œ SQL λ¬Έμ„ ν™•μ •.
-> ν”„λ‘œμ‹œμ €κ°€ μ»΄νŒŒμΌλ λ•Œ 쿼리가 μ™„μ„±λ˜λŠ” 것이 μ•„λ‹ˆλΌ 싀행될 λ•Œ 쿼리가 완성됨.


-- κ²€μƒ‰ --

SELECT *
FROM board
WHERE 제λͺ© LIKE '%컴퓨터%' OR λ‚΄μš© LIKE '%컴퓨터%';;

SELECT *
FROM board
WHERE μž‘μ„±μž LIKE '%컴퓨터%';

SELECT *
FROM board
WHERE λ‚΄μš© LIKE '%컴퓨터%';

SELECT *
FROM board
WHERE 제λͺ© LIKE '%컴퓨터%';


-- λ‹€λ‚˜μ™€ 검색 쑰건 (μ—¬λŸ¬ 쑰건을 μ²΄ν¬ν•΄μ•Όν• λ•Œ κΌ­ 써야함!)


2. PL/SQL λ™μ  μΏΌλ¦¬λ₯Ό μ‚¬μš©ν•˜λŠ” 2가지 λ°©λ²•

  1) μ›μ‹œ λ™μ  μΏΌλ¦¬ ( NDS :    Native Dynamic SQL  )
  2) dbms_sql νŒ¨ν‚€μ§€ μ‚¬μš© X


3. λ™μ  μΏΌλ¦¬λ₯Ό μ‹€ν–‰ν•˜λŠ” λ°©λ²•
  1) ν˜•μ‹

EXECUTE IMMEDIATE  동적쿼리문
            [ INTO λ³€μˆ˜λͺ…,λ³€μˆ˜λͺ…... ]
            [ USING MODE(IN, OUT, IN OUT ) νŒŒλΌλ―Έν„°..... ];



4. λ™μ  μΏΌλ¦¬ μ˜ˆμ œ
  1) 예제1 - 읡λͺ…ν”„λ‘œμ‹œμ €

DECLARE
  vsql VARCHAR2(1000); -- 동적 쿼리 μ €μž₯ν•  λ³€μˆ˜
  vdeptno emp.deptno%type;
  vempno emp.empno%type;
  vename emp.ename%type;
  vjob emp.job%type;
BEGIN

    -- γ„±) 동적 쿼리 μž‘μ„±
    vsql := 'SELECT deptno, empno, ename, job ';
    vsql := vsql || ' FROM emp ';
    vsql := vsql || ' WHERE empno = 7369';
    
    -- γ„΄) 동적 쿼리 μ‹€ν–‰.
     EXECUTE IMMEDIATE  vsql
             INTO  vdeptno, vempno, vename, vjob;
     
     DBMS_OUTPUT.PUT_LINE( vdeptno || ', ' || vempno || ', ' || vename || ', ' || vjob )     ;
    

--EXCEPTION
END;


    1) 예제2 - μ €μž₯ ν”„λ‘œμ‹œμ €

CREATE OR REPLACE  PROCEDURE UP_NDSEmp
(
   pempno emp.empno%type
)
IS
  vsql VARCHAR2(1000);  
  vdeptno emp.deptno%type;
  vempno emp.empno%type;
  vename emp.ename%type;
  vjob emp.job%type;
BEGIN 
    vsql := 'SELECT deptno, empno, ename, job ';
    vsql := vsql || ' FROM emp ';
    vsql := vsql || ' WHErE empno = :pempno'; 
    
     EXECUTE IMMEDIATE  vsql
             INTO  vdeptno, vempno, vename, vjob
             USING pempno;
     
     DBMS_OUTPUT.PUT_LINE( vdeptno || ', ' || vempno || ', ' || vename || ', ' || vjob )     ;
     
--EXCEPTION
END;
EXEC UP_NDSEmp( 7369 );

 

  
     3) μ˜ˆμ œ3 - μ €μž₯ ν”„λ‘œμ‹œμ € 
  dept ν…Œμ΄λΈ”에 μƒˆλ‘œμš΄ λΆ€μ„œ μ •λ³΄λ₯Ό μ €μž₯ν•˜λŠ” ν”„λ‘œμ‹œμ € μƒμ„± + λ™μ  μΏΌλ¦¬ μ‚¬μš©.
  deptno 10/20/30/40 
  seq_dept  μ‹œν€€μŠ€   μ‹œμž‘κ°’50  10증가  X , μ‹œν€€μŠ€ μ‚¬μš© μ•ˆν•˜κ³ 
  

  CREATE OR REPLACE PROCEDURE UP_INSDept
  (
     pdname  dept.dname%type
     , ploc  dept.loc%type
  )
  IS
     vsql VARCHAR2(1000);
     vdeptno dept.deptno%type;
  BEGIN
      SELECT MAX(deptno) + 10 INTO vdeptno
      FROM dept;
  
       vsql := 'INSERT INTO dept ';
       vsql := vsql ||  ' ( deptno, dname, loc ) ';
       vsql := vsql ||  '  VALUES ( :vdeptno, :pdname, :ploc ) ';
       
       EXECUTE IMMEDIATE vsql
                 -- INTO
                 USING  vdeptno, pdname, ploc;
                 
     -- COMMIT;                 
--  EXCEPTION
  END;
 EXEC UP_INSDEPT( 'QC', 'SEOUL');



 --예)   μ‚¬μš©μž μ›ν•˜λŠ” ν˜•νƒœμ˜ κ²Œμ‹œνŒ μ—¬λŸ¬κ°œ 생성.. ( ν…Œμ΄λΈ” 생성 DDL λ¬Έ )  λ™μ  쿼리

 DECLARE
   vsql VARCHAR2(1000);
   vtablename VARCHAR2(20);
 BEGIN
    vtablename := 'tbl_nds';
    
     vsql := 'CREATE TABLE ' || vtablename;
   --vsql := 'CREATE TABLE   :vtablename '; USING μ‚¬μš©ν• κ²½μš°!
    vsql :=  vsql ||  ' ( ';
    vsql :=  vsql ||  '      id number primary key ';
    vsql :=  vsql ||  '      , name varchar2(20) ';
    vsql :=  vsql ||  ' ) ';
    
    DBMS_OUTPUT.PUT_LINE( vsql );
    
    EXECUTE IMMEDIATE vsql;
                --USING vtablename;
 END;




 -- λ§ˆμ§€λ§‰ λ™μ  μΏΌλ¦¬ μ˜ˆμ œ ( μ•”κΈ° ) --
 μ˜ˆ ) OPEN FOR λ¬Έ ?
     λ™μ  SQL의 μ‹€ν–‰ κ²°κ³Όκ°€ μ—¬λŸ¬ κ°œμ˜ ν–‰μ„ λ°˜ν™˜ν•˜λŠ” SELECTλ¬Έ +    μ»€μ„œ

CREATE OR REPLACE PROCEDURE up_nds02
(
   pdeptno emp.deptno%type
)
IS
   vsql varchar2(1000);
   vrow emp%ROWTYPE;
   vcur SYS_REFCURSOR;  -- 9i  REF CURSOR
BEGIN
   vsql := 'SELECT * ';
   vsql :=  vsql || ' FROM emp ';
   vsql :=  vsql || ' WHERE deptno = :pdeptno ';
   
   
--    EXECUTE IMMEDIATE 동적쿼리문  X
--        INTO
--        USING pdeptno;
      
      OPEN vcur FOR vsql  USING pdeptno;
       
      LOOP
         FETCH vcur INTO vrow;
         EXIT WHEN vcur%NOTFOUND;
         DBMS_OUTPUT.PUT_LINE( vrow.empno || ', ' || vrow.ename );
      END LOOP;
      
      CLOSE vcur;  
--EXCEPTION
END;

 

EXEC UP_NDS02( 30 );
EXEC UP_NDS02( 10 );

 

트리거 μ‹€μŠ΅
-- μƒν’ˆ ν…Œμ΄λΈ” μž‘μ„±

CREATE TABLE μƒν’ˆ (
   μƒν’ˆμ½”λ“œ        VARCHAR2(6) NOT NULL PRIMARY KEY
  ,μƒν’ˆλͺ…           VARCHAR2(30)  NOT NULL
  ,μ œμ‘°μ‚¬        VARCHAR2(30)  NOT NULL
  ,μ†ŒλΉ„μžκ°€κ²©  NUMBER
  ,μž¬κ³ μˆ˜λŸ‰     NUMBER DEFAULT 0
);

 

-- μž…κ³  ν…Œμ΄λΈ” μž‘μ„±

CREATE TABLE μž…κ³  (
   μž…κ³ λ²ˆν˜Έ      NUMBER PRIMARY KEY
  ,μƒν’ˆμ½”λ“œ      VARCHAR2(6) NOT NULL CONSTRAINT FK_ibgo_no
                 REFERENCES μƒν’ˆ(μƒν’ˆμ½”λ“œ)
  ,μž…κ³ μΌμž     DATE
  ,μž…κ³ μˆ˜λŸ‰      NUMBER
  ,μž…κ³ λ‹¨κ°€      NUMBER
);


-- νŒλ§€ ν…Œμ΄λΈ” μž‘μ„±

CREATE TABLE 판맀 (
   판맀번호      NUMBER  PRIMARY KEY
  ,μƒν’ˆμ½”λ“œ      VARCHAR2(6) NOT NULL CONSTRAINT FK_pan_no
                 REFERENCES μƒν’ˆ(μƒν’ˆμ½”λ“œ)
  ,판맀일자      DATE
  ,νŒλ§€μˆ˜λŸ‰      NUMBER
  ,νŒλ§€λ‹¨κ°€      NUMBER
);

 

-- μƒν’ˆ ν…Œμ΄λΈ”μ— 자료 μΆ”κ°€

INSERT INTO μƒν’ˆ(μƒν’ˆμ½”λ“œ, μƒν’ˆλͺ…, μ œμ‘°μ‚¬, μ†ŒλΉ„μžκ°€κ²©) VALUES
        ('AAAAAA', 'λ””μΉ΄', 'μ‚Όμ‹±', 100000);
INSERT INTO μƒν’ˆ(μƒν’ˆμ½”λ“œ, μƒν’ˆλͺ…, μ œμ‘°μ‚¬, μ†ŒλΉ„μžκ°€κ²©) VALUES
        ('BBBBBB', '컴퓨터', 'μ—˜λ””', 1500000);
INSERT INTO μƒν’ˆ(μƒν’ˆμ½”λ“œ, μƒν’ˆλͺ…, μ œμ‘°μ‚¬, μ†ŒλΉ„μžκ°€κ²©) VALUES
        ('CCCCCC', 'λͺ¨λ‹ˆν„°', 'μ‚Όμ‹±', 600000);
INSERT INTO μƒν’ˆ(μƒν’ˆμ½”λ“œ, μƒν’ˆλͺ…, μ œμ‘°μ‚¬, μ†ŒλΉ„μžκ°€κ²©) VALUES
        ('DDDDDD', 'ν•Έλ“œν°', 'λ‹€μš°', 500000);
INSERT INTO μƒν’ˆ(μƒν’ˆμ½”λ“œ, μƒν’ˆλͺ…, μ œμ‘°μ‚¬, μ†ŒλΉ„μžκ°€κ²©) VALUES
         ('EEEEEE', 'ν”„λ¦°ν„°', 'μ‚Όμ‹±', 200000);
COMMIT;


------------------------------------------------------------
-- 3. νŠΈλ¦¬κ±° μž‘μ„± (문제)
 -- 1) μž…κ³  ν…Œμ΄λΈ”에 INSERT νŠΈλ¦¬κ±°λ₯Ό μž‘μ„± ν•œλ‹€.
   -- [μž…κ³ ] ν…Œμ΄λΈ”에 μžλ£Œκ°€ μΆ”κ°€ λ˜λŠ” κ²½μš° [μƒν’ˆ] ν…Œμ΄λΈ”μ˜ [μž¬κ³ μˆ˜λŸ‰]이 λ³€κ²½ λ˜λ„둝 νŠΈλ¦¬κ±°λ₯Ό μž‘μ„±ν•œλ‹€.

-- μž…κ³  ν…Œμ΄λΈ”에 λ°μ΄ν„° μž…λ ₯

INSERT INTO μž…κ³  (μž…κ³ λ²ˆν˜Έ, μƒν’ˆμ½”λ“œ, μž…κ³ μΌμž, μž…κ³ μˆ˜λŸ‰, μž…κ³ λ‹¨κ°€)
              VALUES (1, 'AAAAAA', '2004-10-10', 5,   50000);
INSERT INTO μž…κ³  (μž…κ³ λ²ˆν˜Έ, μƒν’ˆμ½”λ“œ, μž…κ³ μΌμž, μž…κ³ μˆ˜λŸ‰, μž…κ³ λ‹¨κ°€)
              VALUES (2, 'BBBBBB', '2004-10-10', 15, 700000);
INSERT INTO μž…κ³  (μž…κ³ λ²ˆν˜Έ, μƒν’ˆμ½”λ“œ, μž…κ³ μΌμž, μž…κ³ μˆ˜λŸ‰, μž…κ³ λ‹¨κ°€)
              VALUES (3, 'AAAAAA', '2004-10-11', 15, 52000);
INSERT INTO μž…κ³  (μž…κ³ λ²ˆν˜Έ, μƒν’ˆμ½”λ“œ, μž…κ³ μΌμž, μž…κ³ μˆ˜λŸ‰, μž…κ³ λ‹¨κ°€)
              VALUES (4, 'CCCCCC', '2004-10-14', 15,  250000);
INSERT INTO μž…κ³  (μž…κ³ λ²ˆν˜Έ, μƒν’ˆμ½”λ“œ, μž…κ³ μΌμž, μž…κ³ μˆ˜λŸ‰, μž…κ³ λ‹¨κ°€)
              VALUES (5, 'BBBBBB', '2004-10-16', 25, 700000);
COMMIT;
  CREATE OR REPLACE TRIGGER ins
  AFTER
  INSERT ON μž…κ³ 
  FOR EACH ROW
  BEGIN    
    UPDATE μƒν’ˆ
    SET μž¬κ³ μˆ˜λŸ‰ = μž¬κ³ μˆ˜λŸ‰ + :NEW.μž…κ³ μˆ˜λŸ‰
    WHERE μƒν’ˆμ½”λ“œ = :NEW.μƒν’ˆμ½”λ“œ;
  END;



 -- 2) μž…κ³  ν…Œμ΄λΈ”에 UPDATE νŠΈλ¦¬κ±°λ₯Ό μž‘μ„± ν•œλ‹€. (문제)
--  [μž…κ³ ] ν…Œμ΄λΈ”μ˜ μžλ£Œκ°€ λ³€κ²½ λ˜λŠ” κ²½μš° [μƒν’ˆ] ν…Œμ΄λΈ”μ˜ [μž¬κ³ μˆ˜λŸ‰]이 λ³€κ²½ λ˜λ„둝 νŠΈλ¦¬κ±°λ₯Ό μž‘μ„±ν•œλ‹€.

CREATE OR REPLACE TRIGGER ups
AFTER
UPDATE ON μž…κ³ 
FOR EACH ROW
BEGIN
    UPDATE μƒν’ˆ
    SET μž¬κ³ μˆ˜λŸ‰ = μž¬κ³ μˆ˜λŸ‰ - :OLD.μž…κ³ μˆ˜λŸ‰ + :NEW.μž…κ³ μˆ˜λŸ‰
    WHERE μƒν’ˆμ½”λ“œ = :NEW.μƒν’ˆμ½”λ“œ;
END;


-- UPDATE ν…ŒμŠ€νŠΈ

UPDATE μž…κ³  SET μž…κ³ μˆ˜λŸ‰ = 30 WHERE μž…κ³ λ²ˆν˜Έ = 5;
COMMIT;



 -- 3) μž…κ³  ν…Œμ΄λΈ”에 DELETE νŠΈλ¦¬κ±°λ₯Ό μž‘μ„± ν•œλ‹€.
 -- [μž…κ³ ] ν…Œμ΄λΈ”μ˜ μžλ£Œκ°€ μ‚­μ œλ˜λŠ” κ²½μš° [μƒν’ˆ] ν…Œμ΄λΈ”μ˜ [μž¬κ³ μˆ˜λŸ‰]이 λ³€κ²½ λ˜λ„둝 νŠΈλ¦¬κ±°λ₯Ό μž‘μ„±ν•œλ‹€.

CREATE OR REPLACE TRIGGER des
AFTER
DELETE ON μž…κ³ 
FOR EACH ROW
BEGIN
    UPDATE μƒν’ˆ
    SET μž¬κ³ μˆ˜λŸ‰ = μž¬κ³ μˆ˜λŸ‰ - :OLD.μž…κ³ μˆ˜λŸ‰
    WHERE μƒν’ˆμ½”λ“œ = :OLD.μƒν’ˆμ½”λ“œ;
END;


-- DELETE ν…ŒμŠ€νŠΈ

DELETE FROM μž…κ³  WHERE μž…κ³ λ²ˆν˜Έ = 5;
COMMIT;



-- μž…κ³  ν…Œμ΄λΈ”μ˜ 재고 μˆ˜λŸ‰ μˆ˜μ • 및 μ‚­μ œλŠ” μƒν’ˆ ν…Œμ΄λΈ”μ˜ 재고 μˆ˜λŸ‰μ΄ μ κ±°λ‚˜ μ—†μœΌλ©΄ ν•  수 μ—†μœΌλ―€λ‘œ

-- UPDATE 및 DELETE 트리거λ₯Ό BEFORE 트리거둜 μˆ˜μ •ν•˜μ—¬ μƒν’ˆ ν…Œμ΄λΈ”μ˜ 재고 μˆ˜λŸ‰μ— 따라 μˆ˜μ • λ˜λŠ” μ‚­μ œλ₯Ό ν• μˆ˜ 없도둝 μˆ˜μ •ν•œλ‹€.

 -- 4) νŒλ§€ ν…Œμ΄λΈ”에 INSERT νŠΈλ¦¬κ±°λ₯Ό μž‘μ„±ν•œλ‹€.(BEFORE νŠΈλ¦¬κ±°λ‘œ μž‘μ„±)
 -- [판맀] ν…Œμ΄λΈ”에 μžλ£Œκ°€ μΆ”κ°€ λ˜λŠ” κ²½μš° [μƒν’ˆ] ν…Œμ΄λΈ”μ˜ [μž¬κ³ μˆ˜λŸ‰]이 λ³€κ²½ λ˜λ„둝 νŠΈλ¦¬κ±°λ₯Ό μž‘μ„±ν•œλ‹€.

CREATE OR REPLACE TRIGGER in_판맀
BEFORE
INSERT ON 판맀
FOR EACH ROW
DECLARE
    vμž¬κ³ μˆ˜λŸ‰ NUMBER;
 BEGIN
    SELECT μž¬κ³ μˆ˜λŸ‰ INTO vμž¬κ³ μˆ˜λŸ‰
    FROM μƒν’ˆ 
    WHERE μƒν’ˆμ½”λ“œ = :NEW.μƒν’ˆμ½”λ“œ;
    
    IF :NEW.νŒλ§€μˆ˜λŸ‰ > vμž¬κ³ μˆ˜λŸ‰
        THEN RAISE_APPLICATION_ERROR(-20000, 'μž¬κ³ λΆ€μ‘±! 판맀 λΆˆκ°€');
    ELSE        
       UPDATE μƒν’ˆ
       SET μž¬κ³ μˆ˜λŸ‰ = μž¬κ³ μˆ˜λŸ‰ - :NEW.νŒλ§€μˆ˜λŸ‰
       WHERE μƒν’ˆμ½”λ“œ = :NEW.μƒν’ˆμ½”λ“œ;
    END IF;
END;


-- νŒλ§€ ν…Œμ΄λΈ”에 λ°μ΄ν„° μž…λ ₯

INSERT INTO 판맀 (판맀번호, μƒν’ˆμ½”λ“œ, 판맀일자, νŒλ§€μˆ˜λŸ‰, νŒλ§€λ‹¨κ°€) VALUES
               (1, 'AAAAAA', '2004-11-10', 5, 1000000);
COMMIT;
INSERT INTO 판맀 (판맀번호, μƒν’ˆμ½”λ“œ, 판맀일자, νŒλ§€μˆ˜λŸ‰, νŒλ§€λ‹¨κ°€) VALUES
               (1, 'AAAAAA', '2004-11-10', 50, 1000000);
COMMIT;



 -- 5) νŒλ§€ ν…Œμ΄λΈ”에 UPDATE νŠΈλ¦¬κ±°λ₯Ό μž‘μ„±ν•œλ‹€.(BEFORE νŠΈλ¦¬κ±°λ‘œ μž‘μ„±)
 -- [판맀] ν…Œμ΄λΈ”μ˜ μžλ£Œκ°€ λ³€κ²½ λ˜λŠ” κ²½μš° [μƒν’ˆ] ν…Œμ΄λΈ”μ˜ [μž¬κ³ μˆ˜λŸ‰]이 λ³€κ²½ λ˜λ„둝 νŠΈλ¦¬κ±°λ₯Ό μž‘μ„±ν•œλ‹€.

CREATE OR REPLACE TRIGGER up_판맀
BEFORE
UPDATE ON 판맀
FOR EACH ROW
DECLARE
    vμž¬κ³ μˆ˜λŸ‰ NUMBER;
BEGIN
    SELECT μž¬κ³ μˆ˜λŸ‰ INTO vμž¬κ³ μˆ˜λŸ‰
    FROM μƒν’ˆ 
    WHERE μƒν’ˆμ½”λ“œ = :NEW.μƒν’ˆμ½”λ“œ;
    
    IF :NEW.νŒλ§€μˆ˜λŸ‰ > vμž¬κ³ μˆ˜λŸ‰ + :OLD.νŒλ§€μˆ˜λŸ‰
        THEN RAISE_APPLICATION_ERROR(-20001, 'νŒλ§€μˆ˜μ •λΆˆκ°€');
    ELSE        
        UPDATE μƒν’ˆ
        SET μž¬κ³ μˆ˜λŸ‰ = μž¬κ³ μˆ˜λŸ‰ + :OLD.νŒλ§€μˆ˜λŸ‰ - :NEW.νŒλ§€μˆ˜λŸ‰
        WHERE μƒν’ˆμ½”λ“œ = :NEW.μƒν’ˆμ½”λ“œ;
    END IF;
END;


-- UPDATE ν…ŒμŠ€νŠΈ

UPDATE 판맀 SET νŒλ§€μˆ˜λŸ‰ = 200 WHERE 판맀번호 = 1;
UPDATE 판맀 SET νŒλ§€μˆ˜λŸ‰ = 10 WHERE 판맀번호 = 1;
COMMIT;


 -- 6) νŒλ§€ ν…Œμ΄λΈ”에 DELETE νŠΈλ¦¬κ±°λ₯Ό μž‘μ„± ν•œλ‹€.
 -- [판맀] ν…Œμ΄λΈ”μ— μžλ£Œκ°€ μ‚­μ œλ˜λŠ” 경우 [μƒν’ˆ] ν…Œμ΄λΈ”μ˜ [μž¬κ³ μˆ˜λŸ‰]이 λ³€κ²½ λ˜λ„λ‘ 트리거λ₯Ό μž‘μ„±ν•œλ‹€.

CREATE OR REPLACE TRIGGER de_판맀
AFTER
DELETE ON 판맀
FOR EACH ROW
BEGIN        
        UPDATE μƒν’ˆ
        SET μž¬κ³ μˆ˜λŸ‰ = μž¬κ³ μˆ˜λŸ‰ + :OLD.νŒλ§€μˆ˜λŸ‰
        WHERE μƒν’ˆμ½”λ“œ = :OLD.μƒν’ˆμ½”λ“œ;
END;


-- DELETE ν…ŒμŠ€νŠΈ

DELETE 판맀 WHERE 판맀번호 = 1;
COMMIT;

 

μ΄ˆκΈ°ν™”


------------------------------------------------------------
-- μƒν’ˆ ν…Œμ΄λΈ” μž‘μ„±
DROP TABLE 판맀;
DROP TABLE μž…κ³ ;
DROP TABLE μƒν’ˆ;


CREATE TABLE μƒν’ˆ (
   μƒν’ˆμ½”λ“œ        VARCHAR2(6) NOT NULL PRIMARY KEY
  ,μƒν’ˆλͺ…           VARCHAR2(30)  NOT NULL
  ,μ œμ‘°μ‚¬        VARCHAR2(30)  NOT NULL
  ,μ†ŒλΉ„μžκ°€κ²©  NUMBER
  ,μž¬κ³ μˆ˜λŸ‰     NUMBER DEFAULT 0
);

-- μž…κ³  ν…Œμ΄λΈ” μž‘μ„±
CREATE TABLE μž…κ³  (
   μž…κ³ λ²ˆν˜Έ      NUMBER PRIMARY KEY
  ,μƒν’ˆμ½”λ“œ      VARCHAR2(6) NOT NULL CONSTRAINT FK_ibgo_no
                 REFERENCES μƒν’ˆ(μƒν’ˆμ½”λ“œ)
  ,μž…κ³ μΌμž     DATE
  ,μž…κ³ μˆ˜λŸ‰      NUMBER
  ,μž…κ³ λ‹¨κ°€      NUMBER
);

-- 판맀 ν…Œμ΄λΈ” μž‘μ„±
CREATE TABLE 판맀 (
   판맀번호      NUMBER  PRIMARY KEY
  ,μƒν’ˆμ½”λ“œ      VARCHAR2(6) NOT NULL CONSTRAINT FK_pan_no
                 REFERENCES μƒν’ˆ(μƒν’ˆμ½”λ“œ)
  ,판맀일자      DATE
  ,νŒλ§€μˆ˜λŸ‰      NUMBER
  ,νŒλ§€λ‹¨κ°€      NUMBER
);

-- μƒν’ˆ ν…Œμ΄λΈ”μ— 자료 μΆ”κ°€
INSERT INTO μƒν’ˆ(μƒν’ˆμ½”λ“œ, μƒν’ˆλͺ…, μ œμ‘°μ‚¬, μ†ŒλΉ„μžκ°€κ²©) VALUES
        ('AAAAAA', 'λ””μΉ΄', 'μ‚Όμ‹±', 100000);
INSERT INTO μƒν’ˆ(μƒν’ˆμ½”λ“œ, μƒν’ˆλͺ…, μ œμ‘°μ‚¬, μ†ŒλΉ„μžκ°€κ²©) VALUES
        ('BBBBBB', '컴퓨터', 'μ—˜λ””', 1500000);
INSERT INTO μƒν’ˆ(μƒν’ˆμ½”λ“œ, μƒν’ˆλͺ…, μ œμ‘°μ‚¬, μ†ŒλΉ„μžκ°€κ²©) VALUES
        ('CCCCCC', 'λͺ¨λ‹ˆν„°', 'μ‚Όμ‹±', 600000);
INSERT INTO μƒν’ˆ(μƒν’ˆμ½”λ“œ, μƒν’ˆλͺ…, μ œμ‘°μ‚¬, μ†ŒλΉ„μžκ°€κ²©) VALUES
        ('DDDDDD', 'ν•Έλ“œν°', 'λ‹€μš°', 500000);
INSERT INTO μƒν’ˆ(μƒν’ˆμ½”λ“œ, μƒν’ˆλͺ…, μ œμ‘°μ‚¬, μ†ŒλΉ„μžκ°€κ²©) VALUES
         ('EEEEEE', 'ν”„λ¦°ν„°', 'μ‚Όμ‹±', 200000);
COMMIT;
SELECT * FROM μƒν’ˆ;
  • 넀이버 λΈ”λŸ¬κ·Έ κ³΅μœ ν•˜κΈ°
  • 넀이버 λ°΄λ“œμ— κ³΅μœ ν•˜κΈ°
  • 페이슀뢁 κ³΅μœ ν•˜κΈ°
  • μΉ΄μΉ΄μ˜€μŠ€ν† λ¦¬ κ³΅μœ ν•˜κΈ°