《Oracle PL/SQL開發指南》學習筆記28——原始碼除錯——PL/SQL基礎知識(第三部分)
阿新 • • 發佈:2019-01-28
1. 變數賦值時(隱式)強制型別轉換 (讓我想起了將近二十年前學C語言時的場景)
SQL> edit Wrote file afiedt.buf 1 DECLARE 2 lv_input INTEGER; 3 BEGIN 4 lv_input := 4.67; 5 dbms_output.put_line('['||lv_input||']'); 6 EXCEPTION 7 WHEN OTHERS THEN 8 dbms_output.put_line('['||SQLERRM||']'); 9* END; SQL> / [5] PL/SQL procedure successfully completed.
2. 巢狀匿名塊中的變數的作用域(學C語言時就碰到過)
SQL> edit Wrote file afiedt.buf 1 /* Formatted on 2018/11/26 13:58:37 (QP5 v5.256.13226.35538) */ 2 DECLARE 3 -- Declare local variable. 4 lv_input VARCHAR2 (30) DEFAULT 'OUTER'; 5 BEGIN 6 -- Print the value before the inner block. 7 DBMS_OUTPUT.put_line ('Outer block [' || lv_input || ']'); 8 -- Nested block. 9 BEGIN 10 -- Print the value before the assignment. 11 DBMS_OUTPUT.put_line ('Inner block [' || lv_input || ']'); 12 -- Assign new value to variable. 13 lv_input := 'INNER'; 14 -- Print the value after the assignment. 15 DBMS_OUTPUT.put_line ('Inner block [' || lv_input || ']'); 16 END; 17 -- Print the value after the nested block. 18 DBMS_OUTPUT.put_line ('Outer block [' || lv_input || ']'); 19 EXCEPTION 20 WHEN OTHERS 21 THEN 22 DBMS_OUTPUT.put_line ('Exception [' || SQLERRM || ']'); 23* END; 24 / Outer block [OUTER] Inner block [OUTER] Inner block [INNER] Outer block [INNER] PL/SQL procedure successfully completed.
3. 同名變數在內部塊和外部塊具有不同的“可見性” (這個可是當年大學C語言考試必類內容啊,笑!)
SQL> edit Wrote file afiedt.buf 1 /* Formatted on 2018/11/26 14:05:26 (QP5 v5.256.13226.35538) */ 2 DECLARE 3 -- Declare local variable. 4 lv_outer VARCHAR2 (30) DEFAULT 'OUTER'; 5 lv_active VARCHAR2 (30) DEFAULT 'OUTER'; 6 BEGIN 7 -- Print the value before the inner block. 8 DBMS_OUTPUT.put_line ( 9 'Outer [' || lv_outer || '][' || lv_active || ']'); 10 -- Nested block. 11 DECLARE 12 -- Declare local variable. 13 lv_active VARCHAR2 (30) DEFAULT 'INNER'; 14 BEGIN 15 -- Print the value before the assignment. 16 DBMS_OUTPUT.put_line ( 17 'Inner [' || lv_outer || '][' || lv_active || ']'); 18 -- Assign new value to variable. 19 lv_outer := 'INNER'; 20 -- Print the value after the assignment. 21 DBMS_OUTPUT.put_line ( 22 'Inner [' || lv_outer || '][' || lv_active || ']'); 23 END; 24 -- Print the value after the nested block. 25 DBMS_OUTPUT.put_line ( 26 'Outer [' || lv_outer || '][' || lv_active || ']'); 27 EXCEPTION 28 WHEN OTHERS 29 THEN 30 DBMS_OUTPUT.put_line ('Exception ' || SQLERRM || ']'); 31* END; 32 / Outer [OUTER][OUTER] Inner [OUTER][INNER] Inner [INNER][INNER] Outer [INNER][OUTER] PL/SQL procedure successfully completed.
4. 區域性命名塊 (Local Named Blocks) (這名字也真夠唬人的,無非就是在匿名塊中嵌套了一個命名的過程而已)
SQL> edit
Wrote file afiedt.buf
1 /* Formatted on 2018/11/26 14:15:09 (QP5 v5.256.13226.35538) */
2 DECLARE
3 -- Declare local variable.
4 lv_outer VARCHAR2 (30) DEFAULT 'OUTER';
5 lv_active VARCHAR2 (30) DEFAULT 'OUTER';
6 -- A local procedure without any formal parameters.
7 PROCEDURE local_named
8 IS
9 -- Declare local variable.
10 lv_active VARCHAR2 (30) DEFAULT 'INNER';
11 BEGIN
12 -- Print the value before the assignment.
13 DBMS_OUTPUT.put_line (
14 'Inner [' || lv_outer || '][' || lv_active || ']');
15 -- Assign new value to variable.
16 lv_active := 'INNER';
17 -- Print the value after the assignment.
18 DBMS_OUTPUT.put_line (
19 'Inner [' || lv_outer || '][' || lv_active || ']');
20 END local_named;
21 BEGIN
22 -- Print the value before the inner block.
23 DBMS_OUTPUT.put_line ('Outer ' || lv_outer || '][' || lv_active || ']');
24 -- Call to the locally declared named procedure.
25 local_named;
26 -- Print the value after the nested block.
27 DBMS_OUTPUT.put_line ('Outer [' || lv_outer || '][' || lv_active || ']');
28 EXCEPTION
29 WHEN OTHERS
30 THEN
31 DBMS_OUTPUT.put_line ('Exception [' || SQLERRM || ']');
32* END;
SQL> /
Outer OUTER][OUTER]
Inner [OUTER][INNER]
Inner [OUTER][INNER]
Outer [OUTER][OUTER]
PL/SQL procedure successfully completed.
5. 在命名程式中放入程式碼邏輯的方法稱為模組性,通常它能使你的程式碼結構更加清晰
6. PL/SQL是一個單步執行的解析過程,它從上至下一次性讀取原始碼。這意味著所有的識別符號(如函式名和過程名)必須在呼叫前予以定義,否則會導致執行時錯誤。
SQL> /* Formatted on 2018/11/26 14:22:03 (QP5 v5.256.13226.35538) */
SQL> DECLARE
2 PROCEDURE jack
3 IS
4 BEGIN
5 DBMS_OUTPUT.put_line (hector || ' World!');
6 END jack;
7
8 FUNCTION hector
9 RETURN VARCHAR2
10 IS
11 BEGIN
12 RETURN 'Hello';
13 END hector;
14 BEGIN
15 jack;
16 END;
17 /
DBMS_OUTPUT.put_line (hector || ' World!');
*
ERROR at line 5:
ORA-06550: line 5, column 29:
PLS-00313: 'HECTOR' not declared in this scope
ORA-06550: line 5, column 7:
PL/SQL: Statement ignored
7. 上述程式可如下修改
SQL> edit
Wrote file afiedt.buf
1 DECLARE
2 PROCEDURE jack;
3 FUNCTION hector
4 RETURN VARCHAR2;
5 PROCEDURE jack
6 IS
7 BEGIN
8 DBMS_OUTPUT.put_line (hector || ' World!');
9 END jack;
10 FUNCTION hector
11 RETURN VARCHAR2
12 IS
13 BEGIN
14 RETURN 'Hello';
15 END hector;
16 BEGIN
17 jack;
18* END;
19 /
Hello World!
PL/SQL procedure successfully completed.
8. 儲存命名塊(模式級的函式或過程)
SQL> /* Formatted on 2018/11/26 14:28:38 (QP5 v5.256.13226.35538) */
SQL> CREATE OR REPLACE PROCEDURE local_named
2 IS
3 -- Declare local variable.
4 lv_active VARCHAR2 (30) DEFAULT 'INNER';
5 lv_outer VARCHAR2 (30) DEFAULT ' ';
6 BEGIN
7 -- Print the value before the assignment.
8 DBMS_OUTPUT.put_line ('Inner [' || lv_outer || '][' || lv_active || ']');
9
10 -- Assign new value to variable.
11 lv_outer := 'INNER';
12
13 -- Print the value after the assignment.
14 DBMS_OUTPUT.put_line ('Inner [' || lv_outer || '][' || lv_active || ']');
15 END local_named;
16 /
Procedure created.
SQL> exec local_named;
Inner [ ][INNER]
Inner [INNER][INNER]
PL/SQL procedure successfully completed.
/* Formatted on 2018/11/26 14:32:14 (QP5 v5.256.13226.35538) */
DECLARE
-- Declare local variable.
lv_outer VARCHAR2 (30) DEFAULT 'OUTER';
lv_active VARCHAR2 (30) DEFAULT 'OUTER';
BEGIN
-- Print the value before the inner block.
DBMS_OUTPUT.put_line ('Outer [' || lv_outer || '][' || lv_active || ']');
-- Call to the locally declared named procedure.
local_named;
-- Print the value after the nested block.
DBMS_OUTPUT.put_line ('Outer [' || lv_outer || '][' || lv_active || ']');
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line ('Exception [' || SQLERRM || ']');
END;
輸出為:
Outer [OUTER][OUTER]
Inner [ ][INNER]
Inner [INNER][INNER]
Outer [OUTER][OUTER]
PL/SQL procedure successfully completed.