1:調試技巧
大家調試遊标的時候通常使用的都是直接在存儲過程裡DBMS_OUTPUT包來進行列印資訊的,示例如下:
CREATE OR REPLACE PROCEDURE SP_EMP_FOR(P_DEPTNO IN NUMBER) IS
TYPE EMP_ROW_TYPE IS TABLE OF EMP%ROWTYPE INDEX BY BINARY_INTEGER;
EMP_ROW EMP_ROW_TYPE;
I INT := 1;
EMP_TYPE EMP%ROWTYPE;
BEGIN
FOR TMPROW IN (SELECT *
FROM EMP
WHERE DEPTNO = P_DEPTNO
ORDER BY EMP.EMPNO) LOOP
EMP_ROW(I) := TMPROW;
I := I + 1;
END LOOP;
FOR I IN 1 .. EMP_ROW.COUNT LOOP
EMP_TYPE := EMP_ROW(I);
DBMS_OUTPUT.PUT_LINE('empno :' || EMP_TYPE.EMPNO || ' ename : ' ||
EMP_TYPE.ENAME || ' hiredate :' ||
EMP_TYPE.HIREDATE);
END LOOP;
END SP_EMP_FOR;
SQL> set serveroutput on
SQL> EXEC SP_EMP_FOR(10);
empno :7782 ename : CLARK hiredate :09-JUN-81
empno :7839 ename : KING hiredate :17-NOV-81
empno :7934 ename : MILLER hiredate :23-JAN-82
PL/SQL procedure successfully completed.
2:特殊遊标變量調試技巧
在存儲過程調試時候大部分使用工具調試,例如PLSQL DEVELOP,但是列印所有的變量卻有更友善的調試方法,如下示例可以列印出所有的變量,包括有遊标裡的資料:
CREATE OR REPLACE PROCEDURE SP_TEST(
p_deptno IN NUMBER,
P_OUTSTR OUT VARCHAR2,
P_OUTINT OUT NUMBER,
P_REF1 OUT SYS_REFCURSOR,
P_REF2 OUT SYS_REFCURSOR) AS
BEGIN
P_OUTSTR := 'scott';
P_OUTINT := 1234;
OPEN P_REF1 FOR
SELECT EMPNO, ENAME, HIREDATE FROM EMP WHERE DEPTNO = p_deptno;
OPEN P_REF2 FOR
SELECT * FROM EMP WHERE DEPTNO = p_deptno;
END SP_TEST;
[[email protected] ~]$ sqlplus scott/tiger
SQL*Plus: Release 10.2.0.4.0 - Production on Thu Jun 7 19:14:04 2012
Copyright (c) 1982, 2007, Oracle. All Rights Reserved.
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> SET AUTOPRINT ON
SQL> VAR P_OUTSTR VARCHAR2(10);
SQL> VAR P_OUTINT NUMBER;
SQL> VAR P_REF1 REFCURSOR;
SQL> VAR P_REF2 REFCURSOR;
SQL> VAR p_deptno NUMBER;
SQL> EXEC SP_TEST(10,:P_OUTSTR, :P_OUTINT, :P_REF1, :P_REF2);
PL/SQL procedure successfully completed.
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
---------- ---------- --------- ---------- --------- ---------- ----------
7782 CLARK MANAGER 7839 09-JUN-81 2450 10
7839 KING PRESIDENT 17-NOV-81 5000 10
7934 MILLER CLERK 7782 23-JAN-82 1300 10
EMPNO ENAME HIREDATE
---------- ---------- ---------
7369 SMITH 17-DEC-80
7566 JONES 02-APR-81
7788 SCOTT 19-APR-87
7876 ADAMS 23-MAY-87
7902 FORD 03-DEC-81
P_OUTINT
----------
1234
P_OUTSTR
--------
scott
注意:這裡的SET AUTOPRINT ON 一定要開啟。
3:使用對象類型,列印結果集
--建立自定義對象類型
CREATE TYPE EMP_TYPE AS OBJECT
(
EMPNO NUMBER,
ENAME VARCHAR2(20),
HIREDATE DATE,
DEPTNO NUMBER
);
--建立對象類型
CREATE TYPE EMP_TEST AS TABLE OF EMP_TYPE;
--構造類型資料函數
CREATE OR REPLACE FUNCTION EMP_TABLE RETURN EMP_TEST AS
V_RET EMP_TEST := EMP_TEST();
BEGIN
FOR I IN 1 .. 10 LOOP
V_RET.EXTEND;
V_RET(I) := EMP_TYPE(I, 'Name' || I,Sysdate-i,10);
END LOOP;
RETURN V_RET;
END EMP_TABLE;
SQL> select * from table(EMP_TABLE);
EMPNO ENAME HIREDATE DEPTNO
---------- -------------------- --------- ----------
1 Name1 07-JUN-12 10
2 Name2 06-JUN-12 10
3 Name3 05-JUN-12 10
4 Name4 04-JUN-12 10
5 Name5 03-JUN-12 10
6 Name6 02-JUN-12 10
7 Name7 01-JUN-12 10
8 Name8 31-MAY-12 10
9 Name9 30-MAY-12 10
10 Name10 29-MAY-12 10
10 rows selected.
4:用SELECT BULK COLLECT INTO取得資料,傳回嵌套表的例子
CREATE OR REPLACE FUNCTION EMP_TABLE_test RETURN EMP_TEST
AS
v_ret EMP_TEST:=EMP_TEST();
BEGIN
SELECT EMP_TYPE(EMP.EMPNO,EMP.ENAME,EMP.HIREDATE,EMP.DEPTNO)
BULK COLLECT INTO v_ret
FROM EMP;
RETURN v_ret;
END EMP_TABLE_test;
SQL> select * from table(EMP_TABLE_test);
EMPNO ENAME HIREDATE DEPTNO
---------- -------------------- --------- ----------
7369 SMITH 17-DEC-80 20
7499 ALLEN 20-FEB-81 30
7521 WARD 22-FEB-81 30
7566 JONES 02-APR-81 20
7654 MARTIN 28-SEP-81 30
7698 BLAKE 01-MAY-81 30
7782 CLARK 09-JUN-81 10
7788 SCOTT 19-APR-87 20
7839 KING 17-NOV-81 10
7844 TURNER 08-SEP-81 30
7876 ADAMS 23-MAY-87 20
7900 JAMES 03-DEC-81 30
7902 FORD 03-DEC-81 20
7934 MILLER 23-JAN-82 10
14 rows selected.