๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ’ป/ORACLE

(28)[ORACLE] 11์ผ์ฐจ : PL/SQL

by ๋”ฐ๊ถˆ 2024. 3. 25.

 

 

PL/SQL์ด๋ž€?
ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์˜ ํŠน์„ฑ์„ ๊ฐ€์ง€๋Š” SQL์˜ ํ™•์žฅ์ด๋ฉฐ, ๋ฐ์ดํ„ฐ ์กฐ์ž‘๊ณผ ์งˆ์˜ ๋ฌธ์žฅ์€
PL/SQL์˜ ์ ˆ์ฐจ์  ์ฝ”๋“œ ์•ˆ์— ํฌํ•จ๋œ๋‹ค. 
์ฃผ๋กœ ์ž๋ฃŒ ๋‚ด๋ถ€์—์„œ SQL๋ช…๋ น๋ฌธ๋งŒ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ์—๋Š” ๋ณต์žกํ•œ ์ž๋ฃŒ์˜ ์ €์žฅ์ด๋‚˜
ํ”„๋กœ์‹œ์ €์™€ ํŠธ๋ฆฌ๊ฑฐ ๋“ฑ์„ ์ž‘์„ฑํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋œ๋‹ค.

PL/SQL์€ ํ”„๋กœ๊ทธ๋žจ์„ ๋…ผ๋ฆฌ์ ์ธ ๋ธ”๋ก์œผ๋กœ ๋‚˜๋ˆ„๋Š” ๊ตฌ์กฐํ™” ๋œ ๋ธ”๋ก์–ธ์–ด์ด๋‹ค
PL/SQL ๋ธ”๋ก์€ ์„ ์–ธ๋ถ€(์„ ํƒ์ ),์‹คํ–‰๋ถ€(ํ•„์ˆ˜์ ),์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ถ€(์„ ํƒ์ )๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๊ณ , 
BEGIN๊ณผ END ํ‚ค์›Œ๋“œ๋Š” ๋ฐ˜๋“œ์‹œ ๊ธฐ์ˆ ํ•ด ์ฃผ์–ด์•ผ ํ•œ๋‹ค.

 

PL/SQL ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋‹จ์œ„
PL/SQL ์ต๋ช… ๋ธ”๋ก
ํ•จ์ˆ˜
ํ”„๋กœ์‹œ์ €
ํŒจ๊ธฐ์ง€ : ํŒจํ‚ค์ง€ ๋ช…์„ธ, ํŒจํ‚ค์ง€ ๋ฐ”๋””
ํŠธ๋ฆฌ๊ฑฐ

 

 

๊ธฐ๋ณธ๋ฌธ๋ฒ•

--PL/SQL SELECT
SELECT ์ปฌ๋Ÿผ, ์ปฌ๋Ÿผ INTO ๋ณ€์ˆ˜, ๋ณ€์ˆ˜, FROM  ํ…Œ์ด๋ธ” WHERE ์กฐ๊ฑด;

%TYPE ์†์„ฑ : ํ…Œ์ด๋ธ”์˜ ์ปฌ๋Ÿผ์„ ์ฐธ์กฐํ•˜๋Š” ์†์„ฑ
DECLARE
    --๋ณ€์ˆ˜ ์„ ์–ธ 
    vname    emp.name%TYPE;
    vpay     NUMBER;
    BEGIN
            SELECT name,sal+bonus INTO vname,vpay
            FROM emp
            WHERE empNO = '1001';
            
            DBMS_OUTPUT.PUT_LINE('์ด๋ฆ„ :' || vname);
            DBMS_OUTPUT.PUT_LINE('๊ธ‰์—ฌ :' || vpay);
    
    END;

 

DECLARE : ์‹คํ–‰๋ถ€์—์„œ ์ฐธ์กฐํ•  ๋ชจ๋“  ๋ณ€์ˆ˜,์ƒ์ˆ˜,์ปค์„œ,exception์„ ์„ ์–ธํ•œ๋‹ค.

BEGIN ~ END : ์ฒ˜๋ฆฌํ•  SQL์ด๋‚˜ PL/SQL ๋ธ”๋ก์„ ๊ธฐ์ˆ ํ•œ๋‹ค.

EXCEPTION : ์‹คํ–‰๋ถ€์—์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„๋•Œ ์ˆ˜ํ–‰๋  ๋ฌธ์žฅ์„ ๊ธฐ์ˆ ํ•œ๋‹ค. 

--%ROWTYPE : ํ…Œ์ด๋ธ” ๋˜๋Š” ๋ทฐ์˜ ํ–‰์„ ์ฐธ์กฐํ•˜๋Š” ๋ ˆ์ฝ”๋“œ ์„ ์–ธ 

DECLARE
        vrec emp%ROWTYPE;    
BEGIN
        SELECT name,sal INTO vrec.name,vrec.sal
       
        FROM emp
        WHERE  empNO = '1001';
        
        DBMS_OUTPUT.PUT_LINE('์ด๋ฆ„ :' || vrec.name);
        DBMS_OUTPUT.PUT_LINE('๊ธ‰์—ฌ :' || vrec.sal);
END;

 

  • %TYPE : ์ƒ์ˆ˜,๋ณ€์ˆ˜,ํ•„๋“œ ๋˜๋Š” ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์ด์ „์— ์„ ์–ธ๋œ ๋ณ€์ˆ˜,ํ•„๋“œ,๋ ˆ์ฝ”๋“œ,์ค‘์ฒฉ ํ…Œ์ด๋ธ” ๋˜๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ปฌ๋Ÿผ๊ณผ ๋™์ผํ•œ ๋ฐ์ดํ„ฐ ํ˜•์‹์œผ๋กœ ์„ ์–ธํ•œ๋‹ค. 
  • %ROWTYPE 
    • ํ…Œ์ด๋ธ” ๋˜๋Š” ๋ทฐ์˜ ํ–‰์„ ์ฐธ์กฐํ•˜๋Š” ๋ ˆ์ฝ”๋“œ๋ฅผ ์„ ์–ธํ•œ๋‹ค.
    • ๋ ˆ์ฝ”๋“œ์—๋Š” ์ฐธ์กฐ๋œ ํ…Œ์ด๋ธ” ๋˜๋Š” ๋ทฐ์˜ ๊ฐ ์ปฌ๋Ÿผ์— ๋Œ€ํ•ด ๋ฐ์ดํ„ฐ ์œ ํ˜• ๋ฐ ์ด๋ฆ„์ด ๊ฐ™์€ ํ•„๋“œ๋ฅผ ๊ฐ–๋Š”๋‹ค.
    • ๋ ˆ์ฝ”๋“œ์—์„œ ํ•„๋“œ๋ฅผ ์ฐธ์กฐํ•˜๋ ค๋ฉด record_name.field_name์„ ์‚ฌ์šฉํ•œ๋‹ค. 
DECLARE
        --๋ ˆ์ฝ”๋“œ ์œ ํ˜• ์„ ์–ธ
        TYPE MYTYPE IS RECORD
        
        (
            name emp.name%TYPE,
            pay emp.sal%TYPE
        );
        
    vrec MYTYPE;
BEGIN
        SELECT name,sal INTO vrec.name,vrec.pay
        FROM emp
        WHERE  empNO = '1001';
        
        DBMS_OUTPUT.PUT_LINE('์ด๋ฆ„ :' || vrec.name);
        DBMS_OUTPUT.PUT_LINE('๊ธ‰์—ฌ :' || vrec.pay);
    END;

 

 

์ œ์–ด๊ตฌ์กฐ

IF๋ฌธ

 

DECLARE
    a NUMBER := 10;
BEGIN
    IF MOD(a,6) = 0 THEN
       DBMS_OUTPUT.PUT_LINE(a||':2๋˜๋Š” 3์˜๋ฐฐ์ˆ˜');
    ELSIF MOD(a,2) = 0 THEN
       DBMS_OUTPUT.PUT_LINE(a||':2์˜๋ฐฐ์ˆ˜');
    ELSIF MOD(a,3) = 0 THEN
        DBMS_OUTPUT.PUT_LINE(a||':3์˜๋ฐฐ์ˆ˜');
    ELSE
         DBMS_OUTPUT.PUT_LINE(a||':2๋˜๋Š” 3์˜๋ฐฐ์ˆ˜๊ฐ€ ์•„๋‹ˆ๋‹ค');
    END IF;
    END;
    /

 

 

CASE๋ฌธ

DECLARE
    vname VARCHAR2(30);
    vpay  NUMBER;
    vtax  NUMBER;
BEGIN
    SELECT name,sal+bonus INTO vname,vpay
    FROM emp
    WHERE empNO = '1001';
    
    CASE 
    
    WHEN  vpay >= 3000000 THEN
        vtax := TRUNC(vpay * 0.03);
    WHEN   vpay >= 2000000 THEN
            vtax := TRUNC(vpay * 0.02);
    ELSE
        vtax := 0;
    END CASE;
    
    DBMS_OUTPUT.PUT_LINE('์ด๋ฆ„:'||vname);
    DBMS_OUTPUT.PUT_LINE('๊ธ‰์—ฌ:'||vpay);
    DBMS_OUTPUT.PUT_LINE('์„ธ๊ธˆ:'||vtax);
END;
/

 

 

LOOP๋ฌธ

  • ๋ฌดํ•œ ๋ฐ˜๋ณต๋˜๋Š” LOOP๋ฌธ์žฅ์ด๋‹ค.
  • EXIT๋ฌธ์„ ๋งŒ๋‚˜๋ฉด ๋น ์ ธ๋‚˜๊ฐ„๋‹ค.
  • EXIT WHEN <condition>;์„ ์‚ฌ์šฉํ•˜์—ฌ LOOP๋ฌธ์„ ๋น ์ ธ ๋‚˜๊ฐ€๋Š” ์กฐ๊ฑด์„ ์ œ์–ด ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋‹ค๋ฅธ LOOP๋ฅผ ํฌํ•จํ•˜์—ฌ ์ค‘์ฒฉ ๊ฐ€๋Šฅํ•˜๋‹ค. 

EXIT๋ฌธ

  • LOOP๋ฌธ์—์„œ EXIT๋ฌธ์„ ๋งŒ๋‚˜๋ฉด loop๊ฐ€ ์™„๋ฃŒ๋˜๊ณ  ์ œ์–ด๊ฐ€ END LOOP ๋ฐ”๋กœ ๋‹ค์Œ ๋ฌธ์žฅ์„ ์‹คํ–‰ํ•œ๋‹ค.
  • EXIT WHEN <condition>๋ฌธ์€ WHEN ์ ˆ์˜ ์กฐ๊ฑด์ด TRUE์ธ ๊ฒฝ์šฐ loop๊ฐ€ ์™„๋ฃŒ๋˜๊ณ  ์ œ์–ด๊ฐ€ END LOOP ๋ฐ”๋กœ ๋‹ค์Œ ๋ฌธ์žฅ์„ ์‹คํ–‰ํ•œ๋‹ค. 
--1~100๊นŒ์ง€ ํ•ฉ ์ถœ๋ ฅ 
DECLARE
        n NUMBER :=0;
        s NUMBER :=0;
BEGIN
        LOOP
            n:= n+1;
            s:= s+n;
            EXIT WHEN n = 100;
        END LOOP;
        DBMS_OUTPUT.PUT_LINE('๊ฒฐ๊ณผ:'||s);
END;
/

 

 

CONTINUE๋ฌธ

  • LOOP๋ฌธ์—์„œ CONTINUE๋ฌธ์„ ๋งŒ๋‚˜๋ฉด loop์˜ ํ˜„์žฌ ๋ฐ˜๋ณต์ด ์™„๋ฃŒ๋˜๊ณ  ์ œ์–ด๊ฐ€ loop์˜ ๋‹ค์Œ ๋ฐ˜๋ณต์œผ๋กœ ์ „๋‹ฌ ๋œ๋‹ค.
  • CONTUINUE WHEN<condition>๋ฌธ์€ WHEN ์ ˆ์˜ ์กฐ๊ฑด์ด TRUE์ธ loop์˜ ํ˜„์žฌ ๋ฐ˜๋ณต์ด ์™„๋ฃŒ๋˜๊ณ  ์ œ์–ด๊ฐ€ loop์˜ ๋‹ค์Œ ๋ฐ˜๋ณต์œผ๋กœ ์ „๋‹ฌ ๋œ๋‹ค. 

WHILE-LOOP๋ฌธ

  • ์กฐ๊ฑด์ด TRUE์ธ ๊ฒฝ์šฐ ๋ฐ˜๋ณต๋˜๋Š” LOOP ๋ฌธ์žฅ์ด๋‹ค.
  • ๋‹ค๋ฅธ LOOP๋ฅผ ํฌํ•จํ•˜์—ฌ ์ค‘์ฒฉ ๊ฐ€๋Šฅํ•˜๋‹ค. 
-- 1~100๊นŒ์ง€ ์ˆ˜์ค‘ 2๋˜๋Š” 3์˜ ๋ฐฐ์ˆ˜๋ฅผ ์ œ์™ธํ•˜๊ณ  ์ถœ๋ ฅ 
DECLARE
    n NUMBER := 0;
BEGIN
    WHILE n < 100 LOOP
        n := n + 1;
        EXIT WHEN n > 100; -- ์ถ”๊ฐ€: ๋ฃจํ”„ ์ข…๋ฃŒ ์กฐ๊ฑด
        CONTINUE WHEN MOD(n, 2) = 0 OR MOD(n, 3) = 0;
        DBMS_OUTPUT.PUT(n || ' ');
    END LOOP;
    DBMS_OUTPUT.NEW_LINE();
END;

 

 

 

FOR-LOOP๋ฌธ

  • ๋‹จ์ˆœ FOR-LOOP๋ฌธ์€ ์ง€์ •๋œ ์ •์ˆ˜ ๋ฒ”์œ„์—์„œ ๋ฐ˜๋ณต๋œ๋‹ค.
  • FOR๋ฃจํ”„๊ฐ€ ์ฒ˜์Œ ์ž…๋ ฅ ๋ ๋•Œ ๋ฒ”์œ„๊ฐ€ ํ‰๊ฐ€๋˜๊ณ  ๋‹ค์‹œ ํ‰๊ฐ€๋˜์ง€ ์•Š์œผ๋ฉฐ, lower_bound๊ฐ€ upper_bound์™€ ๊ฐ™์œผ๋ฉด ๋ฃจํ”„ ๋ณธ๋ฌธ์ด ํ•œ ๋ฒˆ ์‹คํ–‰๋œ๋‹ค
  • FOR๋ฌธ์˜ ๋ฐ˜๋ณต์— ์‚ฌ์šฉ๋œ ๋ณ€์ˆ˜๋Š” ์ดˆ๊ธฐ๊ฐ’์—์„œ ์‹œ์ž‘ํ•ด ์ตœ์ข…๊ฐ’๊นŒ์ง€ ๋ฃจํ”„๋ฅผ ๋Œ๋ฉฐ 1์”ฉ ์ฆ๊ฐ€๋˜๋Š”๋ฐ, ๋ณ€์ˆ˜๋Š” ์ฐธ์กฐ๋Š” ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ๋ณ€๊ฒฝํ•  ์ˆ˜๋Š” ์—†๊ณ  ์ฐธ์กฐ๋„ ์˜ค์ง ๋ฃจํ”„ ์•ˆ์—์„œ๋งŒ ๊ฐ€๋Šฅํ•˜๋‹ค.
  • FOR๋ฌธ์˜ ๋ฐ˜๋ณต์— ์‚ฌ์šฉ๋œ ๋ณ€์ˆ˜๋Š” ์„ ์–ธ๋ถ€์—์„œ ์„ ์–ธํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • ์ผ๋ฐ˜์ ์œผ๋กœ ๋ฐ˜๋ณต์€ ์ ์€ ๊ฐ’์—์„œ ํฐ ๊ฐ’์œผ๋กœ ์ง„ํ–‰ํ•˜์ง€๋งŒ REVERSE๋Š” ํฐ ๊ฐ’์—์„œ ์ ์€ ๊ฐ’์œผ๋กœ ๋ฐ˜๋ณต๋œ๋‹ค. 
--1๋ถ€ํ„ฐ 100๊นŒ์ง€ ํ•ฉ
DECLARE
    s NUMBER := 0;
BEGIN
--FOR์—์„œ ๋ฐ˜๋ณต์„ ๋‚˜ํƒ€๋‚ด๋Š” ๋ณ€์ˆ˜๋Š” ์„ ์–ธํ•˜์ง€ ์•Š๋Š”๋‹ค 
    FOR n IN 1..100 LOOP
        s := s + n;
    END LOOP;
        DBMS_OUTPUT.PUT_LINE('๊ฒฐ๊ณผ:' || s);
END;
/

--REVERSE์—ญ์œผ๋กœ ์ถœ๋ ฅ 
--10 9 8 7 6 5 4 3 2 1 
DECLARE
BEGIN
    FOR n IN REVERSE 1..10 LOOP
    DBMS_OUTPUT.PUT(n||' ');
    END LOOP;
    DBMS_OUTPUT.NEW_LINE();
END;
/

 

 

SQL Cursor FOR LOOP

  • FOR LOOP์— ์ฟผ๋ฆฌ ํ…์ŠคํŠธ๋ฅผ ํฌํ•จ์‹œ์ผœ ๊ฐ ํ–‰์„ loop๋กœ ์ฒ˜๋ฆฌํ•œ๋‹ค.
  • ์ฟผ๋ฆฌ ๊ฐ ํ–‰์˜ ์‹คํ–‰ ๊ฒฐ๊ณผ๋Š” ๋ ˆ์ฝ”๋“œ ๋ณ€์ˆ˜์— ์ €์žฅ๋˜์–ด loop๋‚ด์—์„œ ๋ ˆ์ฝ”๋“œ ๋ณ€์ˆ˜์˜ ๊ฐ ํ•„๋“œ๋ฅผ ์ฐธ์กฐํ•˜์—ฌ ์—ฐ์‚ฐํ•˜๊ฑฐ๋‚˜ ๊ฒฐ๊ณผ๋ฅผ ํ‘œ์‹œ ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • FOR๋ฌธ์˜ record ๋ณ€์ˆ˜๋Š” ์„ ์–ธ๋ถ€์—์„œ ์„ ์–ธํ•˜์ง€ ์•Š๋Š”๋‹ค.
DECLARE
BEGIN
    FOR rec IN (SELECT name,sal+bonus pay FROM emp) LOOP
    DBMS_OUTPUT.PUT_LINE(rec.name||':'||rec.pay);
    END LOOP;
   
END;
/