6.Procedure預存程序
文法:
CREATE OR REPLACE PROCEDURE procedure_name
[(argument_name [{IN|OUT|IN OUT}] TYPE,
...
argument_name [{IN|OUT|IN OUT}] TYPE)]
{IS|AS}
BEGIN
statements
END;
預存程序也稱作:帶名塊,它可儲存於資料庫中,可以在任何需要的地方調用,此外帶明塊還包括: FUNCTION,PACKAGE,TRIGGER.
有帶名的,當然周有不帶名的:匿名塊
匿名塊:
不能儲存在資料庫中,每次使用時都進行解析,不能在其他塊中相互調用
文法:
DECLARE
//聲明取
BEGIN
//塊體
END
繼續回到Procedure,先看一個簡單的demo:
CREATE OR REPLACE PROCEDURE pro_hello IS
//以上頭部相當於匿名塊的:DECLARE
BEGIN
DBMS_OUTPUT.PUT_LINE('HELLO,WORLD');
//在螢幕上輸出一個HELLO,WORLD字串,每進入一次SQLPLUS時,程式中要想看到輸出結果就要開啟開關:set serveroutput on
END;
可以在匿名塊中調用上面的預存程序,
BEGIN
pro_hello;
//預存程序的名字
END;
以上是一個簡單的樣本!沒麼實用價值,通常我們用資料庫都會涉及對資料的:增,刪,改,查:
超簡單的查詢:
CREATE OR REPLACE PROCEDURE pro_lab(
p_id s_emp.ID%TYPE //p_id是pro_lab的形參
) IS
v_fname s_emp.FIRST_NAME%TYPE;
BEGIN
SELECT FIRST_NAME
INTO v_fname
//INTO把查的結果賦值給變數:v_fname
FROM s_emp
WHERE ID=p_id;
DBMS_OUTPUT.PUT_LINE('HELLO, '||v_fname);
END;
//調用procedure
file-name:lab1.sql
BEGIN
pro_lab(1); //1:pro_lab的實參
END;
Procedure的參數模式:
IN:
預設模式.在調用Procedure的時候,Procedure的實參的值被傳遞到該Procedure,在Procedure的內部,Procedure的形參是唯讀:
OUT:
在調用Procedure時,任何的Procedure的實參都將被忽略,在Procedure的內部,形參是只可寫的:
IN OUT:
IN與OUT的組合.在調用Procedure的時候,實參的值可以被傳遞給該Procedure;在其內部,形參也可以被讀出也可以被寫入;該Procedure結束時,控制會返回給控制環境,而形參的內容將賦給調用時的實參.
CREATE OR REPLACE PROCEDURE pro_param(
p_in IN NUMBER, //參數類型後不能帶精度/刻度,也周是不能帶:(3)
p_out OUT NUMBER //procedure的形參
) IS
BEGIN
DBMS_OUTPUT.PUT_LINE('IN PARAM: '||p_in);
p_in := 100; //IN模式的形參只可讀
DBMS_OUTPUT.PUT_LINE('OUT PARAM: '||p_out);
p_out : = 200; //OUT模式只能從procedure往外帶值
END;
//調用procedure
file-name:lab3.sql
DECLARE
v_out NUMBER :=100; //該實參不能傳進procedure中
BEGIN
pro_param(2,v_out); //2:IN 模式的實參 v_out:OUT模式的實參
END;
練習:
查詢某位員工的領導姓名
CREATE OR REPLACE PROCEDURE p_lab(
p_id IN s_emp.ID%TYPE,
p_fname OUT s_emp.FIRST_NAME%TYPE) IS
v_fname s_emp.FIRST_NAME%TYPE;
v_mid s_emp.ID%TYPE;
BEGIN
SELECT decode(a.FIRST_NAME, NULL, b.FIRST_NAME, a.FIRST_NAME) name
INTO v_fname
FROM s_emp a,s_emp b
WHERE b.MANAGER_ID=a.ID(+) and b.ID=p_id;
p_fname := v_fname;
/*
SELECT FIRST_NAME,MANAGER_ID
INTO v_fname,v_mid
FROM s_emp
WHERE ID=p_id
IF v_mid IS NULL THEN
p_fname := v_fname;
ELSE
SELECT FIRST_NAME
INTO p_fname
FROM s_emp
WHERE ID=v_mid
END IF
*/
END;
file-name:lab6.sql
DECLARE
v_name s_emp.FIRST_NAME%TYPE;
BEGIN
p_lab(3,v_name);
DBMS_OUTPUT.PUT_LINE('MANAGER IS: '||vname);
END;
注惜掉的是老師推薦的寫法