Oracle Database 10g The Complete Reference phần 5 ppsx

135 277 0
Oracle Database 10g The Complete Reference phần 5 ppsx

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

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

RADIUS AREA 3 28.27 4 50.27 5 78.54 6 113.1 Because the area value for a Radius value of 6 exceeds 100, no further Radius values are processed and the PL/SQL block completes. Simple Cursor Loops You can use the attributes of a cursor—such as whether or not any rows are left to be fetched— as the exit criteria for a loop. In the following example, a cursor is executed until no more rows are returned by the query. To determine the status of the cursor, the cursor’s attributes are checked. Cursors have four attributes you can use in your program: %FOUND A record can be fetched from the cursor. %NOTFOUND No more records can be fetched from the cursor. %ISOPEN The cursor has been opened. %ROWCOUNT The number of rows fetched from the cursor so far. The %FOUND, %NOTFOUND, and %ISOPEN cursor attributes are Booleans; they are set to either TRUE or FALSE. Because they are Boolean attributes, you can evaluate their settings without explicitly matching them to values of TRUE or FALSE. For example, the following command will cause an exit to occur when rad_cursor%NOTFOUND is TRUE: exit when rad_cursor%NOTFOUND; In the following listing, a simple loop is used to process multiple rows from a cursor: declare pi constant NUMBER(9,7) := 3.1415927; area NUMBER(14,2); cursor rad_cursor is select * from RADIUS_VALS; rad_val rad_cursor%ROWTYPE; begin open rad_cursor; loop fetch rad_cursor into rad_val; exit when rad_cursor%NOTFOUND; area := pi*power(rad_val.radius,2); insert into AREAS values (rad_val.radius, area); end loop; close rad_cursor; end; / Chapter 29: An Introduction to PL/SQL 523 ORACLE Series TIGHT / Oracle Database 10g: TCR / Loney / 225351-7 / Chapter 29 Blind Folio 29:523 P:\010Comp\Oracle8\351-7\CD\Ventura\book.vp Friday, August 13, 2004 1:49:47 PM Color profile: Generic CMYK printer profile Composite Default screen 524 Part IV: PL/SQL ORACLE Series TIGHT / Oracle Database 10g: TCR / Loney / 225351-7 / Chapter 29 Blind Folio 29:524 The loop section of the PL/SQL block uses values from the RADIUS_VALS table as its input. Instead of basing the exit criteria on the Area value, the cursor’s %NOTFOUND attribute is checked. If no more rows are found in the cursor, then %NOTFOUND will be TRUE—and, therefore, the loop will be exited. The commented version of the loop is shown in the following listing: loop /* Within the loop, fetch a record. */ fetch rad_cursor into rad_val; /* If the fetch attempt reveals no more */ /* records in the cursor, then exit the loop. */ exit when rad_cursor%NOTFOUND; /* If the fetch attempt returned a record, */ /* then process the Radius value and insert */ /* a record into the AREAS table. */ area := pi*power(rad_val.radius,2); insert into AREAS values (rad_val.radius, area); /* Signal the end of the loop. */ end loop; When the preceding PL/SQL block is executed, every record in the RADIUS_VALS table will be processed by the loop. So far, the RADIUS_VALS table only contains one record—a Radius value of 3. NOTE Prior to executing the PL/SQL block for this section, add two new Radius values—4 and 10—to the RADIUS_VALS table. The following listing shows the addition of the new records to the RADIUS_VALS table: insert into RADIUS_VALS values (4); insert into RADIUS_VALS values (10); commit; select * from RADIUS_VALS order by Radius; RADIUS 3 4 10 Once the new records have been added to the RADIUS_VALS table, execute the PL/SQL block shown earlier in this section. The output of the PL/SQL block is shown in the following listing: select * from AREAS order by Radius; P:\010Comp\Oracle8\351-7\CD\Ventura\book.vp Friday, August 13, 2004 1:49:47 PM Color profile: Generic CMYK printer profile Composite Default screen Chapter 29: An Introduction to PL/SQL 525 ORACLE Series TIGHT / Oracle Database 10g: TCR / Loney / 225351-7 / Chapter 29 Blind Folio 29:525 RADIUS AREA 3 28.27 4 50.27 10 314.16 The query of the AREAS table shows that every record in the RADIUS_VALS table was fetched from the cursor and processed. When there were no more records to process in the cursor, the loop was exited and the PL/SQL block completed. FOR Loops A simple loop executes until an exit condition is met, whereas a FOR loop executes a specified number of times. An example of a FOR loop is shown in the following listing. The FOR loop’s start is indicated by the keyword for, followed by the criteria used to determine when the processing is complete and the loop can be exited. Because the number of times the loop is executed is set when the loop is begun, an exit command isn’t needed within the loop. In the following example, the areas of circles are calculated based on Radius values ranging from 1 through 7, inclusive. delete from AREAS; declare pi constant NUMBER(9,7) := 3.1415927; radius INTEGER(5); area NUMBER(14,2); begin for radius in 1 7 loop area := pi*power(radius,2); insert into AREAS values (radius, area); end loop; end; / The steps involved in processing the loop are shown in the following commented listing: /* Specify the criteria for the number of loop */ /* executions. */ for radius in 1 7 loop /* Calculate the area using the current Radius */ /* value. */ area := pi*power(radius,2); /* Insert the area and radius values into the AREAS */ /* table. */ insert into AREAS values (radius, area); /* Signal the end of the loop. */ end loop; Note that there is no line that says radius := radius+1; P:\010Comp\Oracle8\351-7\CD\Ventura\book.vp Friday, August 13, 2004 1:49:48 PM Color profile: Generic CMYK printer profile Composite Default screen in the FOR loop. Because the specification of the loop specifies for radius in 1 7 loop the Radius values are already specified. For each value, all the commands within the loop are executed (these commands can include other conditional logic, such as if conditions). Once the loop has completed processing a Radius value, the limits on the for clause are checked, and either the next Radius value is used or the loop execution is complete. Sample output from the FOR loop execution is shown in the following listing: select * from AREAS order by Radius; RADIUS AREA 1 3.14 2 12.57 3 28.27 4 50.27 5 78.54 6 113.1 7 153.94 7 rows selected. Cursor FOR Loops Whereas a FOR loop executes a specified number of times, a Cursor FOR loop uses the results of a query to dynamically determine the number of times the loop is executed. In a Cursor FOR loop, the opening, fetching, and closing of cursors is performed implicitly; you do not need to explicitly specify these actions. The following listing shows a Cursor FOR loop that queries the RADIUS_VALS table and inserts records into the AREAS table: delete from AREAS; declare pi constant NUMBER(9,7) := 3.1415927; area NUMBER(14,2); cursor rad_cursor is select * from RADIUS_VALS; begin for rad_val in rad_cursor loop area := pi*power(rad_val.radius,2); insert into AREAS values (rad_val.radius, area); end loop; end; / 526 Part IV: PL/SQL ORACLE Series TIGHT / Oracle Database 10g: TCR / Loney / 225351-7 / Chapter 29 Blind Folio 29:526 P:\010Comp\Oracle8\351-7\CD\Ventura\book.vp Friday, August 13, 2004 1:49:49 PM Color profile: Generic CMYK printer profile Composite Default screen Chapter 29: An Introduction to PL/SQL 527 ORACLE Series TIGHT / Oracle Database 10g: TCR / Loney / 225351-7 / Chapter 29 Blind Folio 29:527 In a Cursor FOR loop, there is no open or fetch command. The command for rad_val in rad_cursor implicitly opens the rad_cursor cursor and fetches a value into the rad_val variable. When no more records are in the cursor, the loop is exited and the cursor is closed. In a Cursor FOR loop, there is no need for a close command. Note that rad_val is not explicitly declared in the block. The loop portion of the PL/SQL block is shown in the following listing, with comments to indicate the flow of control. The loop is controlled by the existence of a fetchable record in the rad_ cursor cursor. There is no need to check the cursor’s %NOTFOUND attribute—that is automated via the Cursor FOR loop. /* If a record can be fetched from the cursor, */ /* then fetch it into the rad_val variable. If */ /* no rows can be fetched, then skip the loop. */ for rad_val in rad_cursor /* Begin the loop commands. */ loop /* Calculate the area based on the Radius value */ /* and insert a record into the AREAS table. */ area := pi*power(rad_val.radius,2); insert into AREAS values (rad_val.radius, area); /* Signal the end of the loop commands. */ end loop; Sample output is shown in the following listing; for this example, the RADIUS_VALS table has three records, with Radius values of 3, 4, and 10: select * from RADIUS_VALS order by Radius; RADIUS 3 4 10 The execution of the PL/SQL block with the Cursor FOR loop will generate the following records in the AREAS table: select * from AREAS order by Radius; RADIUS AREA 3 28.27 4 50.27 10 314.16 P:\010Comp\Oracle8\351-7\CD\Ventura\book.vp Friday, August 13, 2004 1:49:50 PM Color profile: Generic CMYK printer profile Composite Default screen WHILE Loops A WHILE loop is processed until an exit condition is met. Instead of the exit condition being specified via an exit command within the loop, the exit condition is specified in the while command that initiates the loop. In the following listing, a WHILE loop is created so that multiple Radius values will be processed. If the current value of the Radius variable meets the while condition in the loop’s specification, then the loop’s commands are processed. Once a Radius value fails the while condition in the loop’s specification, the loop’s execution is terminated: delete from AREAS; declare pi constant NUMBER(9,7) := 3.1415927; radius INTEGER(5); area NUMBER(14,2); begin radius := 3; while radius<=7 loop area := pi*power(radius,2); insert into AREAS values (radius, area); radius := radius+1; end loop; end; / The WHILE loop is similar in structure to the simple loop because it terminates based on a variable’s value. The following listing shows the steps involved in the loop, with embedded comments: /* Set an initial value for the Radius variable. */ radius := 3; /* Establish the criteria for the termination of */ /* the loop. If the condition is met, execute the */ /* commands within the loop. If the condition is */ /* not met, then terminate the loop. */ while radius<=7 /* Begin the commands to be executed. */ loop /* Calculate the area based on the current */ /* Radius value and insert a record in the */ /* AREAS table. */ area := pi*power(radius,2); insert into AREAS values (radius, area); /* Set a new value for the Radius variable. The */ /* new value of Radius will be evaluated against */ /* the termination criteria and the loop commands */ /* will be executed for the new Radius value or */ /* the loop will terminate. */ 528 Part IV: PL/SQL ORACLE Series TIGHT / Oracle Database 10g: TCR / Loney / 225351-7 / Chapter 29 Blind Folio 29:528 P:\010Comp\Oracle8\351-7\CD\Ventura\book.vp Friday, August 13, 2004 1:49:50 PM Color profile: Generic CMYK printer profile Composite Default screen radius := radius+1; /* Signal the end of the commands within the loop. */ end loop; When executed, the PL/SQL block in the previous listing will generate records in the AREAS table. The output of the PL/SQL block is shown in the following listing: select * from AREAS order by Radius; RADIUS AREA 3 28.27 4 50.27 5 78.54 6 113.1 7 153.94 Because of the value assigned to the Radius variable prior to the loop, the loop is forced to execute at least once. You should verify that your variable assignments meet the conditions used to limit the loop executions. CASE Statements You can use case statements to control the branching logic within your PL/SQL blocks. For example, you can use case statements to assign values conditionally or to transform values prior to inserting them. In the following example, case expressions use the Radius values to determine which rows to insert into the AREAS table: declare pi constant NUMBER(9,7) := 3.1415927; area NUMBER(14,2); cursor rad_cursor is select * from RADIUS_VALS; rad_val rad_cursor%ROWTYPE; begin open rad_cursor; loop fetch rad_cursor into rad_val; exit when rad_cursor%NOTFOUND; area := pi*power(rad_val.radius,2); case when rad_val.Radius = 3 then insert into AREAS values (rad_val.radius, area); when rad_val.Radius = 4 then insert into AREAS values (rad_val.radius, area); when rad_val.Radius = 10 Chapter 29: An Introduction to PL/SQL 529 ORACLE Series TIGHT / Oracle Database 10g: TCR / Loney / 225351-7 / Chapter 29 Blind Folio 29:529 P:\010Comp\Oracle8\351-7\CD\Ventura\book.vp Friday, August 13, 2004 1:49:51 PM Color profile: Generic CMYK printer profile Composite Default screen then insert into AREAS values (0, 0); else raise CASE_NOT_FOUND; end case; end loop; close rad_cursor; end; / This block generates the following output. When the Radius value is 10, the case clause inserts a row with the Radius and Area values both set to 0: select * from AREAS; RADIUS AREA 3 28.27 4 50.27 0 0 The keyword case begins the clause: case when rad_val.Radius = 3 then insert into AREAS values (rad_val.radius, area); The when clauses are evaluated sequentially. The else keyword within the case clause works similarly to the else keyword within an if-then clause. If you omit the else keyword, PL/SQL adds the following implicit else clause: else raise CASE_NOT_FOUND; The end case clause ends the case clause. The case clause is commonly used to translate lists of values to their descriptions, as in the case of the bookshelf category names. The following listing shows how CategoryName values can be translated to other values as part of SQL commands: case CategoryName when 'ADULTFIC' then 'Adult Fiction' when 'ADULTNF' then 'Adult Nonfiction' when 'ADULTREF' then 'Adult Reference' when 'CHILDRENFIC' then 'Children Fiction' when 'CHILDRENNF' then 'Children Nonfiction' when 'CHILDRENPIC' then 'Children Picturebook' else CategoryName end See Chapter 16 for examples of the complex uses of case. 530 Part IV: PL/SQL ORACLE Series TIGHT / Oracle Database 10g: TCR / Loney / 225351-7 / Chapter 29 Blind Folio 29:530 P:\010Comp\Oracle8\351-7\CD\Ventura\book.vp Friday, August 13, 2004 1:49:51 PM Color profile: Generic CMYK printer profile Composite Default screen Exception Handling Section When user-defined or system-related exceptions (errors) are encountered, the control of the PL/SQL block shifts to the Exception Handling section. Within the Exception Handling section, the when clause is used to evaluate which exception is to be “raised”—that is, executed. If an exception is raised within the Executable Commands section of your PL/SQL block, the flow of commands immediately leaves the Executable Commands section and searches the Exception Handling section for an exception matching the error encountered. PL/SQL provides a set of system-defined exceptions and allows you to add your own exceptions. Examples of user- defined exceptions are shown in Chapters 30 and 31. The Exception Handling section always begins with the keyword exception, and it precedes the end command that terminates the Executable Commands section of the PL/SQL block. The placement of the Exception Handling section within the PL/SQL block is shown in the following listing: declare <declarations section> begin <executable commands> exception <exception handling> end; The Exception Handling section of a PL/SQL block is optional—none of the PL/SQL blocks shown previously in this chapter included an Exception Handling section. However, the examples shown in this chapter have been based on a very small set of known input values with very limited processing performed. In the following listing, the simple loop for calculating the area of a circle is shown, with two modifications. A new variable named some_variable is declared in the Declarations section, and a calculation to determine the variable’s value is created in the Executable Commands section. declare pi constant NUMBER(9,7) := 3.1415927; radius INTEGER(5); area NUMBER(14,2); some_variable NUMBER(14,2); begin radius := 3; loop some_variable := 1/(radius-4); area := pi*power(radius,2); insert into AREAS values (radius, area); radius := radius+1; exit when area >100; end loop; end; / Chapter 29: An Introduction to PL/SQL 531 ORACLE Series TIGHT / Oracle Database 10g: TCR / Loney / 225351-7 / Chapter 29 Blind Folio 29:531 P:\010Comp\Oracle8\351-7\CD\Ventura\book.vp Friday, August 13, 2004 1:49:52 PM Color profile: Generic CMYK printer profile Composite Default screen [...]... Series TIGHT / Oracle Database 10g: TCR / Loney / 2 253 51-7 / Chapter 31 Blind Folio 31 :55 5 CHAPTER 31 Procedures, Functions, and Packages P:\010Comp \Oracle8 \ 351 -7\CD\Ventura\book.vp Friday, August 13, 2004 1 :50 : 05 PM Color profile: Generic CMYK printer profile Composite Default screen 55 6 Part IV: ORACLE Series TIGHT / Oracle Database 10g: TCR / Loney / 2 253 51-7 / Chapter 31 Blind Folio 31 :55 6 PL/SQL ophisticated... TIGHT / Oracle Database 10g: TCR / Loney / 2 253 51-7 / Chapter 30 Blind Folio 30 :53 5 CHAPTER 30 Triggers P:\010Comp \Oracle8 \ 351 -7\CD\Ventura\book.vp Friday, August 13, 2004 1:49 :54 PM Color profile: Generic CMYK printer profile Composite Default screen 53 6 Part IV: ORACLE Series TIGHT / Oracle Database 10g: TCR / Loney / 2 253 51-7 / Chapter 30 Blind Folio 30 :53 6 PL/SQL A trigger defines an action the database. .. P:\010Comp \Oracle8 \ 351 -7\CD\Ventura\book.vp Friday, August 13, 2004 1 :50 :04 PM 55 3 Color profile: Generic CMYK printer profile Composite Default screen P:\010Comp \Oracle8 \ 351 -7\CD\Ventura\book.vp Friday, August 13, 2004 1 :50 : 05 PM ORACLE Series TIGHT / Oracle Database 10g: TCR / Loney / 2 253 51-7 / Chapter 30 Blind Folio 30 :55 4 Color profile: Generic CMYK printer profile Composite Default screen ORACLE. .. understand First, the trigger is named: create or replace trigger BOOKSHELF_BEF_UPD_ROW P:\010Comp \Oracle8 \ 351 -7\CD\Ventura\book.vp Friday, August 13, 2004 1:49 :56 PM 53 9 Color profile: Generic CMYK printer profile Composite Default screen 54 0 Part IV: ORACLE Series TIGHT / Oracle Database 10g: TCR / Loney / 2 253 51-7 / Chapter 30 Blind Folio 30 :54 0 PL/SQL The name of the trigger contains the name of the table... processing from the application (on the client) to the database (on the server) may dramatically improve performance ■ Because the procedural code is stored within the database and is fairly static, you may also benefit from the reuse of the same queries within the database The Shared SQL Area in the System Global Area (SGA) will store the parsed versions of the executed commands Thus, the second time... UPDATING In this case, the trigger checks to see if the record is being inserted into the BOOKSHELF table If it is, then the first part of the trigger body is executed The INSERTING portion of the trigger body inserts the new values of the record into the BOOKSHELF_AUDIT table begin if INSERTING then P:\010Comp \Oracle8 \ 351 -7\CD\Ventura\book.vp Friday, August 13, 2004 1:49 :58 PM 54 1 Color profile: Generic... 55 8 Part IV: ORACLE Series TIGHT / Oracle Database 10g: TCR / Loney / 2 253 51-7 / Chapter 31 Blind Folio 31 :55 8 PL/SQL When you execute remote procedures, the name of a database link must be specified (see Chapter 23 for information on database links) The name of the database link must immediately follow the procedure’s name and precede the variables, as shown in the following example: execute NEW_BOOK@REMOTE_CONNECT('ONCE... P:\010Comp \Oracle8 \ 351 -7\CD\Ventura\book.vp Friday, August 13, 2004 1:49 :53 PM 53 3 Color profile: Generic CMYK printer profile Composite Default screen P:\010Comp \Oracle8 \ 351 -7\CD\Ventura\book.vp Friday, August 13, 2004 1:49 :53 PM ORACLE Series TIGHT / Oracle Database 10g: TCR / Loney / 2 253 51-7 / Chapter 29 Blind Folio 29 :53 4 Color profile: Generic CMYK printer profile Composite Default screen ORACLE. .. of performing the actions that invoked the trigger For example, you could use an INSTEAD OF trigger on a view to redirect inserts P:\010Comp \Oracle8 \ 351 -7\CD\Ventura\book.vp Friday, August 13, 2004 1:49 :55 PM 53 7 Color profile: Generic CMYK printer profile Composite Default screen 53 8 Part IV: ORACLE Series TIGHT / Oracle Database 10g: TCR / Loney / 2 253 51-7 / Chapter 30 Blind Folio 30 :53 8 PL/SQL into... WHEN weekend_error THEN RAISE_APPLICATION_ERROR (-20001, P:\010Comp \Oracle8 \ 351 -7\CD\Ventura\book.vp Friday, August 13, 2004 1 :50 :01 PM 54 5 Color profile: Generic CMYK printer profile Composite Default screen 54 6 Part IV: ORACLE Series TIGHT / Oracle Database 10g: TCR / Loney / 2 253 51-7 / Chapter 30 Blind Folio 30 :54 6 PL/SQL 'Deletions not allowed on weekends'); WHEN not_library_user THEN RAISE_APPLICATION_ERROR . screen 54 0 Part IV: PL/SQL ORACLE Series TIGHT / Oracle Database 10g: TCR / Loney / 2 253 51-7 / Chapter 30 Blind Folio 30 :54 0 The name of the trigger contains the name of the table it acts upon and the. Series TIGHT / Oracle Database 10g: TCR / Loney / 2 253 51-7 / Chapter 29 Blind Folio 29 :52 5 RADIUS AREA 3 28.27 4 50 .27 10 314.16 The query of the AREAS table shows that every record in the RADIUS_VALS. to PL/SQL 52 9 ORACLE Series TIGHT / Oracle Database 10g: TCR / Loney / 2 253 51-7 / Chapter 29 Blind Folio 29 :52 9 P:10Comp Oracle8 351 -7CDVenturaook.vp Friday, August 13, 2004 1:49 :51 PM Color

Ngày đăng: 08/08/2014, 20:21

Tài liệu cùng người dùng

Tài liệu liên quan