3.6.5 與存儲程序有關的數據字典
在數據庫中,存儲過程、存儲函數以及程序包的信息是存放在數據字典中的。與存儲程序有關的數據字典有:
user_procedures
user_objects
user_source
user_errors
在數據字典user_procedures中存放的是當前用戶所擁有的存儲過程和存儲函數信息。例如,要想查看當前用戶所擁有的存儲過程和存儲函數,執行下面的SELECT語句:
- SQL>SELECT object_name,object_type, authid FROM user_procedures;
- OBJECT_NAME OBJECT_TYPE AUTHID
- EMPLOYEE PACKAGE DEFINER
- EMPLOYEE PACKAGE DEFINER
- TAX_PER_DEPART FUNCTION DEFINER
- TOTAL_INCOME PROCEDURE DEFINER
數據字典user_objects用來存放當前用戶所擁有的所有類型的數據庫對象,包括表、視圖、觸發器、序列、存儲過程、存儲函數以及程序包等。如果要了解當前用戶所擁有的數據庫對象類型,可以執行下面的SELECT語句:
- SQL> SELECT distinct object_type FROM user_objects;
- OBJECT_TYPE
- ------------------
- FUNCTION
- INDEX
- PACKAGE
- PACKAGE BODY
- PROCEDURE
- TABLE
從執行結果可以看出,在當前用戶所擁有的模式中,有索引、表、存儲過程、存儲函數和程序包五種數據庫對象。程序包的頭部和包體的類型分別爲PACKAGE和PACKAGE BODY。如果要查看某個數據庫對象的詳細信息,同樣可以執行相應的SELECT語句。例如,以下SELECT語句用來查看對象“total_income”的詳細信息:
- SQL> SELECT object_name,object_type,created,
status FROM user_objects - WHERE object_name='TOTAL_INCOME';
- OBJECT_NAM OBJECT_TYPE CREATED STATUS
- ---------- ------------------ ---------- -------
- TOTAL_INCOME FUNCTION 28-5月-10 VALID
數據字典user_source用來存放存儲過程、存儲函數和程序包的源代碼。當然,這個視圖的目的只是爲了查看源代碼,PL/SQL程序的執行並不是從這裏開始的,因爲程序在創建時已經經過了編譯,在數據庫中以二進制形式存儲。因此,試圖通過修改這個數據字典而達到修改存儲程序的功能是行不通的。Oracle在創建PL/SQL程序時,將按照用戶在編寫時的自然格式,以行的形式存儲程序代碼,並記錄每行的行號,所有代碼行合起來就是該程序的源代碼。例如,要查看函數tax_per_depart的源代碼,可以執行下列SELECT語句:
- SQL> SELECT line,text FROM user_source WHERE name='TAX_PER_DEPART';
- LINE TEXT
- ---------- --------------------------------------------------
- 1 function tax_per_depart(dno integer)
- 2 RETURN number
- 3 as
- 4 result number;
- 5 BEGIN
- 6 SELECT sum(sal)*0.03 INTO result FROM emp
- 7 WHERE deptno=dno
- 8 GROUP BY deptno;
- 9 RETURN result;
- 10 END;
如果在創建存儲過程、存儲函數或者程序包時發生了語法錯誤,SQL*Plus將把錯誤信息在屏幕上顯示,同時Oracle把錯誤信息記錄在數據字典中。數據字典user_errors就是用來存放當前用戶在創建存儲程序時發生的錯誤的。例如,在創建存儲函數total_income時,錯把SELECT語句中的“WHERE deptno=dno”寫成了“WHERE deptno=ddno”,於是發生了錯誤:
- CREATE OR REPLACE FUNCTION total_income(dno emp.deptno%type)
- RETURN number
- as
- result number;
- BEGIN
- SELECT sum(sal) INTO result FROM emp
- WHERE deptno=ddno
- GROUP BY deptno;
- RETURN result;
- END;
- SQL>/
- 警告: 創建的函數帶有編譯錯誤。
爲了確定發生的所有錯誤的位置,執行下列查詢語句:
- SQL> SELECT sequence,line,position FROM user_errors
- WHERE name='TOTAL_ INCOME';
- SEQUENCE LINE POSITION
- ------------------------------ ------------
---------- ---------- ---------- - 1 7 14
- 2 6 1
可以看出,發生了兩個錯誤,第一個位於第7行第14個字符處,第二個位於第6行第1個字符處。爲了查看第一個錯誤的詳細信息,需要檢索TEXT列的數據:
- SQL> SELECT text FROM user_errors WHERE SEQUENCE=1;
- TEXT
- --------------------------------------------------------------------
- PLS-00103: 出現符號"END"在需要下列之一時:
- BEGIN case DECLARE exit for
- goto if loop mod null pragma raise RETURN SELECT UPDATE while
- with <an identifier> <a double-quoted delimited-identifier>
- <a bind variable> << close current DELETE fetch lock INSERT
- open rollback savepoint set sql execute commit forall merge
- <a single-quoted SQL string> pipe
- PL/SQL: ORA-00904: "DDNO": 無效的標識符
根據這些錯誤信息很快便可以確定錯誤的原因,從而進行糾正。在很多情況下,發生的多個錯誤是由同一個原因引起的,只要修改了出現錯誤的程序代碼,多個錯誤可能一起消失。這需要用戶在編寫程序的過程中不斷積累經驗。
SQL*Plus還提供了一種查看錯誤信息的簡便方法,用show errors命令可以查看當前發生的錯誤,而不需要了解數據字典的詳細結構。這個命令的用法爲:
- SQL>show errors
命令執行的結果爲:
- FUNCTION TOTAL_INCOME 出現錯誤:
- LINE/COL ERROR
- -------- ----------------------------------------
- 6/1 PL/SQL: SQL Statement ignored
- 7/14 PL/SQL: ORA-00904: "DDNO": 無效的標識符
或者在查看錯誤信息時指定發生錯誤的對象的類型和名稱,如:
- SQL>show errors function total_income
在這種情況下,命令show errors的格式爲:
- SQL>show errors 對象類型 對象名稱