Procedures, Packages, Errors, and Exceptions 1917 The Syntax for the CREATE PROCEDURECommand CREATE OR REPLACE PROCEDURE procedure_name arguments AS [pl/sql body code] In this syntax, th
Trang 1Using Oracle’s Built-In Functions 177
6
TABLE 6.9 Masks Used with the ROUND and TRUNC Functions
Mask Options Description
CC , SCC Rounds or truncates to the century
YYYY , SYYYY , YEAR , Truncates to the year or rounds up to the next year after July 1st
SYEAR , YYY , YY , Y IYYY , IYY , IY , I ISO year
Q Truncates to the quarter or rounds up to the nearest quarter on or after the
16th day of the second month of the quarter
MM , MON , MONTH , RM Truncates the month or rounds up to the next month on or after the 16th day
DD , DDD , J Truncates or rounds to the day
WW Same day of the week as the first day of the year
IW Same day of the week as the first day of the ISO year
W Same day of the week as the first day of the month
Day , Dy , D Truncates or rounds to the first day of the week
HH24 , HH12 , HH Truncates to the hour or rounds up to the next hour on or after 30 minutes
MI Truncates to the minute or rounds up on or after 30 seconds
Now that you have seen all the possible masking options, try the TRUNCfunction bytesting it with different examples You will first truncate the time from the system date
Remember, you still see the time displayed, but if you use TRUNCon all dates, the time isalways 12:00 AM instead of the time the date was assigned; therefore, all dates can becalculated properly regardless of time Go ahead and execute the SQL code in Listing 6.19
LISTING 6.19 Removing the Time from SYSDATE 1: SELECT TO_CHAR(TRUNC(SYSDATE),’MM/DD/YYYY HH:MM:SS AM’) 2: “Today’s Date and Time”
3: from DUAL;
Your output appears similar toToday’s Date and Time - 06/21/1999 12:00:00 AMNotice that the time element is still displayed, but if you were to subtract twotruncated dates with the same time, you get an even number of days One moreobservation is that the default for TRUNCis the same as a format mask of DD, whichsimply eliminates the need to worry about the time in your calculations
INPUT
OUTPUT
A NALYSIS
Trang 2You can test the TRUNCfunction by truncating the SYSDATEto the nearest quarter by cuting the code in Listing 6.20.
exe-L ISTING 6.20 Truncating to the Quarter
1: SELECT TO_CHAR(TRUNC(SYSDATE,’Q’),’MM/DD/YYYY HH:MM:SS AM’) 2: “Today’s Date and Time”
3: from DUAL
Assuming today’s date is 06/01/99, you get the following output:
Today’s Date and Time - 04/01/1999 12:00:00 AM
This result makes sense because June is in the second quarter, and the quarterranges from 04/01/99 to 06/30/99 Truncating to the quarter gives the beginningdate for the applicable quarter You’ll get the opportunity to test this function in the exercises at the end of the lesson
TheADD_MONTHSfunction adds or subtracts months from a date Because this function is
overloaded, which means that you can pass different data types to the same function or
change the order of the parameters, you can specify the parameters in any order
ADD_MONTHS(date_passed, months_to_add)
Ifmonths_to_addis positive, it adds months into the future If the months_to_addnumber is negative, it subtracts months from date_passed You can specifymonths_to_addas a fraction, but Oracle completely ignores the fraction You can indi-cate the day level by using other Oracle functions Another caution is that Oracle returnsthe same day in the resulting calculation except when the last day in one month (forexample, March 31st) and the resulting month does not have as many days (Forexample, April 30th is the answer to adding one month.) The following three examples inListing 6.21 provide the same result
L ISTING 6.21 Adding Two Months to SYSDATE 1: SELECT ADD_MONTHS(SYSDATE,2) from DUAL;
2: SELECT ADD_MONTHS(SYSDATE,2.654) from DUAL;
Trang 3Using Oracle’s Built-In Functions 179
6
All of these (assuming the date is 06/02/99) produce the following output:
ADD_MONTH - 02-AUG-99You can see what happens for the last day of the month by adding one month to March31st, as shown in Listing 6.22
LISTING 6.22 Adding One Month
SELECT ADD_MONTHS(TO_DATE(‘31-MAR-99’),1) from DUAL;
This example has the outputADD_MONTH
30-APR-99Oracle could not output April 31st because no such date exists
-The NEXT_DAY Function
TheNEXT_DAYfunction returns the next date in the week for the day of the week fied after the input date The time returned is the time specified by the input date whencalled
speci-NEXT_DAY(input_date_passed, day_name)
TheNEXT_DAYfunction offers a lot of possibilities You can calculate anythingfrom the first Monday of every month to each payday in a calendar year You’llstart by testing the NEXT_DAYfunction on the SYSDATEfunction to find the next Monday
Assume the SYSDATEis June 3, 1999 Your own results will differ when you execute thecode in Listing 6.23
LISTING 6.23 Finding the First Monday After the Current Date and Time
1: SELECT TO_CHAR(NEXT_DAY(SYSDATE,’Monday’),’MM/DD/YYYY HH:MM:SS AM’) 2: “Next_Day”
Trang 4The result returned for the SYSDATEof June 3, 1999 isNext_Day
06/07/1999 07:06:38 AMThe first Monday after the date is June 7, 1999 Because you are using the SYSDATE, the corresponding time value is returned when the function is called.You can find the first Monday for August 1999 by executing the code in Listing 6.24
-L ISTING 6.24 Finding the First Monday in the Month of August
1: SELECT TO_CHAR(NEXT_DAY(‘01-AUG-99’,’Monday’),’MM/DD/YYYY HH:MM:SS AM’) 2: “Next_Day”
3: from DUAL;
Your output isNext_Day - 08/02/1999 12:00:00 AM
Although the first Monday in August is 08/02/99, is there a logic problem here?
If you repeat the example but use a month in which Monday is the first day ofthe month, what happens? Execute the code in Listing 6.25
L ISTING 6.25 Finding the First Monday in the Month of September
1: SELECT TO_CHAR(NEXT_DAY(‘01-MAY-00’,’Monday’),’MM/DD/YYYY HH:MM:SS AM’) 2: “Next_Day”
3: from DUAL;
Your output isNext_Day - 05/08/2000 12:00:00 AMThe result is definitely not what you had in mind! The NEXT_DAYfunction returnsthe next day of the day specified If the day of the week specified matches theinput date, it adds one week to the input date If you want to calculate the first occur-rence of any day in the month, always use the end date of the previous month Reviewthe proper code in Listing 6.26
Trang 5Using Oracle’s Built-In Functions 181
The LAST_DAY Function
TheLAST_DAYfunction provides the last day of the given month A useful purpose is todetermine how many days are left in the given month
LAST_DAY(input_date_passed) You will compute the last days in the month when summer officially starts from 1999
Execute the code in Listing 6.27
LISTING 6.27 Finding the Last Day of the Month Starting Summer
1: SELECT TO_CHAR(LAST_DAY(‘30-JUN-99’),’MM/DD/YYYY HH:MM:SS AM’) “Last_Day”
2: from DUAL;
Your output isLast_Day - 06/30/1999 12:06:00 AM
I purposefully used the last day of the month to illustrate an important fact
Unlike NEXT_DAY, which adds one week if the day of the week specified is thesame as the input date, the LAST_DAYfunction always returns the last day of the montheven if the input date is the same
You can take this one step further and see how many days of summer exist in the month
of June by subtracting the last day of the month by the start date of summer ExecuteListing 6.28 to see the result
Trang 6L ISTING 6.28 Calculating the Number of Days of Summer in June
1: SELECT LAST_DAY(‘20-JUN-99’) “Last_Day”, 2: LAST_DAY(‘20-JUN-99’) - TO_DATE(‘20-JUN-99’) “Days_Summer”
3: from DUAL;
Your output isLast_Day Days_Summer - 30-JUN-99 10
TheMONTHS_BETWEENfunction returns the number of months between two given dates Ifthe day is the same in both months, you get an integer value returned If the day is dif-ferent, you get a fractional result based upon a 31-day month If the second date is prior
to the first date, the result is negative
MONTHS_BETWEEN(input_date1,input_date2)
You can see all the possible returned values by executing the code in Listing 6.29
L ISTING 6.29 Experimenting with MONTHS_BETWEEN 1: SELECT MONTHS_BETWEEN(‘25-DEC-99’,’02-JUN-99’) “Fractional”, 2: MONTHS_BETWEEN(‘02-FEB-99’,’02-JUN-99’) “Integer”
3: from DUAL;
Your output isFractional Integer - - 6.7419355 -4
Trang 7Using Oracle’s Built-In Functions 183
6
The NEW_TIME Function
Have you ever wondered what time it is in Germany? Would your phone call wake upyour friend in the middle of the night? The NEW_TIMEfunction enables you to find out thetime in the time zones listed in Table 6.10 by simply passing the date and time of thefirst zone and specifying the second zone
NEW_TIME(input_date_and_time, time_zone1, time_zone2)
See Table 6.10 for the valid time zones
TABLE 6.10 Time Zones
Time Zone Abbreviation Time Zone Description
AST Atlantic Standard Time
ADT Atlantic Daylight Savings Time
BDT Bering Daylight Savings Time
CST Central Standard Time
CDT Central Daylight Savings Time
EST Eastern Standard Time
EDT Eastern Daylight Savings Time
GMT Greenwich Mean Time (the date line!)
HST Alaska-Hawaii Standard Time
HDT Alaska-Hawaii Daylight Savings Time
MST Mountain Standard Time
MDT Mountain Daylight Savings Time
NST Newfoundland Standard Time
PST Pacific Standard Time
PDT Pacific Daylight Savings Time
YDT Yukon Daylight Savings Time
You can compute the date and time difference between Chicago and Los Angeles byspecifying Central Daylight Time to Pacific Daylight Time Enter and execute the code inListing 6.30
Trang 8L ISTING 6.30 Time Change from Chicago to Los Angeles
1: SELECT TO_CHAR(NEW_TIME(TO_DATE(‘060299 01:00:00 AM’, 2: ‘MMDDYY HH:MI:SS AM’),
3: ‘CDT’,’PDT’), ‘DD-MON-YY HH:MI:SS AM’) “Central to Pacific”
OUTPUT
In a database that traverses time zones, you might want to store the time and date for all entries in one standardized time zone, along with the time zone abbreviation from the original time zone This arrangement saves you
a lot of time and coding when designing the database.
Tip
A NALYSIS
The ROUND Function
ROUNDis similar to the TRUNCfunction In fact, it uses the same format mask as TRUNCinTable 6.9 This function enables you to round up or down based upon the format mask.The default mask when specifying a DATEvalue is DD Some useful purposes for this are
• Rounding to the nearest minute for billing cellular-based calls
• Rounding to closest month to determine a pay periodROUND(input_date_and_time_or_number, rounding_specification) You can practice rounding to the nearest minute to charge people who use cellularphones by entering the code in Listing 6.31
Trang 9Using Oracle’s Built-In Functions 185
6
LISTING 6.31 Rounding to the Nearest Minute
1: SELECT TO_CHAR(ROUND(TO_DATE(‘060299 01:00:35 AM’, 2: ‘MMDDYY HH:MI:SS AM’),
3: ‘MI’), ‘DD-MON-YY HH:MI:SS AM’) “Rounded to nearest Minute”
4: from DUAL;
Your output isRounded to nearest Minute - 02-JUN-99 01:01:00 AM 10Because the seconds were 30 or greater, this example rounded to the next minute
at 1:01 from 1:00 Had the number of seconds been 22, the return value would be1:00 You should test this code on your own
TheTRIMfunction truncates leading and trailing characters from a specified string This
is equivalent to using the LTRIMandRTRIMfunctions simultaneously
TRIM ([LEADING/TRAILING/BOTH], trim_character FROM trim source) You can practice the TRIMfunction to remove leading and trailing zeroes from a specifiednumber by entering the code in Listing 6.32
LISTING 6.32 TRIM Leading and Trailing Zeroes
SELECT TRIM (0 FROM 067270676800) “TRIM Example”
FROM DUAL;
Your output isTRIM Example - 672706768TheTRIMfunction lets us remove all unwanted leading and trailing zeroes fromthe specified number
Summary
Today, you discovered only a fraction of Oracle’s powerful built-in functions Today’slesson stressed the importance of converting data and working with dates I highly rec-ommend that you refer to Appendix B to review the rest of the functions A final tip:
Trang 10Q Are all the functions available within PL/SQL?
A No Several functions can be used in SQL only.
Q Must I use Oracle’s built-in functions?
A No You can always create your own similar functions, but when speed is of the
essence, why reinvent the wheel? Use the built-in functions whenever possible
Q What date does the Julian system start counting from?
A January 1, 4712 BC.
Q When using TO_DATE, is the format mask important?
A Not just a little bit important, but very important and required! Without the proper
format mask, you will most certainly get an Oracle error message
Q How long should the number format mask be?
A At least equal to or greater than the length of the largest value.
Q What function allows you to perform mathematical computations on acter strings?
char-A TO_NUMBERconverts character strings to numbers so that you can perform anymathematical calculations you want
Q Where does the SYSDATEdate and time originate?
A If you are using Personal Oracle, the system date and time come from the PC’s
internal clock If you are in a client/server environment, the system date and timeare pulled from the server
1 True or False: All functions are accessible within PL/SQL
2 What function do I use to combine two strings together?
3 What function converts ‘11/28/99’to an Oracle DATE?
4 In a VARCHAR2string, each string can be a variable length What function do youuse to determine the length so that you can search through the entire string?
Trang 11Using Oracle’s Built-In Functions 187
6
5 How do you get rid of padded spaces to the right of a string in Oracle?
6 To determine the remainder, you use the _ function
7 To determine how many months a customer is delinquent, you can use the _ function
8 You can use the TRUNCandROUNDfunctions with what data types?
Exercises
1 Create a PL/SQL block that reads in the month of a date and displays the month in
a Roman numeral format Use a date of 06/11/67 This allows you to practice theTO_CHARfunction When printing the Roman numeral equivalent, use LTRIMtoremove any spaces padded to the left of the Roman numeral If you are reallyambitious, on your own you can create the same RM-type function by usingIF THEN ELSEstatements for practice from Day 4 Remember, practice helps
to solidify your knowledge through repetition and understanding
2 Use the TRUNCfunction on the SYSDATEto round to the nearest century
3 Use CONCATto link two strings together Repeat the same line by using ||instead
6 Calculate how many months are between 05/15/97 and 08/22/97
7 Round the SYSDATEto the nearest century
8 Calculate the time in Newfoundland from Central Standard Time from 02-22-97,05:00 AM
9 From Listing 6.22, subtract one month and explain the answer
10 Calculate the number of days until Christmas from the last day of the month oftoday’s date (We don’t get paid until the end of the month!)
Trang 13D AY 7
W EEK 1
Procedures, Packages, Errors, and Exceptions
by Tom Luers
Procedures and packages enable you to organize your program code into logicalgroups for easier maintenance and implementation Additionally, these groupshave built-in error trapping to prevent the code from abnormally stoppingduring processing In today’s lesson on procedures, packages, errors, andexceptions, you will learn about
• Creating procedures
• Invoking stored procedures
• Invoking rights for procedure
• Creating packages
• Trapping errors and exceptions
Trang 14Using Procedures
A procedure is a logically grouped set of SQL and PL/SQL statements that form a specific task It’s a miniature self-contained program A stored procedure
per-is a procedure that has been compiled and stored inside the database Once stored the
procedure is a schema object (that is, a specific database object).
Procedures have several parts The declarative part contains declarations of types, cursors,constants, variables, exceptions, and nested subprograms Procedures can be declared inPL/SQL blocks, packages, and other procedures The executable part contains statementsthat control execution and manipulate data Occasionally, the procedure might contain anexception-handling part to deal with exceptions raised during execution Procedures can bedefined and executed by using any Oracle tool that supports PL/SQL, such as SQL*Plus
Why Use Procedures?
Procedures are created to solve a specific problem or task PL/SQL procedures offer thefollowing advantages:
• In PL/SQL, you can tailor a procedure to suit your specific requirements
• Procedures are modular, which means they let you break a program down intomanageable, well-defined units
• Because procedures are stored in a database, they are reusable After a procedurehas been validated, it can be used over and over, without being recompiled or dis-tributed over the network
• Procedures improve database security You can restrict database access by allowingusers to access data only through stored procedures
• Procedures take advantage of shared memory resources
Procedures Versus Functions
Procedures and functions are PL/SQL subprograms that are stored in the database Thesignificant difference between the two is simply the types of output the two objects gen-erate A function returns a single value, whereas a procedure is used to perform compli-cated processing when you want a substantial amount of information back
Trang 15Procedures, Packages, Errors, and Exceptions 191
7
The Syntax for the CREATE PROCEDURECommand
CREATE OR REPLACE PROCEDURE procedure_name (arguments)
AS [pl/sql body code]
In this syntax, the keywords and parameters are as follows:
• OR REPLACE—An optional keyword I strongly suggest you always use this keywordbecause it re-creates the procedure if it already exists You can use this keyword tochange an existing procedure without having to drop and re-create the procedure
• procedure_name—The name you assign to the procedure being created
• arguments—The arguments in the procedure, which can be the following:
• in—Specifies that you must pass a value to the subprogram being called
Theinparameter might not be assigned a value because it acts like a stant The actual value that corresponds to the parameter can be a constant, aliteral, an initialized variable, or an expression
con-• out—Specifies that the procedure returns a value to the calling program
This parameter acts like an uninitialized parameter; therefore, its valuecannot be assigned to another variable The actual value that corresponds tothe parameter must be a variable It cannot be a literal, a constant, or anexpression Within your subprogram, the outparameter must be assigned avalue
• inout—Specifies that you must pass a value to the procedure and that theprocedure returns a value to its calling environment after execution
• pl/sql body code—The logic of the procedure There must be at least onePL/SQL statement, or an error occurs
The code shown in Listing 7.1 creates a simple stored procedure named emp_change_s.This procedure accepts one argument, the emp_idparameter
LISTING 7.1 Creating a Stored Procedure
CREATE OR REPLACE PROCEDURE emp_change_s (i_emp_id IN integer)
AS BEGIN UPDATE employee set pay_type = “S”
WHERE emp_id = i_emp_id;
Trang 16In this sample code, you have created a procedure that is stored in the database.This procedure is named emp_change_sand can accept one parameter,emp_id.When this procedure is stored in the database, you can invoke the program via any otherPL/SQL block To see the effect of this procedure, first select the rows from the
employee table prior to running this procedure Then run the procedure and re-select therows from the table The records are now updated
Normally, procedures are created as standalone schema objects However, you can create
a procedure as part of a package; this topic is discussed later in this lesson, in the section
“Exploring Packages.”
TheRETURNstatement causes a subprogram to immediately complete its execution andreturn to the calling program Execution in the calling program resumes with the state-ment following the procedure call
In procedures, the RETURNstatement cannot contain an expression Its sole purpose is toreturn control to the calling program before the end of the procedure is reached
Procedure Dependencies
One of the inherent features of Oracle is that it checks the database to make sure that theoperations of a procedure, function, or package are possible based on the objects the userhas access to For example, if you have a procedure that requires access to several tables andviews, Oracle checks during compilation time to see if those tables and views are present
and available to the user The procedure is said to be dependent on these tables and views
Oracle automatically recompiles all dependent objects when you explicitly recompile the parent object This automatic recompilation of dependent objects happens when the dependent object is called Therefore, you should not recompile a parent module in a production system: It causes all depen- dent objects to recompile and consequently can cause performance prob- lems for your production system.
Caution
You can discover object dependencies in several different ways You can examine theprocedure or function code and determine which database objects it depends on Or youcan talk with the database administrator (DBA) and examine the schema to identifydependencies Finally, you can run the Oracle utldtree.sqlscript, which generates atemporary table and a view that lets you see the objects that are dependent on a givenobject This script generates a listing only for the objects to which you have access
A NALYSIS
Trang 17Procedures, Packages, Errors, and Exceptions 193
7
Recompiling Stored Procedures
To explicitly recompile a stored procedure, issue the ALTER PROCEDUREcommand Thiscommand must be used only on standalone stored procedures and not on procedures thatare part of the package
Recompiling a procedure does not change the procedure’s declaration or definition Youmust use CREATE PROCEDUREwith the OR REPLACEclause to do these things If Oraclesuccessfully recompiles a procedure, then the procedure becomes a valid procedure thatcan be executed without runtime compilation If compilation fails, the procedurebecomes invalid and must be debugged
You can use the ALTER PROCEDUREcommand to explicitly recompile a procedure that isinvalid After a procedure is compiled, it does not need to be recompiled implicitly duringruntime processes This leads to reduced overhead and elimination of runtime compilationerrors
You can produce debugging information from within an application by issuing the PUTorPUT_LINEcommands These commands place the debugging information into a bufferthat was created by the DBMS_OUTPUTpackage To display the contents of the buffer, typetheSET SERVEROUTPUT ONcommand at the SQL*Plus prompt
The code in Listing 7.2 illustrates the PUT_LINEcommand line that you can includeinside a procedure
LISTING 7.2 The PUT_LINE Command Within a Procedure
CREATE OR REPLACE PROCEDURE emp_change_s (i_emp_id IN integer)
AS BEGIN UPDATE employee set pay_type = ‘S’
WHERE emp_id = i_emp_id;
DBMS_OUTPUT.PUT_LINE (‘New Pay Type = ‘ || ‘S’); debug Line END emp_change_s;
The following statements are issued at the SQL*Plus command line to execute the partsprocedure and to display the debugging information:
SQL> execute emp_change_s SQL> execute emp_change_sThe following are the results of these statements being executed This information is gen-erated from the dba_outputbuffer area:
New Pay Type = S
INPUT
INPUT
OUTPUT
Trang 18In this example, the emp_change_sprocedure was created and then executed.During its invocation, one parameter was passed During its execution, this pro-cedure simply created the new Pay Typevalue, and displayed it
Re-creating and Modifying Procedures
A valid standalone procedure cannot be altered; it must be either replaced with a newdefinition or dropped and re-created For example, you cannot just slightly alter one ofthe PL/SQL statements in the procedure Instead, you must re-create the procedure withthe modification
When replacing a procedure, you must include the OR REPLACEclause in the CREATEPROCEDUREstatement The OR REPLACEclause is used to replace an older version of aprocedure with a newer version of the procedure This replacement keeps all grants in
place; therefore, you do not have to re-create the grants Grants are statements which
when executed allow certain privileges to be given to the object of the grant However, ifyou drop the procedure and re-create it, the grants are dropped and consequently have to
be rebuilt If you attempt a CREATE PROCEDUREcommand for a procedure that alreadyexists, Oracle generates an error message
Listing 7.3 re-creates the procedure named emp_change_s
L ISTING 7.3 Re-creating a Procedure By Using OR REPLACE
CREATE OR REPLACE PROCEDURE emp_change_s (i_emp_id IN integer)
AS BEGIN UPDATE employee set pay_type = ‘S’
WHERE emp_id = i_emp_id;
END emp_change_s;
Invoking Stored Procedures
You can invoke procedures from many different environments, including SQL*Plus andOracle*Forms Also, you can invoke procedures from within another procedure or trigger.For example, the procedure emp_change_scan be called from another procedure ortrigger, with the following statement:
DECLARE other PL/SQL block code
Trang 19Procedures, Packages, Errors, and Exceptions 195
is returned to the next line of code immediately following the procedure invocation line
Another example of the same procedure being executed from within SQL*Plus is the following:
SQL> execute emp_change_s (2);
The following example shows a procedure being called from within a precompiler program:
exec sql execute BEGIN
emp_change_s (2) END
END-execThis is a fairly common and simple method for executing a stored procedure Youwill probably use this approach frequently during your developments efforts
Using Parameters
Procedures use parameters (that is, variables or expressions) to pass information When
a parameter is being passed to a procedure, it is known as an actual parameter.
Parameters declared internal to a procedure are known as internal, or formal, parameters.
The actual parameter and its corresponding formal parameter must belong to compatibledatatypes For example, PL/SQL cannot convert an actual parameter with the datatypeDATEto a formal parameter with the datatype LONG In this case, Oracle would return anerror message This compatibility issue also applies to the return values
Parameter Definitions
When you invoke a procedure, you must pass it a value for each of the procedure’s meters If you pass values to the parameter, they are positional and must appear in thesame order as they appear in the procedure declaration If you pass argument names, theycan appear in any order You can have a combination of values and names in the argumentvalues If this is the case, the values identified in order must precede the argument names
para-Listing Stored Procedure Information
Oracle provides several data dictionary views that provide information about proceduresthat are currently stored in a schema:
Trang 20• all_errors—A list of current errors on all objects accessible to the user
• all_source—The text source of all stored objects accessible to the user
• user_objects—A list of all the objects the current user has access to
• dba_errors—Current errors on all stored objects in the database
• dba_object_size—All PL/SQL objects in the database
• dba_source—The text source of all stored objects in the database
• user_errors—The current errors on all a user’s stored objects
• user_source—The text source of all stored objects belonging to the user
• user_object_size—The user’s PL/SQL objectsThe code in Listing 7.4 queries the user_errorsview to obtain information about thecurrent errors on a procedure owned by user_01
L ISTING 7.4 Viewing Errors in a Database
SELECT LINE, TYPE, NAME, TEXT from user_errors LINE TYPE NAME TEXT
Additionally, you can select from the user_objectstable and interrogate which objectsare invalid and need to be recompiled User_objectsis a database table which comes bydefault with your database It contains information about all objects owned by a specificuser Executing the following piece of code via SQL*PLUS produces the object namesand their types for the database objects that need to be evaluated for recompilation:
SELECT object_name, object_type from user_objects
WHERE status = ‘INVALID’;
Object_Name Object_Type Emp_change_h Procedure
In this example, the procedure named emp_change_his listed in the user_objectstable as invalid Emp_change_his a procedure that I have made up to illustrate thistable It will not show up in your exercise Now the developer knows which object is
Trang 21Procedures, Packages, Errors, and Exceptions 197
7
Dropping a Stored Procedure
You can issue the SQL statement DROPprocedure to drop a procedure object
In the Oracle environment, the term drop means to delete that object from the
Oracle permits you to call the same procedure name in a package but with
dif-ferent arguments This is known as overloading This technique is very useful,
especially when you want to execute the same procedure several times, but with ments that have different datatypes One example of using procedure overloading is withthe package DBMS_OUTPUT, in which the PUT_LINEprocedure is called numerous times toproduce output lines of different datatypes
argu-The following example illustrates the definition of two overloaded local procedures:
DECLARE PROCEDURE compute_sales (begin_date in date) RETURN boolean 1st example of procedure is
BEGIN RETURN begin_date > :start_date;
END;
PROCEDURE compute_sales (sales_in in date) RETURN boolean overloaded example of procedure is
BEGIN RETURN sales_in > :sales_target;
END;
When the PL/SQL engine encounters a call to compute_sales, the compiler executes themodule in the body that has the correct and matching module header
Using Recursive Procedures
A recursive procedure is a procedure that calls itself Each recursive call creates
a new instance of any object declared in the procedure, including parameters,variables, cursors, and exceptions Also, new instances of SQL statements are created ateach level in the recursive procedure
Trang 22With recursive logic, the procedure must be able to terminate itself at some defined point, or the recursion would last forever This point of termination is
pre-defined in a terminating condition.
The following code example uses a conditional statement to terminate the recursivecycle:
FUNCTION inv_calc BEGIN
IF qty = > :max_qty THEN terminating condition;
RETURN 1;
ELSE RETURN qty * inv_calc (qty * :part_qty); recursive call
END IF END inv_calc;
In this example, the function inv_calccalls itself continuously until max_qtyisreached When max-qtyis reached, recursion stops and the function returns 1.It’s important to be careful with recursion and where you place the recursive call If youplace the recursive call inside a cursor FORloop or between OPENandCLOSEstatements, acursor is opened at each call This can open enough cursors to violate the maximumallowable open cursors permitted by the OPEN_CURSORinitialization parameter
Procedure Invocation Security
When executing a stored procedure, Oracle verifies that you have the necessary leges to do so If you do not have the appropriate execution permissions, an error occurs.The primary way you grant execution privileges to a user is via the Oracle Role Oracleevaluates and uses roles in different ways, depending the type of PL/SQL block (named
privi-or anonymous) and the type of rights of the user (invoker privi-or definer)
As you learned on Day 2, “Writing Declarations and Blocks,” an anonymous block isone that is not part of a formal block, such as a procedure or function, and a namedblock is one that is part of a formal block
Like functions, definer and invoker rights dictate the security of procedure invocation Bydefault, the function executes with the same privileges as the function definer, not thefunction invoker These definer rights are bound to the schema in which it resides Youcan fully qualify the object names in the PL/SQL statements so that you can modifytables in other schemas However, be aware that this limits the portability of your code.Oracle allows you to call functions with invoker rights In this case, you are not bound toone schema, but you are bound by the privileges of the caller You can use the INVOKERrights via the AUTHIDclause
A NALYSIS
N EW T ERM
Trang 23Procedures, Packages, Errors, and Exceptions 199
7
All roles are disabled in any named PL/SQL block (that is, stored procedure, function, ortrigger) that executes with definer rights Roles are not used for privilege checking andyou cannot set roles within a definer-rights procedure The SESSION_ROLESview showsall roles that are currently enabled If a named PL/SQL block that executes with definerrights queries SESSION_ROLES, the query does not return any rows
Named PL/SQL blocks that execute with invoker rights and anonymous PL/SQL blocksare executed based on privileges granted through enabled roles Current roles are usedfor privilege checking within an invoker-rights PL/SQL block, and you can use dynamicSQL to set a role in the session
Exploring Packages
A package is an encapsulated collection of related schema objects These objects
can include procedures, functions, variables, constants, cursors, and exceptions Apackage is compiled and then stored in the database’s data dictionary as a schema object Acommon use for packages is to package together all procedures, functions, and otherrelated objects that perform similar tasks For example, you might want to group allaccount billable objects in one package and accounts receivable objects in a differentpackage
The packages contain stored subprograms, or standalone programs, which are
called the package’s subprograms These subprograms can be called from
another stored program, triggers, precompiler programs, or any of the interactive Oracleprograms, such as SQL*Plus Unlike the stored subprograms, the package itself cannot
be called or nested, and parameters cannot be passed to it
A package usually has two components to it: a specification and a body The
specification declares the types, variables, constants, exceptions, cursors, and subprograms that are available for use The body fully defines cursors, functions, and
procedures and so implements the specification
Why Use Packages?
Packages offer the following advantages:
• They enable you to organize your application development more efficiently intomodules Each package is easily understood, and the interfaces between packagesare simple, clear, and well defined
• They allow you to grant privileges efficiently
• A package’s public variables and cursors persist for the duration of the session
Therefore, all cursors and procedures that execute in this environment can share them
• They enable you to perform overloading on procedures and functions
N EW T ERM
N EW T ERM
N EW T ERM
Trang 24• They improve performance by loading multiple objects into memory at once.Therefore, subsequent calls to related subprograms in the package require noinput/output.
• They promote code reuse through the use of libraries that contain stored dures and functions, thereby eliminating redundant coding
DO keep packages simple and general to
promote their reuse in future applications
DO design the package body after you
design the application Place only those objects that you want visible to all users
in the package specification.
DON’T write packages that replicate
existing Oracle functionality.
DON’T place too many items in the
package specification; specifically, avoid placing in the package specification items that need to be compiled Changes to a package body do not require Oracle to recompile dependent procedures.
However, changes to the specification of a package require Oracle to recompile every stored subprogram that references the package.
DO DON’T
The Package Specification
The package specification contains public declarations of the name of the package andthe names and datatypes of any arguments This declaration is local to the database andglobal to the package This means that the declared objects in the package are accessiblefrom anywhere in the package Therefore, all the information the application needs toexecute a stored subprogram is contained in the package specification
The Syntax for the CREATE PACKAGESpecification Command
CREATE [OR REPLACE] PACKAGE package_name [AUTHID {CURRENT_USER | DEFINER}] {IS | AS}
[package body object declaration]
END [package_name];
In this syntax, the keywords and parameters are as follows:
• package nameis the name of the package the creator defines It is important togive it a name that is meaningful and represents the contents of the package
• AUTHIDrepresents the type of rights you want invoked when the package is cuted The rights may be those of the CURRENT_USERor of those of the packageDEFINER(creator)
exe-• package body object declarationis where you list the objects that will be
Trang 25Procedures, Packages, Errors, and Exceptions 201
7
The following is an example of a package declaration In this example, the specificationdeclares a function and two procedures Then the package body contains the actual logicfor the items declared in the specification:
CREATE PACKAGE employee_maint AS
Procedure emp_change_s (I_emp_id IN intger);
Procedure emp_change_h (I_emp_id IN integer);
Function emp_rate (rate number) RETURN number;
End employee_maint;
The package employee_maintis first defined in the package declaration Thisdeclaration makes the existence of the package known to the domain of the data-base instance Hence it can be called by any program in the instance that also has theappropriate access rights
Sometimes a specification declares only variables, constants, and exceptions, and fore, a package body is not necessary This is a great method to use when defining globalvariables that you want to be persistent during a session
there-The following example is a package specification for a package that does not have apackage body:
CREATE PACKAGE inv_costings package specification header AUTHID DEFINER invokes definer rights when executed is
type inv_rec is record (part_name varchar2(30), part_price number, part_cost number);
The Package Body
The body of a package contains the definition of the public objects you declare in thespecification The body also contains other object declarations that are private to thepackage The objects declared privately in the package body are not accessible to other
INPUT
A NALYSIS
INPUT
A NALYSIS