¡Ü PL/SQLÀ̶õ?
¢ºPL/SQLÀº ÀýÂ÷Àû ÇÁ·Î±×·¡¹Ö ¾ð¾î·Î SQLÀ» È®ÀåÇÑ °Í.
¢ºµ¥ÀÌÅÍ Á¶ÀÛ°ú ÁúÀǹ®Àº PL/SQL ºí·Ï¾È¿¡ Æ÷ÇÔµÈ °Í.
¢ºPL/SQLÀº º°°³ÀÇ Oracle Á¦Ç°ÀÌ ¾Æ´Ï¶ó Oracle7 ¼¹ö¿Í ´Ù¸¥ Oracle Åø¿¡ ÀÌ¿ëµÇ°í ÀÖ´Â ÇÁ·Î±×·¡¹Ö ¾ð¾îÀÌ´Ù.
¡¡¡¡
¡Ü PL/SQLÀÇ ÀåÁ¡
SQL·Î´Â ¾òÀ» ¼ö ¾ø´Â PL/SQLÀÇ ÀýÂ÷Àû ÇÁ·Î±×·¡¹Ö ±â´ÉÀÌ ÀÖÀ½.
¢Â ¸ðµâÈµÈ ÇÁ·Î±×·¥ °³¹ß
º ºí·Ï ³»¿¡¼ ³í¸®ÀûÀ¸·Î °ü·ÃµÈ ¹®ÀåµéÀÇ ±×·ìÈ
º °·ÂÇÑ ÇÁ·Î±×·¥À» ÀÛ¼ºÇϱâ À§ÇØ ¼ºê ºí·ÏµéÀ» Å« ºí·Ï¿¡ Æ÷ÇÔ
º º¹ÀâÇÑ ¹®Á¦¿¡ ´ëÇÑ ÇÁ·Î±×·¡¹ÖÀÌ ÀûÀýÈ÷ ³ª´µ¾îÁø ¸ðµâµéÀÇ ÁýÇÕÀ¸·Î ±¸¼º
¢Â CURSOR, EXCEPTION
º º¯¼ö, »ó¼ö µîÀ» ¼±¾ðÇϰí SQL°ú ÀýÂ÷ÀûÀÎ ÇÁ·Î±×·¥¿¡¼ »ç¿ë
º µ¥ÀÌÅͺ£À̽ºÀÇ Å×À̺í°ú Record¸¦ ±â¹ÝÀ¸·Î ÇÏ´Â dynamicÇÑ º¯¼ö ¼±¾ðÀÌ °¡´É
¢Â ÀýÂ÷Àû ¾ð¾î ±¸Á¶·Î µÈ ÇÁ·Î±×·¥ ÀÛ¼º
º Á¶°Ç¿¡ µû¶ó ÀÏ·ÃÀÇ ¹®ÀåÀ» ½ÇÇà (IF)
º ·çÇÁ¿¡¼ ¹Ýº¹ÀûÀ¸·Î ÀÏ·ÃÀÇ ¹®ÀåÀ» ½ÇÇà (LOOP)
º Explicit Cursor¸¦ ÀÌ¿ëÇÑ Multi-row ÁúÀÇ Ã³¸®
¢Â ERROR ó¸®
º Exception ó¸® ·çƾÀ» ÀÌ¿ëÇÏ¿© ¿À¶óŬ7 ¼¹ö ¿¡·¯¸¦ ó¸®ÇÔ
º »ç¿ëÀÚ Á¤ÀÇ ¿¡·¯¸¦ ¼±¾ðÇϰí Exception ó¸® ·çƾÀ¸·Î
󸮰¡´ÉÇÔ.
¡Ü PL/SQL ºí·Ï ±¸Á¶
¡¡¢ºDECLARE¡çOptional
-º¯¼ö, »ó¼ö, Cursor
-user - defined exception
¡¡ ¢ºBEGIN¡çMandatery
-SQL ¹®Àå
-PL/SQL Á¦¾î¹®
¡¡ ¢ºEXCEPTION ¡çOptional
-Error ¹ß»ý½Ã ¼öÇàÇÒ ³»¿ë
¡¡ ¢¹END; ¡çMandatery
¡Ü SQL*Plus¸¦ ÀÌ¿ëÇÑ PL/SQL ºí·Ï ÀÛ¼º
¢ºDECLAREÀý
-¼±ÅûçÇ×(option) ÀýÀÌ´Ù.
-PL/SQL¿¡¼ ÂüÁ¶µÇ´Â ¸ðµç º¯¼ö¿Í »ó¼ö ¼±¾ð.
¢Ñ º¯¼ö¿Í »ó¼ö¼±¾ð:Syntax
Identifier [CONSTANT] Datatype [NOT NULL]
[:= | DEFAULT ¼ö½Ä];
-CONSTANT´Â ½Äº°ÀÚÀÇ °ªÀÌ º¯°æµÉ ¼ö ¾øµµ·Ï ¼±¾ð
-Naming RuleÀ» µû¸§
-NOT NULL·Î ÁöÁ¤µÈ »ó¼ö¿Í º¯¼ö¿¡ Ãʱ⠰ªÀ» ÁÖ¾î¾ß ÇÔ
-ÁöÁ¤ ¿¬»êÀÚ(:=)³ª DEFAULT ¿¹¾à¾î¸¦ »ç¿ëÇÏ¿© ¹ø¼ö¸¦ ÃʱâÈ ÇÒ¼ö ÀÖÀ½
-ÇÑ Çà¿¡´Â ÇϳªÀÇ º¯¼ö¸¸ ¼±¾ðÇÒ ¼ö ÀÖÀ½.
¢Ñ º¯¼ö¿Í »ó¼ö¼±¾ð: ¿¹
Fax_NumberVARCHAR2(10);
Current_Used_ValueNUMBER(6,2) := 100.00;
StateVARCHAR2(2) := 'CA';
¢ºPL/SQL¸¸ÀÇ º¯¼ö ¼±¾ð
-BOOLEAN;
True, False, Null Áß¿¡ ÇϳªÀÇ °ªÀ» °¡Áü.
-%TYPE; ÀÌ¹Ì ÁöÁ¤µÈ IdentifierÀÇ datatypeÀ» »ç¿ëÇÔ.
.µ¥ÀÌÅͺ£À̽º Å×À̺íÀÇ column
.ÀÌ¹Ì ¼±¾ðÇÑ º¯¼ö¸í
Ex> T_EmpnoEmp.Empno%TYPE;
T_MgrT_empno%TYPE;
>%TYPE ¼Ó¼ºÀ» ÀÌ¿ëÇÏ¿© ¾òÀ» ¼ö ÀÖ´Â ÀåÁ¡
¡¡.±â¼úÇÑ µ¥ÀÌÅͺ£À̽º column definitionÀ» Á¤È®È÷ ¾ËÁö ¸øÇÏ´Â °æ¿ì¿¡µµ ¾µ ¼ö ÀÖ´Ù.
¡¡.±â¼úÇÑ µ¥ÀÌÅͺ£À̽º column definitionÀÌ º¯°æµÇ¾îµµ ´Ù½Ã
PL/SQLÀ» °íÄ¥ ÇÊ¿ä ¾ø´Ù.
-%ROWTYPE; Å×À̺íÀ̳ª ViewÀÇ Column¸í°ú datatypeµéÀ» ¼±¾ðÇÑ RowÀÇ º¯¼ö·Î ÃëÇÔ.
Ex> t_emp_rowemp%ROWTYPE;
BEGIN
t_emp_row.empno := 7803;
t_emp_row.ename := 'RICHARDSON';
¢Ñ ½Ç½À¿ë Table »ý¼º
SQL> create table test_table (
record_number int,
current_date date);
¡Ü ¹Ýº¹(Loop) Á¦¾î ±¸Á¶
¢º Basic LOOP
>Exit Á¶°ÇÀÌ TrueÀÎ µ¿¾È ¹®ÀåÀ» Loop ¹Ýº¹.
>·çÇÁ ¾È¿¡ EXIT¹®ÀÌ ¾øÀ¸¸é ·çÇÁ¸¦ ¹«ÇÑÈ÷ ¹Ýº¹ÇÏ°Ô µÈ´Ù.
>EXIT¹®¿¡ WHEN Á¶°ÇÀýÀÌ ¾øÀ¸¸é ¹«Á¶°Ç ºüÁ®³ª°¨.
SQL>DECLARE
max_records CONSTANT int := 10;
i int := 0;
BEGIN
LOOP
i := i + 1;
INSERT INTO test_table (record_number, current_date)
VALUES(i, sysdate);
EXIT WHEN i >= max_records;¢ÐExit È®ÀÎ ÁöÁ¡
END LOOP;
COMMIT;
END;
¢º WHILE-LOOP
>While Á¶°ÇÀÌ TRUEÀÎ µ¿¾È¿¡ ¹®ÀåÀ» ¹Ýº¹.
SQL>DECLARE
max_records CONSTANT int := 10;
i int := 0;
BEGIN
WHILE i < 10 LOOP¢ÐExit È®ÀÎ ÁöÁ¡
i := i + 1;
INSERT INTO test_table (record_number, current_date)
VALUES(i + 10, sysdate + 1);
END LOOP;
COMMIT;
END;
¢º FOR-LOOP
>FOR¹®ÀÇ ÇÏÇѰª°ú »óÇѰª »çÀÌ Á¶°ÇÀÏ µ¿¾È¸¸ Loop ¹Ýº¹.
>À妽º´Â ÀÚµ¿ÀûÀ¸·Î ¼±¾ðµÈ´Ù.
>À妽º´Â »óÇÑ¿¡ µµ´ÞÇÒ ¶§±îÁö ·çÇÁ¸¦ ¹Ýº¹ÇÒ ¶§¸¶´Ù ÀÚµ¿ÀûÀ¸·Î 1¾¿ Áõ°¨ÇÏ´Â °ª
¡¡¡¡ >REVERSE´Â »óÇÑ¿¡¼ ÇÏÇѱîÁö À妽º°¡ ¹Ýº¹ ¶§¸¶´Ù °¨¼Ò
¡¡FOR À妽º IN [REVERSE] ÇÏÇÑ..»óÇÑ LOOP
¡¡¡¡¹®Àå1;
¡¡¡¡¹®Àå2;
¡¡¡¡...
¡¡END LOOP;
SQL>DECLARE
max_rec CONSTANT int := 30;
start_rec int := 21;
BEGIN
FOR i IN start_rec..max_rec LOOP¢ÐExit È®ÀÎ ÁöÁ¡
INSERT INTO test_table (record_number, current_date)
VALUES(i, SYSDATE + 2);
END LOOP;
COMMIT;
END;
¢¼ LOOP¿Í Label
>³»ºÎ ºí·ÏÀÇ °ª¿¡ ±Ù°ÅÇÏ¿© ¿ÜºÎ ·çÇÁ±îÁö Á¾·áÇÒ ¶§ »ç¿ë.
>LabelÀº ¹®Àå¿¡¼ÀÇ Æ¯Á¤ À§Ä¡¸¦ ÁöÁ¤ÇÒ ¶§ »ç¿ë. <<lebel_name>>
£¼£¼outer_loop£¾£¾
WHILE a>b LOOP
b:=b+1;
£¼£¼inner_loop£¾£¾
WHILE b>c LOOP
¡¡¡¡¡¡c:=c+2;
EXIT outer_loop WHEN c>200;
END LOOP inner_loop;
END LOOP outer_loop;
¢¼ GOTO¹®°ú Label
>GOTO¹®À» »ç¿ëÇÏ¿© ƯÁ¤ Label·Î ºüÁ®³ª°£´Ù.
WHILE a>b LOOP
b:=b+1;
WHILE b>c LOOP
¡¡¡¡¡¡c:=c+2;
if c>200 then
GOTO more_process;
END LOOP;
END LOOP;
<<more_process>>
¡Ü IF Á¦¾î ±¸Á¶
>Á¶°Ç¿¡ µû¶ó ¼±ÅÃÀûÀ¸·Î ÀÛ¾÷À» ¼öÇàÇÑ´Ù.
IFÁ¶°Ç THEN
¹®Àå;
[ELSIF Á¶°Ç THEN¢Ð¹Ýº¹ »ç¿ë °¡´É
¹®Àå;]
ELSE
¹®Àå;
END IF;
SQL>DECLARE
max_rec CONSTANT int := 30;
BEGIN
FOR i IN 1..max_rec LOOP
IF i <= 10 THEN
update test_table set current_date = current_date + i
where record_number = i;
ELSIF i <= 20 THEN
update test_table set current_date = current_date - i
where record_number = i;
ELSE
NULL;
END IF;
END LOOP;
COMMIT;
END;
¡Ü Null¹® »ç¿ë
>¾î¶°ÇÑ Çൿµµ ÃëÇÏÁö ¸»¾Æ¾ß ÇÒ ºÎºÐ¿¡ »ç¿ë
¡Ü ÁÖ¼® ´Þ±â
> /* ¿Í */ »çÀÌ¿¡ ÇÑ ÁÙ ÀÌ»ó ¸í½Ã
>¶Ç´Â, -- ´ÙÀ½¿¡ ÇÑ ÁÙ¸¸ ¸í½Ã
¡Ü °Ë»öµÈ ³»¿ë »ç¿ë ¹× º¸±â
SQL> SET SERVEROUTPUT ON
SQL>DECLARE
max_rec CONSTANT int := 30;
sel_rowtest_table%rowtype;
output_linevarchar2(80);
BEGIN
DBMS_OUTPUT.ENABLE;
FOR i IN 1..max_rec LOOP
SELECT * INTO sel_row.record_number, sel_row.current_date
from test_table
where record_number = i;
output_line := to_char(sel_row.record_number, '99')|| ' '
|| to_char(sel_row.current_date,'yy/mm/dd');
dbms_output.put_line(output_line);
END LOOP;
END;
¡Ü ºí·Ï ³»ÀÇ Procedure Call
>PL/SQL ºí·Ï ³»¿¡ º°µµÀÇ Procedure¸¦ ¼±¾ðÇØ ³õ°í Main
ºí·Ï¿¡¼ Procedure callÇÏ¿© »ç¿ë
SQL>DECLARE
row_cnt CONSTANT int := 10;
PROCEDURE sel_out_proc (max_rec int) is
sel_rowtest_table%rowtype;
output_linevarchar2(80);
BEGIN
DBMS_OUTPUT.ENABLE;
FOR i IN 1..max_rec LOOP
SELECT * INTO sel_row.record_number, sel_row.current_date
from test_table
where record_number = i;
output_line := to_char(sel_row.record_number, '99')|| ' '
|| to_char(sel_row.current_date,'yy/mm/dd');
dbms_output.put_line(output_line);
END LOOP;
END;
BEGIN
sel_out_proc (row_cnt);
END;
¡Ü ºí·Ï ³»ÀÇ Function Call
>PL/SQL ºí·Ï ³»¿¡ º°µµÀÇ FunctionÀ» ¼±¾ðÇØ ³õ°í Main ºí·Ï¿¡¼ Function callÇÏ¿© »ç¿ë
>Function¿¡¼ ¹Ì¸® Á¤ÀÇµÈ µ¥ÀÌÅÍÇüÀÇ °ª¸¸À» ¹ÝȯÇÑ´Ù´Â
°ÍÀ» Á¦¿ÜÇϰí´Â Procedure Call°ú µ¿ÀÏ
SQL>DECLARE
chk_char varchar2(30) := '%A%';
wild_chk_cnt varchar2(10);
FUNCTION sel_cnt_func (wild_chk varchar2) return int is
row_cntint;
BEGIN
SELECT count(*) INTO row_cnt
from student
where last_name like wild_chk;
return row_cnt;
END;
BEGIN
dbms_output.enable;
wild_chk_cnt := to_char(sel_cnt_func (chk_char), '999');
dbms_output.put_line('Last_name like ' || chk_char ||': '||wild_chk_cnt);
END;
Last_name like %A%: 15
PL/SQL 󸮰¡ Á¤»ó ¿Ï·áµÇ¾ú½À´Ï´Ù.
<½Ç½À> p267, [¸®½ºÆ® 9.15]
ƯÁ¤ Çаú(department_id)ÀÇ ¸ðµç °ÁÂ(Course_id)¿¡ ´ëÇØ¼
ºÎ°¡¼ö¾÷·á(additional_fees)°¡ °¡Àå Å« °ÁÂÄڵ带 Ãâ·ÂÇÏ´Â PL/SQL ÇÁ·Î±×·¥À»
Function()À» »ç¿ëÇÏ¿© ÀÛ¼ºÇ϶ó.
>SQL·Î ÇØ°á
SQL> select Course_ID, additional_fees
from Course A
where Department_ID = 'ECON'
and Additional_Fees =
(select max(Additional_Fees)
from Course B
where A.Department_ID = B.Department_id);
>PL/SQL·Î ÇØ°á
SQL> DECLARE
Course_ID Course.Course_ID%type;
FUNCTION Max_Additional_Fees (Dept_ID varchar2)
return varchar2 is
Additional_Fees Course.Additional_Fees%type;
Units Course.Units%type;
Course_ID Course.Course_ID%type;
BEGIN
select Course_ID into Course_ID
from Course
where Department_ID = Dept_ID
and Additional_Fees =
(select max(Additional_Fees)
from Course
where Department_ID = Dept_ID);
return Course_ID;
END;
-- Beginning of executable section of anonymous block.
BEGIN
dbms_output.enable;
Course_ID := Max_Additional_Fees ('ECON');
dbms_output.put_line('Course_ID: ' || Course_ID);
END;
<½Ç½À> p269 [¸®½ºÆ® 9.16]
declare
this_arg1 number;
this_arg2 number;
this_arg3 number;
output_linevarchar2(80);
procedure different_arguments
(arg1in number,
arg2out number,
arg3in out number) is
begin
arg2 := arg1;
arg3 := arg3 + 1;
end;
begin
this_arg1 := 3.14159;
this_arg2 := 5;
this_arg3 := 10;
different_arguments (this_arg1, this_arg2, this_arg3);
dbms_output.enable;
output_line := to_char(this_arg1,'99.99') || ' '
|| to_char(this_arg2,'99.99') || ' ' || to_char(this_arg3,'99.99');
dbms_output.put_line(output_line);
end;
¡Ü ¿¹¿Ü(EXCEPTION) ó¸®
>PL/SQLÀ» ½ÇÇà µ¿¾È¿¡ ¹ß»ýÇÏ´Â error¿¡ ´ëÇÑ Ã³¸®¸¦ ÀǹÌÇÑ´Ù.
¢Ã ¹Ì¸® Á¤ÀÇµÈ ¿¹¿Ü (System¿¡¼ Á¦°ø)
¢Ã DUP_VAL_ON_INDEX ; À¯Àϰª Áߺ¹ Error
¢Ã INVALID_NUMBER ;Data type ºÒÀÏÄ¡ Error
¢Ã NO_DATA_FOUND ;ÇØ´ç ÀÚ·á°¡ ¾øÀ» ¶§
¢Ã TOO_MANY_ROWS ;¹ÝȯµÈ °ªÀÌ Çϳª ÀÌ»óÀÏ ¶§ (Select ~ into ~ ¿¡¼)
¢Ã VALUE_ERROR ;´ëÀԵǴ °ªÀÌ ±æÀÌ Ãʰú Error
<½Ç½À>
¢Ã DUP_VAL_ON_INDEX ; p313, [¸®½ºÆ® 11.3]
¢Ã INVALID_NUMBER ;p314, [¸®½ºÆ® 11.4]
¢Ã NO_DATA_FOUND ;p315, [¸®½ºÆ® 11.6]
¢Ã TOO_MANY_ROWS ;p315, [¸®½ºÆ® 11.7]
¢Ã VALUE_ERROR ;p316, [¸®½ºÆ®
11.8]
<½Ç½À> Course Å×ÀÌºí¿¡¼ course_id=''777'ÀÎ ÇàÀÇ ³»¿ëÀ» ¸ðµÎ Á¶È¸Ç϶ó.
¢Ã DUP_VAL_ON_INDEX ; p313,
[¸®½ºÆ® 11.3]
SQL>declare
Course_Rec Course%ROWTYPE;
begin
dbms_output.enable;
select *
into Course_Rec from Course
where Course_ID = '777';
exception
when NO_DATA_FOUND then
dbms_output.put_line('No data returned');
when TOO_MANY_ROWS then
dbms_output.put_line('TOO_MANY_ROW returned');
when OTHERS then
NULL;
end;