※限制包的行為
可參考官方網站常用的有四種:
WNDS:Writes No Database State-->不能寫入資料庫的狀態,所以不能新增、修改、刪除
RNDS:Reads No Database State-->不能讀資料庫的狀態,所以不能查詢
WNPS:Writes No Package State-->不能寫入包的狀態,所以不能賦值,如var := 'x';
RNPS:Reads No Package State-->不能讀包的狀態,所以不能使用變數
CREATE OR REPLACE PACKAGE xxx_pkg IS ooo VARCHAR2(10) := 'ooo'; FUNCTION a(p NUMBER) RETURN NUMBER; FUNCTION b(p VARCHAR2) RETURN NUMBER; FUNCTION c(p1 NUMBER, p2 VARCHAR2) RETURN VARCHAR2; FUNCTION d(p1 VARCHAR2, p2 NUMBER) RETURN VARCHAR2; PRAGMA RESTRICT_REFERENCES(a, WNDS); PRAGMA RESTRICT_REFERENCES(b, RNDS); PRAGMA RESTRICT_REFERENCES(c, WNPS); PRAGMA RESTRICT_REFERENCES(d, RNPS); END;
※定義四個限制包的行為
CREATE OR REPLACE PACKAGE BODY xxx_pkg IS FUNCTION a(p NUMBER) RETURN NUMBER IS BEGIN DELETE FROM DEPT WHERE DEPTNO = p; RETURN 0; END a; FUNCTION b(p VARCHAR2) RETURN NUMBER IS xxx DEPT%ROWTYPE; BEGIN SELECT * INTO xxx FROM DEPT WHERE DNAME = p; RETURN 0; END b; FUNCTION c(p1 NUMBER, p2 VARCHAR2) RETURN VARCHAR2 IS BEGIN ooo := 'xxx'; RETURN ''; END c; FUNCTION d(p1 VARCHAR2, p2 NUMBER) RETURN VARCHAR2 IS BEGIN RETURN ooo; END d; END;
※包體故意違反後編譯,就會出現如下的錯誤
Compilation errors for PACKAGE BODY OOO.XXX_PKG
Error: PLS-00452: Subprogram 'A' violates its associated pragma
Line: 3
Text: FUNCTION a(p NUMBER) RETURN NUMBER IS
Error: PLS-00452: Subprogram 'B' violates its associated pragma
Line: 9
Text: FUNCTION b(p VARCHAR2) RETURN NUMBER IS
Error: PLS-00452: Subprogram 'C' violates its associated pragma
Line: 16
Text: FUNCTION c(p1 NUMBER, p2 VARCHAR2) RETURN VARCHAR2 IS
Error: PLS-00452: Subprogram 'D' violates its associated pragma
Line: 22
Text: FUNCTION d(p1 VARCHAR2, p2 NUMBER) RETURN VARCHAR2 IS
Error: Hint: Parameter 'p1' is declared but never used in 'c'
Line: 16
Text: FUNCTION c(p1 NUMBER, p2 VARCHAR2) RETURN VARCHAR2 IS
Error: Hint: Parameter 'p2' is declared but never used in 'c'
Line: 16
Text: FUNCTION c(p1 NUMBER, p2 VARCHAR2) RETURN VARCHAR2 IS
Error: Hint: Parameter 'p1' is declared but never used in 'd'
Line: 22
Text: FUNCTION d(p1 VARCHAR2, p2 NUMBER) RETURN VARCHAR2 IS
Error: Hint: Parameter 'p2' is declared but never used in 'd'
Line: 22
Text: FUNCTION d(p1 VARCHAR2, p2 NUMBER) RETURN VARCHAR2 IS
※也可以限制只能讀取資料庫等,如:
PRAGMA RESTRICT_REFERENCES(a, WNDS, WNPS, RNPS);
也就是用逗號隔開
※DBMS_OUTPUT包
※PUT_LINE、ENABLE、DISABLE、PUT、NEW_LINE
DECLARE BEGIN DBMS_OUTPUT.PUT_LINE('目前看得見'); DBMS_OUTPUT.DISABLE; DBMS_OUTPUT.PUT_LINE('看不見'); DBMS_OUTPUT.ENABLE; DBMS_OUTPUT.PUT_LINE('看得見'); DBMS_OUTPUT.PUT('ww'); DBMS_OUTPUT.PUT('w.'); DBMS_OUTPUT.NEW_LINE; DBMS_OUTPUT.PUT('因為後面沒有執行NEW_LINE,所以看不見'); END;
※結果:
看得見
www.
※DISABLE方法是將整個輸出關閉,不管之前有沒有,一切全洗掉,類似SET SERVEROUTPUT OFF
※PUT後面必需有接換行的方法才會印出,如NEW_LINE、PUT_LINE
※debug時,寫DBMS_OUTPUT.PUT_LINE寫太多時報錯,可用exception印SQLCODE,有可能是報「-20000」的錯,因為超過buffer大小,預設是20000,可參考官網
以下是不設定 buffer 的做法:
declare begin DBMS_OUTPUT.ENABLE(null); for i in 1..1000 loop dbms_output.put_line('1234567890'); end loop; end;
※給 null 和空都可以,或者用以下的方式
※如果兩個都設定,以程式碼為主
※GET_LINE
DECLARE line1 VARCHAR2(20); line2 VARCHAR2(20); status INTEGER; BEGIN DBMS_OUTPUT.ENABLE; DBMS_OUTPUT.PUT('http:'); DBMS_OUTPUT.PUT('//'); DBMS_OUTPUT.NEW_LINE; DBMS_OUTPUT.PUT('www.'); DBMS_OUTPUT.PUT('google.com'); DBMS_OUTPUT.NEW_LINE; DBMS_OUTPUT.GET_LINE(line1, status); -- DBMS_OUTPUT.GET_LINE(line2, status); DBMS_OUTPUT.PUT_LINE('line1=' || line1); -- DBMS_OUTPUT.PUT_LINE('line2=' || line2); DBMS_OUTPUT.PUT_LINE('status=' || status); END;
※結果:
l1=http://
xxx_out=0
※一直到最後的NEW_LINE是上一個程式碼講過的,但一執行到GET_LINE就什麼都印不出來了,然後要到PUT_LINE又會印出,印出的是第一次NEW_LINE上面的全部內容,也就是http和//兩行,而最後的xxx_out只有兩個值,1和0,0表示成功印出,1表示一行都沒有,可參考官方網站,所以將ENABLE到第二次的NEW_LINE註解就會印出1了
※GET_LINES、CHARARR
DECLARE lines DBMS_OUTPUT.CHARARR; -- lines DBMSOUTPUT_LINESARRAY; numlines INTEGER := 2; BEGIN DBMS_OUTPUT.ENABLE; DBMS_OUTPUT.PUT('http:'); DBMS_OUTPUT.PUT('//'); DBMS_OUTPUT.NEW_LINE; DBMS_OUTPUT.PUT('www.'); DBMS_OUTPUT.PUT('google.com'); DBMS_OUTPUT.NEW_LINE; DBMS_OUTPUT.GET_LINES(lines, numlines); FOR i IN lines.FIRST..lines.LAST LOOP DBMS_OUTPUT.PUT_LINE(lines(i)); END LOOP; END;
※如果將numlines設為1就等同於GET_LINE
※註解那行也可以,官網有寫
沒有留言:
張貼留言