1. Trang chủ
  2. » Công Nghệ Thông Tin

Oracle Built−in Packages- P18 pdf

5 322 1

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 5
Dung lượng 82,15 KB

Nội dung

fdbk INTEGER; BEGIN DBMS_SQL.PARSE (cur, 'BEGIN ' || proc || '(' || arglist || ', :outparam); END;', DBMS_SQL.NATIVE); DBMS_SQL.BIND_VARIABLE (cur, 'outparam', 1); fdbk := DBMS_SQL.EXECUTE (cur); DBMS_SQL.VARIABLE_VALUE (cur, 'outparam', outval); DBMS_SQL.CLOSE_CURSOR (cur); END; / Now if I have the following procedure defined: CREATE OR REPLACE PROCEDURE testdyn (in1 IN NUMBER, in2 IN DATE, out1 OUT NUMBER) IS BEGIN out1 := in1 + TO_NUMBER (TO_CHAR (in2, 'YYYY')); END; / Then I can execute testdyn dynamically as follows: DECLARE n NUMBER; BEGIN runproc ('testdyn', '1, sysdate', n); DBMS_OUTPUT.PUT_LINE (n); END; / As you have likely discerned, this is not a very good general−purpose program. It will work only with procedures that have parameter lists in which the last argument is a numeric OUT parameter and that argument must be the only OUT or IN OUT parameter in the list. There can be many complications when attempting to execute dynamic PL/SQL. For suggestions on how best to perform these tasks, see the "Tips on Using Dynamic SQL" section. 2.3.9 Closing the Cursor When you are done working with a cursor, you should close it and release associated memory. 2.3.9.1 The DBMS_SQL.CLOSE_CURSOR procedure The CLOSE_CURSOR procedure closes the specified cursor and sets the cursor handle to NULL. It releases all memory associated with the cursor. The specification for the procedure is, PROCEDURE DBMS_SQL.CLOSE_CURSOR (c IN OUT INTEGER); where c is the handle or pointer to the cursor that was originally returned by a call to OPEN_CURSOR. The parameter is IN OUT because once the cursor is closed, the pointer is set to NULL. If you try to close a cursor that is not open or that is not a valid cursor ID, this program will raise the INVALID_CURSOR exception. You might consider building a "wrapper" for CLOSE_CURSOR to avoid [Appendix A] What's on the Companion Disk? 2.3.9 Closing the Cursor 76 this exception. CREATE OR REPLACE PROCEDURE closeif (c IN OUT INTEGER) IS BEGIN IF DBMS_SQL.IS_OPEN (c) THEN DBMS_SQL.CLOSE_CURSOR (c); END IF; END; / 2.3.10 Checking Cursor Status Several functions allow you to check the status of a cursor. 2.3.10.1 The DBMS_SQL.LAST_ERROR_POSITION function The LAST_ERROR_POSITION function returns the byte offset in the SQL statement where the error occurred. The first character in the statement is at position 0. This function offers the same kind of feedback SQL*Plus offers you when it displays a syntax or value error while executing a SQL statement: it displays the problematic text with an asterisk (*) under the character that caused the problem. Here's the specification for this function: FUNCTION DBMS_SQL.LAST_ERROR RETURN INTEGER; You must call this function immediately after a call to EXECUTE or EXECUTE_AND_FETCH in order to obtain meaningful results. The following script demonstrates when and how this function's return value can come in handy: /* Filename on companion disk: file errpos.sql */* DECLARE cur BINARY_INTEGER := DBMS_SQL.OPEN_CURSOR; errpos BINARY_INTEGER; fdbk BINARY_INTEGER; BEGIN DBMS_SQL.PARSE (cur, 'SELECT empno, ^a FROM emp', DBMS_SQL.NATIVE); DBMS_SQL.DEFINE_COLUMN (cur, 1, 1); fdbk := DBMS_SQL.EXECUTE_AND_FETCH (cur, false); DBMS_SQL.CLOSE_CURSOR (cur); EXCEPTION WHEN OTHERS THEN errpos := DBMS_SQL.LAST_ERROR_POSITION; DBMS_OUTPUT.PUT_LINE (SQLERRM || ' at pos ' || errpos); DBMS_SQL.CLOSE_CURSOR (cur); END; / When I run this script in SQL*Plus, I get the following output: SQL> @errpos ORA−00936: missing expression at pos 14 One of the greatest frustrations with dynamic SQL is getting your string strung together improperly. It is very easy to introduce syntax errors. The DBMS_SQL.LAST_ERROR_POSITION function can be a big help in uncovering the source of your problem. NOTE: Some readers may be wondering why I declared a local variable called errpos and assigned the value to it before calling DBMS_OUTPUT.PUT_LINE to examine the error. [Appendix A] What's on the Companion Disk? 2.3.10 Checking Cursor Status 77 The reason (discovered by Eric Givler, ace technical reviewer for this book) is that if I do not grab the value from this function before calling SQLERRM, the function will return 0 instead of the 14 for which I am looking. If my exception section looks, for example, as follows, WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE (SQLERRM || ' at pos ' || DBMS_SQL.LAST_ERROR_POSITION); DBMS_SQL.CLOSE_CURSOR (cur); then the output from running the program will become: SQL> @errpos ORA−00936: missing expression at pos 0 Why does this happen? The SQLERRM function must be executing an implicit SQL statement (probably a query!). This action resets the values returned by this DBMS_SQL function, since it is tied to the underlying, generic implicit cursor attribute. 2.3.10.2 The DBMS_SQL.LAST_ROW_COUNT function The LAST_ROW_COUNT function returns the total number of rows fetched at that point. This function corresponds to the %ROWCOUNT attribute of a normal, static cursor in PL/SQL. Here's the specification for this function: FUNCTION DBMS_SQL.LAST_ROW_COUNT RETURN INTEGER; You must call this function immediately after a call to EXECUTE_AND_FETCH or FETCH_ROWS in order to obtain meaningful results. You will most likely use this function when fetching from within a loop: CREATE OR REPLACE PROCEDURE show_n_emps (lim IN INTEGER) IS cur PLS_INTEGER := DBMS_SQL.OPEN_CURSOR; fdbk PLS_INTEGER; v_ename emp.ename%TYPE; BEGIN DBMS_SQL.PARSE (cur, 'SELECT ename FROM emp', DBMS_SQL.NATIVE); DBMS_SQL.DEFINE_COLUMN (cur, 1, v_ename, 100); fdbk := DBMS_SQL.EXECUTE (cur); LOOP EXIT WHEN DBMS_SQL.FETCH_ROWS (cur) = 0; IF DBMS_SQL.LAST_ROW_COUNT <= lim THEN DBMS_SQL.COLUMN_VALUE (cur, 1, v_ename); DBMS_OUTPUT.PUT_LINE (v_ename); ELSE /* Hit maximum. Display message and exit. */ DBMS_OUTPUT.PUT_LINE ('Displayed ' || TO_CHAR (lim) || ' employees.'); EXIT; END IF; END LOOP; DBMS_SQL.CLOSE_CURSOR (cur); END; / [Appendix A] What's on the Companion Disk? 2.3.10 Checking Cursor Status 78 2.3.10.3 The DBMS_SQL.LAST_ROW_ID function The LAST_ROW_ID function returns the ROWID of the row fetched most recently. The specification for this function is as follows: FUNCTION DBMS_SQL.LAST_ROW_ID RETURN ROWID; You must call this function immediately after a call to EXECUTE_AND_FETCH or FETCH_ROWS in order to obtain meaningful results. This function is useful mostly for debugging purposes and perhaps to log which records have been affected. 2.3.10.4 The DBMS_SQL.LAST_SQL_FUNCTION_CODE function The LAST_SQL_FUNCTION_CODE function returns the SQL function code for the SQL statement. The specification for this function is as follows: FUNCTION DBMS_SQL.LAST_SQL_FUNCTION_CODE RETURN INTEGER; You must call this function immediately after a call to EXECUTE_AND_FETCH or EXECUTE in order to obtain meaningful results. It will tell you which type of SQL statement was executed. The SQL function codes are listed in Table 2.3. Table 2.3: SQL Function Codes Code SQL Function Code SQL Function Code SQL Function 01 CREATE TABLE 35 LOCK 69 (NOT USED) 02 SET ROLE 36 NOOP 70 ALTER RESOURCE COST 03 INSERT 37 RENAME 71 CREATE SNAPSHOT LOG 04 SELECT 38 COMMENT 72 ALTER SNAPSHOT LOG 05 UPDATE 39 AUDIT 73 DROP SNAPSHOT LOG 06 DROP ROLE 40 NO AUDIT 74 CREATE SNAPSHOT 07 DROP VIEW 41 ALTER INDEX 75 ALTER SNAPSHOT 08 DROP TABLE 42 CREATE EXTERNAL DATABASE 76 DROP SNAPSHOT 09 DELETE 43 DROP EXTERNAL DATABASE 77 CREATE TYPE 10 CREATE VIEW 44 CREATE DATABASE 78 DROP TYPE 11 DROP USER 45 ALTER DATABASE 79 ALTER ROLE 12 CREATE ROLE 46 CREATE ROLLBACK SEGMENT 80 ALTER TYPE 13 CREATE SEQUENCE 47 ALTER ROLLBACK SEGMENT 81 CREATE TYPE BODY [Appendix A] What's on the Companion Disk? 2.3.10 Checking Cursor Status 79 14 ALTER SEQUENCE 48 DROP ROLLBACK SEGMENT 82 ALTER TYPE BODY 15 (NOT USED) 49 CREATE TABLESPACE 83 DROP TYPE BODY 16 DROP SEQUENCE 50 ALTER TABLESPACE 84 DROP LIBRARY 17 CREATE SCHEMA 51 DROP TABLESPACE 85 TRUNCATE TABLE 18 CREATE CLUSTER 52 ALTER SESSION 86 TRUNCATE CLUSTER 19 CREATE USER 53 ALTER USER 87 CREATE BITMAPFILE 20 CREATE INDEX 54 COMMIT (WORK) 88 ALTER VIEW 21 DROP INDEX 55 ROLLBACK 89 DROP BITMAPFILE 22 DROP CLUSTER 56 SAVEPOINT 90 SET CONSTRAINTS 23 VALIDATE INDEX 57 CREATE CONTROL FILE 91 CREATE FUNCTION 24 CREATE PROCEDURE 58 ALTER TRACING 92 ALTER FUNCTION 25 ALTER PROCEDURE 59 CREATE TRIGGER 93 DROP FUNCTION 26 ALTER TABLE 60 ALTER TRIGGER 94 CREATE PACKAGE 27 EXPLAIN 61 DROP TRIGGER 95 ALTER PACKAGE 28 GRANT 62 ANALYZE TABLE 96 DROP PACKAGE 29 REVOKE 63 ANALYZE INDEX 97 CREATE PACKAGE BODY 30 CREATE SYNONYM 64 ANALYZE CLUSTER 98 ALTER PACKAGE BODY 31 DROP SYNONYM 65 CREATE PROFILE 99 DROP PACKAGE BODY 32 ALTER SYSTEM SWITCH LOG 66 DROP PROFILE 157 CREATE DIRECTORY 33 SET TRANSACTION 67 ALTER PROFILE 158 DROP DIRECTORY 34 PL/SQL EXECUTE 68 DROP PROCEDURE 159 CREATE LIBRARY 2.3.11 Describing Cursor Columns With PL/SQL8, you can now obtain information about the structure of the columns of your dynamic cursor. 2.3.11.1 The DBMS_SQL.DESCRIBE_COLUMNS procedure The DESCRIBE_COLUMNS procedure obtains information about your dynamic cursor. Here is the header: PROCEDURE DBMS_SQL.DESCRIBE_COLUMNS (c IN INTEGER ,col_cnt OUT INTEGER ,desc_t OUT DBMS_SQL.DESC_TAB); The parameters for the DESCRIBE_COLUMNS procedure are summarized in the following table. Parameter Description c The pointer to the cursor. col_cnt The number of columns in the cursor, which equals the number of rows defined in the PL/SQL table. [Appendix A] What's on the Companion Disk? 2.3.11 Describing Cursor Columns 80

Ngày đăng: 07/07/2014, 00:20

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

  • Đang cập nhật ...

TÀI LIỆU LIÊN QUAN