Previous | Table of Contents | Next

Page 417

ANALYSIS The order is to first use OPEN_CURSOR in line 14 to retrieve an assigned cursor ID. You then assign the anonymous PL/SQL block to a variable called v_MatchRecord in line 15. This string codes the PL/SQL block with proper syntax. Before, in the examples of queries and DDL and DML statements, you had to remove the semicolon. You can see that now the block of SQL statements in lines 16 to 18 ends in a semicolon. You then call DBMS_SQL.PARSE in line 21 to check for syntax errors. After binding the appropriate variables in lines 24 and 25, you execute the anonymous PL/SQL block in line 27. You then retrieve from the buffer the values and store them into the variables using DBMS_SQL.VARIABLE_VALUE in lines 31 and 32. The output is displayed in line 35 with DBMS_OUTPUT.PUT_LINE. Finally, after the entire process has completed, in line 42 you close the cursor with CLOSE_CURSOR.

Now you can experiment to show how the buffer truly operates. You will change the code from Listing 17.4 to select values from MyRow = 4. See Listing 17.5 for the change and then execute.

INPUTListing 17.5. Errors with anonymous blocks.

 1: DECLARE
 2: /* This procedure calls an anonymous block which performs a
 3:    query to look up the description for the row id value = 4.
 4:    This demonstrates the use of an anonymous PL/SQL block
 5:    within PL/SQL  */
 6:
 7:      v_CursorID  NUMBER; -- Variable assigned to value from OPEN_CURSOR
 8:      v_MatchRecord  VARCHAR2(500); -- SQL stored as string to select one
         Ârecord
 9:      v_NUMRows  INTEGER; -- Number of rows processed - of no use
10:      v_MyNum INTEGER;
11:      v_MyText VARCHAR2(50);
12:
13: BEGIN
14:      v_CursorID := DBMS_SQL.OPEN_CURSOR; -- Get the Cursor ID
15:      v_MatchRecord := `BEGIN -- Start of Anonymous PL/SQL Block
16:                           SELECT MyRow,MyDesc
17:                              INTO :MyRow, :MyText FROM MyTable
18:                              WHERE MyRow = 4; -- Notice has ending semicolon
19:                        END;'; -- End of Anonymous PL/SQL Block
20:
21:      DBMS_SQL.PARSE(v_CursorID,v_MatchRecord,DBMS_SQL.V7);
22:           /* Perform syntax error checking */
23:
24:      DBMS_SQL.BIND_VARIABLE(v_CursorID, `:MyRow',v_MyNum);
25:      DBMS_SQL.BIND_VARIABLE(v_CursorID, `:MyText',v_MyText,50);
26:
27:      v_NumRows := DBMS_SQL.EXECUTE(v_CursorID);
28:           /* Execute the SQL code  */
29:
30: 
                                                 continues

Page 418

Listing 17.5. continued

31:      DBMS_SQL.VARIABLE_VALUE(v_CursorId,':MyRow',v_MyNum);
32:      DBMS_SQL.VARIABLE_VALUE(v_CursorId,':MyText',v_MyText);
33:      /* Defines variables to hold output */
34:
35:      DBMS_OUTPUT.PUT_LINE(v_MyNum || ` ` || v_MyText);
36:
37:
38: EXCEPTION
39:      WHEN OTHERS THEN
40:                RAISE; -- raise if some other unknown error
41:
42:      DBMS_SQL.CLOSE_CURSOR(v_CursorID); -- Close the cursor
43:
44: END; -- End PL/SQL block

When you execute the code, your output will appear as

OUTPUT
      ORA-01422: exact fetch returns more than requested number of rows
      ORA-06512: at line 30
ANALYSIS Why did you receive the error? When using anonymous blocks, the buffer will only hold one row of data. If you recall, you have two records with a value of 4, which are selected by the SQL statements in lines 16 to 18. Because you can't use FETCH_ROWS, but can only return one row, the error occurs. This is the primary difference between queries and anonymous blocks.

Error Handling

In addition to exceptions, there are many other ways to handle errors with the DBMS_SQL package. You can check to see if the cursor is open with IS_OPEN. You can also check to see information provided by the DBMS_SQL package concerning the last set of rows retrieved with the FETCH_ROWS function with the functions LAST_ROW_COUNT and LAST_ROW_ID. Other functions that provide information on errors are LAST_ERROR_POSITION and LAST_SQL_FUNCTION_CODE.

IS_OPEN

The IS_OPEN function enables you to see if a cursor is open. Some possible uses for this are to check for an open cursor, and if still open, close the cursor. You can also use this to reopen a closed cursor.

The Syntax for the IS_OPEN Function

FUNCTION IS_OPEN(cursor_id IN INTEGER) RETURN BOOLEAN;

The cursor_id parameter is the cursor ID assigned from calling the OPEN_CURSOR function. If the cursor is open, it returns true; otherwise, if the cursor is closed, it passes the value false.

Page 419

LAST_ROW_COUNT

The LAST_ROW_COUNT function passes the total number of rows fetched from the cursor to
date. This should be called immediately after FETCH_ROWS to receive accurate results. The syntax for the LAST_ROW_COUNT function is as follows:

       FUNCTION LAST_ROW_COUNT RETURN INTEGER;

If the call is made before FETCH_ROWS, you will receive a value of zero.

LAST_ROW_ID

The LAST_ROW_ID function returns the ROWID of the last row processed. Again, this should be called immediately after FETCH_ROWS for it to be of any usefulness. The syntax for the LAST_ROW_ID function is as follows:

      FUNCTION LAST_ROW_ID RETURN ROWID;

Testing LAST_ROW_ID and LAST_ROW_COUNT
Enter and execute the code in Listing 17.6 to test these two functions. Make sure that you have entered SET SERVEROUTPUT ON at the SQL*Plus prompt.

INPUTListing 17.6. Checking the progress of fetched rows.

 1: DECLARE
 2: /* The purpose of this PL/SQL block is to demonstrate
 3:    executing queries within PL/SQL through the use of the
 4:    DBMS_SQL package.  We will simply display the output to
 5:    screen with the DBMS_OUTPUT package.  We also demonstrate
 6:    the use of tracking the progress of fetching rows*/
 7:
 8:      v_CursorID  NUMBER; -- Variable assigned to value from OPEN_CURSOR
 9:      v_SelectRecords  VARCHAR2(500); -- SQL stored as string to select
         Ârecords
10:      v_NUMRows  INTEGER; -- Number of rows processed - of no use
11:      v_MyNum INTEGER;
12:      v_MyText VARCHAR2(50);
13:      v_MyROWID ROWID;
14:      v_TotRow INTEGER;
15:
16: BEGIN
17:      v_CursorID := DBMS_SQL.OPEN_CURSOR; -- Get the Cursor ID
18:      v_SelectRecords := `SELECT * from MyTable'; -- SQL to view records
19:
20:
21:      DBMS_SQL.PARSE(v_CursorID,v_SelectRecords,DBMS_SQL.V7);
22:           /* Perform syntax error checking */
23:
24:
25:      DBMS_SQL.DEFINE_COLUMN(v_CursorID,1,v_MyNum);
26:      DBMS_SQL.DEFINE_COLUMN(v_CursorID,2,v_MyText,50);
27: 
                                                 continues

Previous | Table of Contents | Next

Используются технологии uCoz