Download presentation
Presentation is loading. Please wait.
Published byGeraldina Venturini Modified over 5 years ago
1
PL/SQL overview – a native 3GL interface to Oracle RDBMS
This module is a basic introduction to the PL/SQL language - Is an Oracle-developed 3GL used at the application service tier level - Has many OO properties (in fact, “under the hood” PL/SQL implements an “object-relational” model) - Is strongly-coupled to Oracle SQL – Example: all Oracle data types inherit over - Has been in use long before Java/Python/Ruby/ … were in common use - Is more “portable” across platforms (eliminates 3GL differences across OSs) ‘Programming Language/Structured Query Language’ (abbreviated: PL/SQL) Oracle-proprietary 3GL giving procedural capabilities to PL/SQL + SQL Some of the more notable PL/SQL properties: user types are created with the statement: create type ( …) - Substantial OO is processible by some little-known SQL standard constructs block structured 1) anonymous blocks and 2) named blocks (procedures and functions) PL/SQL is quickest, least-cluttered way to cover the important structures for tiering: coupling of the app tier and DB tier: 1) cursors 2) bind variables, and 3) stored procedures (stored IN the database) PL/SQL is probably new to many in CSC204; its use places everyone at same point = > Focus can be on essentials of 3GL tier < > SQL coupling cited above
2
Aspects of Server software architecture
Large-scale apps “tier” service architectures: One form is “3-tier” In the diagram below, a web request “Req” arrives at the Front end, and Req is passed to the 3GL tier for specialized computations, and (assuming database processing needed) Req is passed to SQL Look only at the 3GL tier relationship to the SQL tier in this course. Results/response Database “backend” Req One or more 3GL apps that do special computations not suited for SQL PL/SQL, Java, Perl, etc here (SQL*Plus on DBMS server OR other 3GL on app server) Internet facing Front end Form/field processing DBMS server SQL
3
PL/SQL intro syntax An PL/SQL program consists of statements, organized in (nested) block structure Upper/Lower case letters in a program identifier treated the same When using un-quoted identifiers, AbC is the same name as ABC, (except for character strings in quotes) Reserved words and Keywords of PL/SQL include: BEGIN, END, IF, WHILE, EXCEPTION, DECLARE, and various package names such as “htp” (package name for HTML generation) are examples. Some of these special words are also reserved by SQL You should not use them to name program objects such as constants, variables, cursors, schema objects such as columns, tables, or indexes. (This view is Inaccessible to CS2041xy schemas)
4
Table D-1 PL/SQL Reserved Words
Oracle 10g – Complete list of Reserved words (Cannot be used as identifiers) Begins with: Reserved Words A ALL, ALTER, AND, ANY, ARRAY, ARROW, AS, ASC, AT B BEGIN, BETWEEN, BY C CASE, CHECK, CLUSTERS, CLUSTER, COLAUTH, COLUMNS, COMPRESS, CONNECT, CRASH, CREATE, CURRENT D DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DROP E ELSE, END, EXCEPTION, EXCLUSIVE, EXISTS F FETCH, FORM, FOR, FROM G GOTO, GRANT, GROUP H HAVING I IDENTIFIED, IF, IN, INDEXES, INDEX, INSERT, INTERSECT, INTO, IS L LIKE, LOCK M MINUS, MODE N NOCOMPRESS, NOT, NOWAIT, NULL O OF, ON, OPTION, OR, ORDER,OVERLAPS P PRIOR, PROCEDURE, PUBLIC R RANGE, RECORD, RESOURCE, REVOKE S SELECT, SHARE, SIZE, SQL, START, SUBTYPE T TABAUTH, TABLE, THEN, TO, TYPE U UNION, UNIQUE, UPDATE, USE V VALUES, VIEW, VIEWS W WHEN, WHERE, WITH
5
Oracle 10g PL/SQL Keywords - (can be used as identifiers, but this is NOT recommended)
Table D-2 PL/SQL Keywords (such identifiers have special meaning in a specific contest, thus, could be used as an identifier) Begins with: Keywords A A, ADD, AGENT, AGGREGATE, ARRAY, ATTRIBUTE, AUTHID, AVG B BFILE_BASE, BINARY, BLOB_BASE, BLOCK, BODY, BOTH, BOUND, BULK, BYTE C C, CALL, CALLING, CASCADE, CHAR, CHAR_BASE, CHARACTER, CHARSETFORM, CHARSETID, CHARSET, CLOB_BASE, CLOSE, COLLECT, COMMENT, COMMIT, COMMITTED, COMPILED, CONSTANT, CONSTRUCTOR, CONTEXT, CONVERT, COUNT, CURSOR, CUSTOMDATUM D DANGLING, DATA, DATE, DATE_BASE, DAY, DEFINE, DETERMINISTIC, DOUBLE, DURATION E ELEMENT, ELSIF, EMPTY, ESCAPE, EXCEPT, EXCEPTIONS, EXECUTE, EXIT, EXTERNAL F FINAL, FIXED, FLOAT, FORALL, FORCE, FUNCTION G GENERAL H HASH, HEAP, HIDDEN, HOUR I IMMEDIATE, INCLUDING, INDICATOR, INDICES, INFINITE, INSTANTIABLE, INT, INTERFACE, INTERVAL, INVALIDATE, ISOLATION J JAVA L LANGUAGE, LARGE, LEADING, LENGTH, LEVEL, LIBRARY, LIKE2, LIKE4, LIKEC, LIMIT, LIMITED, LOCAL, LONG, LOOP M MAP, MAX, MAXLEN, MEMBER, MERGE, MIN, MINUTE, MOD, MODIFY, MONTH, MULTISET N NAME, NAN, NATIONAL, NATIVE, NCHAR, NEW, NOCOPY, NUMBER_BASE O OBJECT, OCICOLL, OCIDATETIME, OCIDATE, OCIDURATION, OCIINTERVAL, OCILOBLOCATOR, OCINUMBER, OCIRAW, OCIREFCURSOR, OCIREF, OCIROWID, OCISTRING, OCITYPE, ONLY, OPAQUE, OPEN, OPERATOR, ORACLE, ORADATA, ORGANIZATION, ORLANY, ORLVARY, OTHERS, OUT, OVERRIDING P PACKAGE, PARALLEL_ENABLE, PARAMETER, PARAMETERS, PARTITION, PASCAL, PIPE, PIPELINED, PRAGMA, PRECISION, PRIVATE R RAISE, RANGE, RAW, READ, RECORD, REF, REFERENCE, REM, REMAINDER, RENAME, RESULT, RETURN, RETURNING, REVERSE, ROLLBACK, ROW S SAMPLE, SAVE, SAVEPOINT, SB1, SB2, SB4, SECOND, SEGMENT, SELF, SEPARATE, SEQUENCE, SERIALIZABLE, SET, SHORT, SIZE_T, SOME, SPARSE, SQLCODE, SQLDATA, SQLNAME, SQLSTATE, STANDARD, STATIC, STDDEV, STORED, STRING, STRUCT, STYLE, SUBMULTISET, SUBPARTITION, SUBSTITUTABLE, SUBTYPE, SUM, SYNONYM T TDO, THE, TIME, TIMESTAMP, TIMEZONE_ABBR, TIMEZONE_HOUR, TIMEZONE_MINUTE, TIMEZONE_REGION, TRAILING, TRANSAC, TRANSACTIONAL, TRUSTED, TYPE U UB1, UB2, UB4, UNDER, UNSIGNED, UNTRUSTED, USE, USING V VALIST, VALUE, VARIABLE, VARIANCE, VARRAY, VARYING, VOID W WHILE, WORK, WRAPPED, WRITE Y YEAR Z ZONE Notice that the SQL standard tr processing statements are usable within PL/SQL; in other words, EVERY PL/SQL code section, as well as individual statements are in Oracle tp context
6
General languages note –
PL/SQL naming Some naming rules (in addition to the Oracle namespaces rules covered earlier): - spaces not allowed in names - no special characters other than #, _, $ (and “$” is discouraged, but legal) Ex: a_long_PLSQL_identifier - a name must be unique within a PL/SQL block (nested blocks are allowed) Literals (self-defining items) have 3 types Number 100, 3.14, -67, 5.2E7, NULL Character string ‘A’, ‘This is a string’, ‘0001’, NULL (also represented by ‘’) (Embed a single quote in a string with an extra quote: ‘New Year’’s Day’ Boolean TRUE, FALSE, NULL (these are not enclosed in quote marks) General languages note – Within a block “B” of PL/SQL code, it is possible to communicate (read & write) data and other kinds of entities in: * SQL * SQL*Plus * a PL/SQL stored procedure/function * other programming languages * “foreign” database systems using some form of gateway access (or a database link in Oracle server1 < --- > Oracle server2)
7
2 types of (source code) block
PL/SQL blocks Note: there are 2 modes of PL/SQL translation: Interpreted & native-compiled 2 types of (source code) block Anonymous – can be used anywhere in a stream of SQL*Plus commands or a script This kind of block exists ONLY in source code textfile form, and is directly translated and executed where it appears in a stream of SQL*Plus. No part of an anonymous block is stored in the DD; the Oracle DD stores/knows NOTHING about an anonymous block Named (procedure or function) – executable form is stored in the DBMS itself; very important: enables SQL and the DD info to manage procs/fcns Large-scale apps organized into “Packages” – each package is a collection of related procedures, functions, and other elements, such as triggers, pragmas, etc. (overview soon) Either type of) PL/SQL block has following sections: Declarations Executable Exception handling The outline of syntax for a PL/SQL block DECLARE Optional declaration of constants, variables, cursors, user-defined exceptions, … BEGIN Mandatory section containing PL/SQL statements (Note: NULL; is the do-nothing statement) EXCEPTION {Optional section specifying different action(s) to do for various errors in executable section a WHEN keyword starts exception code and “;”, not an END; terminates this exception code part; can be any number of WHEN sections} END; Of the 4 keywords, only BEGIN and END are mandatory
8
PL/SQL anonymous block – first example
Anonymous blocks - are unnamed – translated/executed, but not stored anywhere; exists only in source code form, as a file; Instructor’s file name convention for a source anonymous block is x.plsql - use “;” to terminate each SQL statement or PL/SQL control statement in the block - use “.” to close SQL*Plus buffer contents - a PL/SQL block is treated as one continuous statement in query buffer, and a “;” within the block does not terminate the block nor execute the buffer contents. When an xxx.plsql source is executed via SQL*Plus execution automatically creates a database connection (Unlike typical 3GL (Java/Python/C …) app tier code that must execute database connection + authentication code) First anonymous block example: skeleton of code: SELECT … INTO a local variable DECLARE Multiple statements per line legal, but code will be less readable v_variable VARCHAR2(5); BEGIN SELECT column_name INTO v_variable FROM table_name; < -- The table/object must exist at compile time, else compile error EXCEPTION WHEN exception_name THEN . . . END; / < -- These last two lines should ALWAYS be included in a PL/SQL show errors block of either type; “/” translates source, and if no errors, executes it A full, complete first example of a PL/SQL anonymous block is at homePage: plsql_ex1_204_f19.plsql Compile and run in SQL*Plus: When no unhandled execution errors or compile errors occur, and following any/all output generated by the source code, you should see msg: ‘PL/SQL procedure successfully completed’
9
PL/SQL variables Types of build-in variables - scalar – a single value
- composite – such as records so that groups of fields can be manipulated - reference – called pointers to designate other program items (not covered here) - LOB – these are locators/references that specify large objects stored in files (for example, a movie or sound clip could be a BFILE type of LOB) - non-PL/SQL variables in language that invokes PL/SQL, and accessible in PL/SQL Example: “bind/host variables” declared in SQL*Plus or Java, etc. All PL/SQL variables have: - datatype: - storage format - constraints - valid range of values DECLARING variables: identifier [CONSTANT] datatype [NOT NULL] [value:= expr]; DECLARE v_hiredate DATE; built-in type “DATE” inherited from Oracle date type v_dno number(2) not null := 10; Initialization of value c_comm CONSTANT NUMBER := 1400; v_name e.lname%type; Inherits type of the Oracle employee column, obviously “understands” public synonyms, and called an “anchored variable” Note: Identifier name convention: c_xxx (v_xxx) is a PL/SQL constant (variable) name ( The “v_...” and “c_...” conventions are NOT PL/SQL rules; they are naming conventions used in this course )
10
DBMS_OUTPUT package; simple SELECT into PL/SQL
PL/SQL does not have virtual I/O statement(s) such as “READ”, but built-in package DBMS_OUTPUT has many I/O methods/routines for use in PL/SQL DBMS_OUTPUT.PUT_LINE( ) is one of the most-used routines (This does not cause immediate output flush (does lazy writes)) The SQL*Plus session variable SERVEROUTPUT must be toggled ON to display package’s session output (default is OFF) Next, illustrate SQL retrieval of a single column value from a table into an anchored variable in PL/SQL There is a utility utl_file for reading from flat files that will not be used in this course
11
Second PL/SQL anonymous block example
-- FileName.plsql, WJM, CSUS -- First PL/SQL anonymous block example -- Usage: Enable DBMS_OUTPUT output with: set serveroutput on, and compile via: DECLARE v_lname company.employee.lname%TYPE; BEGIN -- Limitation: only ONE lname can be returned into variable v_lname SELECT lname INTO v_lname FROM company.employee WHERE ssn like ' '; DBMS_OUTPUT.PUT_LINE ('Last name of SSN is: ' || v_lname); -- Type conversion notes: int type values do not need conversion by to_char END; / show errors Notes: 1. SQL syntax recognized without need of any extra interface syntax 2. || is the string concatenation operator in string expressions 3. A version of this code is on course homePage: blocks3.plsql String concatenation
12
Bind and Anchored variables
Bind variables (aka host variables) are: - Declared in the host environment such as SQL*Plus and in PL/SQL Ex: SQL> variable g_double varchar2(20) - Within PL/SQL code, a bind variable is accessed/used with “:” prefix (Ex: :g_double) - And a host variable can be referenced, assigned a value, and PRINTed in PL/SQL Here is a simple anonymous block that is created and executed at SQL*Plus command level: SQL> BEGIN 2 :g_double := ‘Hi from PL/SQL’; 3 END; 4 / SQL> PRINT g_double (do not use leading “:” to refer to bind variable in SQL*Plus itself) With bind variables, we now have 3 languages that can access each other’s variables: Results of PRINT statement: host language: SQL*Plus G_DOUBLE 3GL language: PL/SQL DB language: SQL Hi from PL/SQL = => Later see: bind variables can speed up execution of loops containing SQL statements Note: Identifier naming convention by instructor: g_xxx is an SQL*Plus host variable Anchored variables are declared in PL/SQL code - declare via: x%TYPE, where x can be a declared PL/SQL variable or a table or view or column name or reference - Also, iterative anchoring is allowed: v_comm NUMBER(7,2); v_total_comm v_comm%TYPE; v_net_comm v_total_comm %TYPE; - NOT NULL constraints inherit from PL/SQL declarations, but not from SQL table columns
13
Generally, a cursor references a block of data returned from the DB
Cursors A larger work area in PL/SQL is needed for SQL SELECT queries that have n row results vs. first anonymous ex. with 1 row returned into one PL/SQL variable Generally, a cursor references a block of data returned from the DB A cursor is the SQL-2 standard construct for a RDBMS < - - > app interface A cursor has User data (rows) & Meta data internals we will not cover Cursor returns results to 3GL tier and implements a program < -- > /SQL/DB communication area, for errors & other purposes and an Oracle cursor also contains info used by the qo 2 types of cursors (as categorized by their names and how created) - implicit cursor: not declared; has various processing methods; some, but not complete user control of such cursors - explicit cursor: has a name; must be declared in the DECLARE section, and contains a SQL SELECT statement; there are commands to process such a cursor: OPEN, CLOSE, FOR … LOOP etc. In CSC204, we (mostly) use explicit cursors Any legal identifier Syntax of a declaration: CURSOR CursorName IS SELECT statement; < - - Any legal SQL query (A cursor’s returned results analogous to a data “array”, with each “array” element corresponding to a row of data retrieved by the cursor’s query) Similar to an anonymous block, a cursor’s only non-volatile existence is in PL/SQL source code; however, a given cursor “CR’s” internal representation might be cached & saved beyond one app’s execution & existence. Note – the DD stores NO information about cursors
14
Explicit vs. Implicit cursors
The life cycle for an explicit cursor is shown below Definition in source Operations/Actions during cursor PL/SQL code (in the execution time DECLARE section) An implicit cursor example – x is an implicit cursor, and does not need to be declared There is an error in this example – can you find it? declare 2 v_rowCount number; -- Init table row count 3 4 begin 5 for x in ( select * from t ) 6 loop 7 v_rowCount := v_rowCount+1; 8 end loop; 9 dbms_output.put_line('Table rowCount is ' || v_rowCount); 10 end;
15
SQL Standard defined Actions on explicit Cursors
The first model/form of cursor usage follows the familiar simple model of I/O programming: 1. Open an existing file “f”, and execute a loop. 2. The loop body has code to 1) read next record “r” from f and 2) process contents of r. OPEN CursorName(args); – successful call enables access to “first” row of the active data set; “active” is meaningful because a row can be referenced by > 1 cursor (the active cursor is THE one of n cursors currently being processed by app code) Values in the rows returned in the cursor can be retrieved into PL/SQL variables for arbitrary application ‘processing’ ‘processing’ best done in a 3GL and/or not suited for SQL During cursor row extraction into PL/SQL (via SELECT into), the number of columns in the SELECT’s result row schema must be matched by the PL/SQL variables receiving data A PL/SQL LOOP control statement can be executed, and in the loop body, individual rows are retrieved using an FETCH statement and then each row is processed by 3GL application code < - - Like file system op. 2. at top of this slide A cursor is closed using CLOSE CursorName; A cursor can be OPENED/CLOSED n times, during a PL/SQL module’s execution Caution – a specific cursor usage might involve necessary conditions: Example: IF C_Emp%FOUND THEN … throws an error if C_EMP is currently closed
16
Explicit cursor FETCH usage, and attributes;
FETCH CursorName INTO VariableList or RecordName; Retrieves the current row in the active cursor set into specified variables, and then, current cursor automatically positions to “next” row, if a next row exists Ex: FETCH employee_cur INTO v_ssn, v_sal; < - - Store row’s columns in 2 PL/SQL variables OR (and often preferred) FETCH employee_cur INTO emp_rec; < - - Store into a PL/SQL record In this example, emp_rec is a record structure declared using a %ROWTYPE declaration (covered soon) CURSOR attributes – coded as: CursorName%CursorAttributeName - %ISOPEN - returns TRUE if cursor is open Ex: cursorName%ISOPEN - %FOUND - returns TRUE if last FETCH returned a row, and complementary attribute is: %NOTFOUND - %ROWCOUNT - returns total number of rows that have been accessed with this cursor since most-recent OPEN Cursors & iteration FOR RecordName IN CursorName LOOP : loop statements; END LOOP; RecordName is either an implicitly declared record with an implicit FETCH (not covered in 204), or an explicitly declared “rowType” variable. In the body of FOR RecordName, storage of row items is done with syntax RecordName.item (where item is, for example, a columnName, and RecordName is the same format as a cursor row) Two types of cursors based on effect on DB itself: read-only - can only read and use 3GL code to calculate in 3GL and updatable – data obtained from cursor rows can be modified by 3GL code and written back to the DB, thus modifying DB content
17
Cursor parameters, and a read-only cursor example
A cursor can be declared with parameters. Parameters provide for more flexible cursors - Use of parameter values for parts of cursor’s queries - Passing different parameters at various OPENs (cursor re-use within one database session) CURSOR CursorName [(Parameter1 DataType, Parameter2 DataType, …)] IS SELECT query; Parameter values can be passed to a cursor as literals, PL/SQL expressions or bind variables First example of: PL/SLQ CURSOR PROCESSING with a read-only cursor (the default cursor kind) undefine dnum (removes any current copy of dnum from previous module executions) DECLARE employee_rec employee_cur%ROWTYPE; (It is legal to reference a cursor’s row type before the cursor definition) CURSOR employee_cur (dept_id company.employee.dno%TYPE) IS SELECT * FROM e WHERE dno = dept_id; dept_num e.dno%type :=&&dnum; -- Automatic prompt for department number; input value assigned to dept_num BEGIN OPEN employee_cur (dept_num); Passing an actual parameter for a dept_id value DBMS_OUTPUT.PUT_LINE('Name and salary of employes in Dept: ' || dept_num); FETCH employee_cur into employee_rec; e.salary type: number (10,2), WHILE employee_cur%FOUND LOOP but TO_CHAR type conversions is DBMS_OUTPUT.PUT_LINE not actually needed here (employee_rec.lname || ‘,’ || employee_rec.fname || ‘makes’ || TO_CHAR(employee_rec.salary)); FETCH employee_cur into employee_rec; END LOOP ; CLOSE employee_cur; END; / show errors Example parameter init: CURSOR employee_cur (dept_id company.employee.DeptId%TYPE := 99) IS The above code version at course homePage: cursor_parameters_demo.plsql
18
Updatable cursor example
UPDATE and DELETE on cursor row data can be performed on fetched rows CURSOR CursorName IS SELECT ColumnNames FROM TableName [ WHERE condition ] [ FOR UPDATE [of ColumnNames] [NOWAIT] ]; 1. The FOR UPDATE specifies intention to update in the database some cursor rows 2. If NOWAIT is specified, you are notified immediately if another tr holds a lock on >=1 row of cursor data = > your exception block will execute because control has returned to your app. After exception handled, your appl can do other processing, then, optionally, retry; = > the appl request is NOT QUEUED as happens with SQL-level row lock requests 3. Without NOWAIT, your app automatically WAITs until the other tr releases locks held on the cursor’s data; that is, your app’s tr is in a tr wait state With UPDATE or DELETE in a cursor is performed on the row(s) fetched. WHERE CURRENT OF clause allows manipulation of THE recently-fetched row: Assuming app does a commit;, these changes are written back to the database UPDATE TableName DELETE FROM TableName SET clause WHERE CURRENT OF CursorName; WHERE CURRENT OF CursorName; No Notification why you are paused…
19
Cursor variables A cursor is based on a specific query (aka static cursor), whereas A cursor variable can be used with different queries within a program (and thus acts like a pointer to a cursor) All of: OPEN, FETCH, %FOUND, etc. operators introduced earlier are available A given cursor variable can also be assigned to another cursor variable Creating a cursor variable involves 2 things: - create a referenced cursor type, as in: TYPE CursorTypeName IS REF CURSOR [RETURN ReturnType]; ReturnType can be a record or %ROWTYPE structure - declare a cursor variable CursorVarName CursorTypeName; Sample code: TYPE any_cursor_type IS REF_CURSOR; TYPE employee_cursor_type IS REF CURSOR RETURN company.employee%ROWTYPE; any_cursor_var any_cursor_type; employee_cursor_var employee_cursor_type; Cursor’s declared without a RETURN type are more flexible (don’t need to match query results to anything), but do not have any error checking associated with them. We will not use cursor reference variables / cursor variables in this course.
20
Exceptions In the PL/SQL language, errors are called exceptions
Exceptions can be caused by hardware/system/user/applications errors When an exception arises in a block, the PL/SQL program transfers to a section of that block specified by the EXCEPTION section for dealing with that exception: There are 3 situations:: - if an exception handler exists, its actions are performed AND the block is exited back to the containing block (if any), else return to caller of this module - if no exception handler exists in current block, control shifts to outer blocks and search for associated handlers in outer block(s) by inner-to-outer nesting order - if no handler exists in any outer block, an error msg is returned, run terminates, and control returns to caller of this module Recall syntax of anonymous blocks: DECLARE Declaration of constants, variables, cursors, exceptions ExceptionName1 exception; Example exception declaration BEGIN -- Suppose exception is raised here EXCEPTION -- Exception is processed here END; The general syntax of the exception section is: WHEN ExceptionName1 [OR ExceptionName2, … ] THEN Exception handler code Executable statements [WHEN ExceptionName3 [OR ExceptionName4, … ] THEN [WHEN OTHERS THEN Executable statements]
21
Exceptions - continued
In the PL/SQL language, there are 3 types of exceptions: - About 20 Oracle pre-defined and named (raised implicitly when a DBMS or PL/SQL error occurs) - Non-pre-defined Oracle server exceptions, standard Oracle server errors and non named - User-defined are declared in the DECLARE section and raised by user explicitly; user decides which abnormal conditions are exceptions Example EXCEPTION section code: EXCEPTION WHEN someExceptionName THEN … WHEN OTHERS THEN This catches any errors caused by failed statements : that are not handled by another part of this EXCEPTION section ROLLBACK TO q1_end; tr savepoints are also visible within an EXCEPTION block -- Pass Error Msg to log table DBMS_OUTPUT.PUT_LINE(SQLERRM); SQLERRM is pre-defined & returns SQL error codes DBMS_OUTPUT.PUT_LINE(' is Oracle Error Msg string sent to EXCEPTION block'); write_h7log(SQLERRM); END; / show errors A script example of Oracle tr savepoint processing is homePage file tp_savepoints_example.txt
22
Block nesting example with loop EXIT demo -- Source filename: plsqlBlockExitDemo.plsql
SQL> set echo on SQL> set serveroutput on SQL> declare 2 v_sum number := 0; 3 begin 4 declare 5 k number := 0; 6 begin 7 while k < 3 loop 8 dbms_output.put_line('Starting loop body with k = ' || k); 9 v_sum := v_sum + k; 10 if k = 2 then 11 dbms_output.put_line('Now exiting loop'); 12 exit; 13 end if; 14 k := k + 1; 15 end loop; 16 dbms_output.put_line('Finished inner-block execution'); 17 exception 18 when others then 19 dbms_output.put_line('Unhandled exception in inner block'); 20 end; 21 dbms_output.put_line('Final v_sum value is: ' || v_sum); 23 end; 24 / Starting loop body with k = 0 Starting loop body with k = 1 Starting loop body with k = 2 Now exiting loop Finished inner-block execution Final v_sum value is: 3 PL/SQL procedure successfully completed. (Omitted final ‘No errors’ message .)
23
Exceptions – continued: pragmas and raise_application_error
Outline of PL/SQL error handling in a PL/SQL anonymous block/proc/fcn; this is NOT a complete example. DECLARE < - - Opening declare for the entire nested anonymous block cursor xyz … : v_xyz_rec xyz%ROWTYPE; < - - One of any number of cursor rowtype (PL/SQL local) variables -- pragmas and exceptions rowsAreLocked EXCEPTION; PRAGMA EXCEPTION_INIT(rowsAreLocked, -54); < - - Pragmas and user-defined exceptions will not be needed in homeworks BEGIN /* In this main block, or in any nested block, the above cursor(s) and declarations are visible */ : code FOR LOOP loop to retry update cursor execution < -- Outer loop implements cursor execution retries : code FOR v_xyz_rec in xyz LOOP < -- Inner loop processes cursor rows . . v_xyz_rec.p < - - How the value of column “p” of the current cursor row is accessed . . . END LOOP; EXIT; < - - Terminate cursor execution and retries (but does NOT terminate entire module execution) EXCEPTION WHEN rowsAreLocked THEN All of the code for handling the rows locked exception END; WHEN OTHERS THEN -- Third argument TRUE in next call means: keep errors returned for any other cause from all stack levels raise_application_error(-20001, 'WHEN OTHERS exception occurred', TRUE); END LOOP; - - FOR loop to retry update cursor execution : code < - - Should be code in this part that reports: Exceeded cursor execution retry count END; < - - End of anonymous block
24
More on implicit cursors
An implicit cursor demo Implicit cursors occur frequently in practical 3GL apps that process data (large and small); many such cursors are executed in repetitive open cursor / execute / close cursor scenarios. The example to the left demos an implicit for update type cursor. Such cursor executions can consume large amounts of SQL resources, and doing so will impact other users on a DB server. h5 demonstrates how bind variables and cursor caching can greatly decrease cursor processing overhead and execution time. SQL> create table ctemp(c number); Table created. SQL> insert into ctemp values(1); 1 row created. SQL> commit; Commit complete. SQL> SQL> select * from ctemp; C 1 SQL> begin 2 for x in (select * from ctemp for update) 3 loop 4 update ctemp set c = -1; 6 end loop; 7 end; 8 / PL/SQL procedure successfully completed. SQL> /* Final table */ -1
25
SQL statement translation – Hard parse vs. Soft parse
If a session executes a SQL statement that does not exist in the shared pool, then Oracle must do a hard parse. Oracle must then: Allocate memory for the statement from the shared pool. Check the statement syntactically Check if the user trying to execute the statement has the necessary rights to execute it A hard parse is expensive in both terms of CPU used and number of shared pool latch and library cache latch it needs to acquire and release. It should be avoided whenever possible. Soft parse If a session executes an SQL statement that exists in the shared pool and there is a version of the statement that can be used, then this is referred to as a soft parse. Identical Statements? That is, can a cursor be shared/re-used? A statement is identical to another statement, if there is absolutely no difference between the letters. For example select x from y and SELECT X FROM Y are not identical, as text, although they clearly do the same thing. Even if two statements are identical, this doesn't mean they are shareable. In order for two identical statements to be shareable, the following must be true Object names must resolve the same actual objects The optimizer goal is the same Types and length of bind variables is similar The NLS environment is the same
26
SQL statement translation – Hard parse vs. Soft parse
The diagram visualizes major steps that are applies to each and every submitted Oracle SQL statement. If a SQL statement does a Soft parse most of the significant statement translation cost (Optimization & Query Transform) is avoided: such costs include excessive latching and shared pool memory processing. A Hard parse does all of the left-diagram’s operation except for Execution. Many believe that poor SQL performance is always due to excessive disk I/O. This is NOT true, particularly with excessive Hard parsing that will involve excessive CPU processing = > A DB can be CPU-bound just as it can be I/O-bound
27
The SQL/PSM ANSI standard
SQL/PSM is part of the SQL standard and specifies how to write persistent stored modules By persistent is meant: the ability to store in the DBMS (not in OS files) an executable form of a procedure/function (aka proc/fcn) The DD stores metadata about each proc/fcn, such as name, signature, validity (status such as VALID or INVALID, …), etc. In Oracle the user_objects DDview can be queried to see proc/fcn metadata With this and other views, SQL, rather than programmers, can manage (query/report/organize) these items, eliminating much tedious, error-prone work PL/SQL implements the PSM standard quite closely Elmasri&Navathe Textbook, Ch 9, section Edition#5) covers the SQL/PSM specification
28
PL/SQL stored procedures & functions
Up till now, the PL/SQL coding involved only anonymous blocks Although good for testing and proof-of-concept, and some other things listed below, they have many limitations: Anonymous blocks cannot be called by another block during execution (without a name there is no referencing/calling mechanism is possible) They cannot get arguments from another block They can, however call PL/SQL procedures and functions (both of which are named blocks with optional parameters) A given anonymous block can be nested within another anonymous block or a procedure or function Procedures and functions (in either PL/SQL or any 3GL) allow us to modularize PL/SQL code; procedures and functions: can be called either inside PL/SQL or at SQL*Plus level The following slides introduce stored procedures and functions as a more general and flexible structuring approach to the 3GL app code. It is a short summary of the basics that are scattered in many places in Oracle documentation and books.
29
PL/SQL stored procedures
A procedure is a named PL/SQL block that can have arbitrary programming logic. It has following general structure: CREATE [OR REPLACE] PROCEDURE ProcedureName [(parameter1 [,parameter2…]) ] IS [ Constant/Variable declarations ] BEGIN Executable statements [ EXCEPTION Exception handling statements ] END [ ProcedureName ]; The create procedure command indicates that , just as with tables, indexes, etc., a procedure is an object, and many of its properties stored in DD. Note – irregular syntax: unlike an anonymous block, there is no DECLARE statement in either a stored procedure or a stored function; simply place declarations following the IS reserved word Oracle identifier Parameters communicate info into and out of this proc Exception handling optional IS is a reserved word
30
PL/SQL stored procedures
Calling a stored procedure can be done within PL/SQL by: ProcedureName [ (parameter1, …) ]; Example calls: MONTHLY_SALARY(V_SALARY); DISPLAY_MSG; Parentheses not needed if no parameters Procedure Header CREATE OR REPLACE PROCEDURE monthly_salary (v_salary_in IN company.employee.salary%TYPE) CREATE OR REPLACE PROCEDURE display_msg Parameters are in 3 kinds: IN – passes a value in; read only (the default parameter mode) OUT – passes a value back to caller; write only IN OUT – (no space/blank after IN) passes a value in and returns a (possibly different) value back to caller
31
PL/SQL stored procedures
-- Procedure Call SEARCH_EMP( 543, LAST); -- Procedure Header PROCEDURE SEARCH_EMP(EMPNO IN NUMBER, LAST OUT VARCHAR2) Formal and actual parameters are associated/matched in 2 ways: - positionally - named (Example: in call statement, use notation EMPNO => 543) A compiled PL/SQL procedure can be called from SQL*Plus by: SQL> EXECUTE ProcedureName [ parameter1, … ] However, if you get an error (instead of results and ‘PL/SQL procedure successfully completed’), you can use following command to get information about the error(s): SQL> SHOW ERROR In fact, DD view user_errors gives error info about proc/fcn compilation, etc Recompiling a procedure A procedure cataloged in the DD becomes invalid if the tables it is based on are deleted or altered. You can recompile with create or replace … OR via: SQL> ALTER PROCEDURE ProcedureName COMPILE;
32
PL/SQL stored procedure – example definition & call
CREATE OR REPLACE PROCEDURE search_emp (i_ssn IN VARCHAR2, An employee ssn o_lname OUT VARCHAR2, -- An employee last name noData IN OUT BOOLEAN) -- True if SELECT INTO retrieves no data -- Note: parameter type declarations such as: char(9) give compile error in PL/SQL -- This is why i_ssn and o_lname are declared as shown (without max sizes) IS BEGIN SELECT lname INTO o_lname FROM e WHERE SSN = i_ssn; EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE('PK ' || i_ssn || ' was not found'); noData := TRUE; END search_emp; / show errors DECLARE Anonymous block driver module v_lname e.lname%TYPE; v_ssn varchar2(10) := &&emp_ssn; v_noData boolean := FALSE; search_emp(v_ssn, v_lname,v_noData); < - - search_emp call -- Display name only when data was found IF v_noDATA = FALSE THEN DBMS_OUTPUT.PUT_LINE('Employee with SSN: ' || v_ssn || ' name is: ' || v_lname); END IF; END; See class homePage file: demo_search_emp_example.plsql NO_DATA_FOUND is a built-in Oracle exception type recognized by all modules Parameter v_noData used to suppress the anon block PUT_LINE I/O when the query returned no data
33
PL/SQL stored functions
A function, like a stored procedure, is a named PL/SQL block. The main difference is that a function always returns a value to caller. Function properties - can be passed >= 0 parameters - must have a RETURN statement (returns a value) in the executable section (at least one RETURN statement must appear) - return value’s data type must be declared in function header’s RETURN clause - cannot be executed as a stand-alone program - can have IN, OUT, and IN OUT parameters, but use of OUT and IN OUT parameters is consider bad programming practice CREATE [OR REPLACE] FUNCTION FunctionName [ (parameter1 [,parameter2…]) ] < = Some other clauses are possible here (we will cover one of them) RETURN DataType IS [ Constant / Variable declarations ] BEGIN Executable statements RETURN ReturnValue [EXCEPTION exception handling statements RETURN ReturnValue ] END [ FunctionName ];
34
CREATE OR REPLACE FUNCTION get_deptname
PL/SQL functions CREATE OR REPLACE FUNCTION get_deptname (p_deptid IN NUMBER) RETURN VARCHAR2 IS v_deptname VARCHAR2 (12); BEGIN SELECT dname INTO v_deptname FROM department WHERE dnumber = p_deptid; RETURN v_deptname; END get_deptname; / show errors Example of calling get_deptname from a stream of SQL*Plus code:: set serveroutput on DECLARE -- Get employee’s ssn from user session via substitution variable v_dept# e.dnumber%TYPE; v_empid e.ssn%TYPE := &ssn; v_deptname VARCHAR2 (12); : v_deptname := get_deptname( v_dept# ); Complete Example PL/SQL procedure driver module that calls another stored procedure: plsql_procedures_and_calls_example.out Expression for department number, here assumed obtained by executing a SQL query above this source line
35
PL/SQL procs/fcns – execution definer’s rights and executer/caller rights (RE: security)
How the Privileges of a Schema Affect the Use of Invoker's Rights Procedures:: An invoker’s rights procedure is useful in situations where a lower-privileged user must execute a procedure owned by a higher-privileged user. When a user runs an invoker's rights procedure (or any PL/SQL program unit that has been created with the AUTHID CURRENT_USER clause), the procedure temporarily inherits all of the privileges of the calling user while the procedure runs, regardless of procedure owner. During execution, the procedure owner also has access to this invoking user's privileges. Usage example CREATE OR REPLACE FUNCTION fcnName (p_someName IN NUMBER) RETURN VARCHAR2 AUTHID CURRENT_USER IS . . .
36
PL/SQL functions – the DETERMINISTIC clause (execution semantics)
An example of an advanced clause that can be used with a PL/SQL stored fcn is DETERMINISTIC This is used in various advanced database purposes not covered in this course) CREATE OR REPLACE FUNCTION fcnName (p_someName IN NUMBER) RETURN VARCHAR2 DETERMINISTIC IS The DETERMINISTIC clause may appear at most once in a function declaration or definition. A function so marked is called deterministic. A deterministic function must return the same value on two distinct invocations if all IN and IN OUT arguments provided to the two invocations are the same. A DETERMINISTIC function may not have side effects. A DETERMINISTIC function may not raise an unhandled exception. If a function with a DETERMINISTIC clause violates any of these semantic rules, the results of its invocation, its value, and the effect on its invoker are all undefined. Usage Notes The DETERMINISTIC clause is an assertion that the function obeys the semantic rules. If the function does not, neither the compiler, SQL execution, or PL/SQL execution may diagnose the problem and incorrect results might be silently produced (that is, with no warning messages).
37
In Oracle, the 5 categories of triggers are
DB triggers – Intro A Trigger is the database analog of a systems programming “interrupt handler” procedure They are one form of Oracle implementation of SQL standard ASSERTION statement (As noted in E&N: No RDBMS vendor has fully implemented the ASSERTION statement) (+) there are useful things that can be done with triggers (-) triggers can be OVERused; any number of triggers per table is allowed BUT too many triggers will slow down table processing in big apps with big tables In Oracle, a trigger is a form of stored proc Uses: Internally in a DB, 1) reacting to pre-specified DB state changes 2) database auditing/logging Triggers have temporal specification: BEFORE trigger fires before operations like INSERT are executed Some Uses: * Ex: place pre-defined values into a new row (reduces complexity of INSERT commands) * Ex: validate a value in a row INSERT before actual insert is executed AFTER trigger fires after a DML statement is executed Some Uses: * Ex: could use to initiate some action(s) based on a DML statement type that just occurred Available built-in boolean fcns INSERTING, UPDATING and DELETING One of these will return TRUE depending on the type of DML statement; = = > allows different processing for different DML operations In Oracle, the 5 categories of triggers are 1) DML Relevant DD views: user_triggers, user_objects 2) INSTEAD OF – these fire instead of the corresponding DML operation, and are defined only on views (Ex: can be used to implement updates for a non-updatable view) – not covered here 3) DDL, Compound (new in oracle 11g), and SYSTEM – not covered in this course 37
38
Trigger clauses & specifications
We will limit trigger coverage in this course to DML statements on tables w. 11g capabilities Generally speaking, a trigger can be defined on table/view/schema/the DB objects Statement vs. Row-level trigger types – specifies the number of times that a trigger executes for a given SQL statement General Oracle trigger specification create or replace trigger <trigger_name> {before | after } {insert | update | update of column1 | delete} on <table_name> Each trigger is defined on only one table ! [ for each row ] IF missing, is a “statement” level trigger; IF present, is a “row-level” trigger [FOLLOWS | PRECEDES another_trigger] Added in Oracle version 11g to specify Order of firing among n triggers [ENABLE / DISABLE ] A trigger is enabled, by default, at creation, but ALTER TRIGGER triggerName DISABLE; disables it [ when (logical_expression) ] Conditions each row must satisfy in order for this trigger to affect this row [declare] No IS nor AS keyword used in Oracle trigger definition [pragma autonomous_transaction;] Allows possibility of creating a stand-alone support tr declaration_statements begin execution_statements end <trigger_name>; Statement Level trigger create or replace trigger price1_trig < = The trigger is fired ONE time after a SQL UPDATE stmt S executes, after update of price_type on price regardless of the number of rows changed by S declare No ‘FOR EACH ROW’ clause price_id number; begin select price_log_seq.nextval into price_id from dual; price_log_seq is an automatic PK generator insert into price_type_log values (price_id, USER, SYSDATE); end price1_trig; /
39
Trigger specifications – cont’d
Row Level trigger create or replace trigger contact_insert_trig before insert on contact for each row ‘FOR EACH ROW’ clause specifies firing trigger before each row is inserted when (Condition) begin processing statements; end contact_insert_trig; / Pseudo columns For a given SQL statement “S” that is DML (INSERT/DELETE/UPDATE) Pseudo-row values referring to old vs new versions of data are referenced in a way depending place used in trigger source code To refer to a value before S executes – Ex: original value of a column: old - used in the WHEN clause :old - used inside the trigger body Similarly, for pseudo-row new To refer to a value that would exist after S executes – Ex: changed value of a row column new – used in WHEN clause :new – used inside the trigger body old and new must make sense relative to the DML operation: For example, old is meaningless for INSERT old and new are both meaningful for UPDATE new is meaningless for DELETE
40
DML Triggers – Oracle implementation
Example of a BEFORE trigger: Prior to each row INSERT into table tbl, the column colx value is assigned as a copy of the PL/SQL variable v_colx; this will override any column default -- Filename: tbl_bi_trigger.plsql -- Purpose: Before trigger to put pre-determined value into data column of a table -- Usage: Ora user coding triggers must have create trigger privilege CREATE OR REPLACE TRIGGER tbl_bi_trigger Name can be any Ora namespace-legal -- Note: tablename aliases CANNOT be used here identifier -- If u do not have update privilege, you get an Ora error when referencing trigger target table BEFORE INSERT ON tbl FOR EACH ROW DECLARE v_colx tbl.c2%TYPE; BEGIN -- The value specified for current row's (when an INSERT is executed), colx col is assigned to v_colx -- This value could also be the value input to a Substitution variable (but would -- require a re-compile of the trigger) v_colx := ‘DogBone'; :NEW.c2 := v_colx; :OLD and :NEW reference a Changed vs. Existing item END; / show errors Example DML (here, INSERT) statement executions and result rows SQL> -- User-defined value, null value, and unspecified value SQL> INSERT into tbl VALUES (1,'Row#1'); 1 row created. SQL> INSERT into tbl VALUES (2,null); SQL> INSERT into tbl(c1) VALUES (3); 1 row created SQL> SELECT * from tbl; C1 C2 1 DogBone 2 DogBone 3 DogBone
41
Some notes on tr scope in PL/SQL modules
Multiple triggers per table; trigger firing order Note – the Oracle rules for trigger firing order are NOT standardized across RDBMSs; also other relational-like DBs like mySQL have their own DB-specific rules There can be any number of triggers defined on any given table. Question: What is the firing order when n triggers are defined & enabled on table T? Answer – Firing order is a combination of ‘category’ and randomized order: There are 4 categories, and their relative firing orders are: Statement level Before triggers - sb Row level Before triggers - rb Row level After triggers - ra Statement level After triggers - sa The default firing order Example: Given: 1 sb and 3 ra triggers on table T, firing order is: The sb and then, in random order, the 3 ra For Oracle 11g and newer: the clauses “FOLLOWS” and “PRECEDES” can be used for all triggers in a given category to order the firings (and override default order) Additional flexibility: one trigger can apply to MORE THAN ONE kind of DML statement, that is, a trigger can fire, for example, on table row INSERT or DELETE
42
Trigger use in apps + Example trigger demoing bad app coding practice
Important behaviors of Oracle DML triggers in tp context Trigger xyz’s execution does not commit the tr context containing xyz. If trigger xyz is rolled back, all data changed by xyz should also be rolled back. Commits, rollbacks and save points are not allowed in the trigger body. These DCL statements compile without error, but are fatal errors at execution time. Unhandled exceptions in a trigger will cause a rollback of the entire transaction, not just the trigger. { this is another reason for 3GL modules (stored proc/fcn/trigger) having EXCEPTION sections: to correctly Undo DB changes in case of execution errors } If more than one trigger is defined on an event, the order of firing has some randomness. If some triggers must fire in a specific order, you could create one trigger that executes all the actions in the required order. A trigger can cause other events to execute cascading triggers Example on next slide = > ============================================================================================== Very important RDBMS app Design Principle:: Each statement “S” in a trigger body should be such that S can be rolled back. Example of Incorrect behavior if this principle is violated: create or replace trigger xyz after insert on someTable for each row begin (post message m on socialMediaSite, message = > ‘ACME Inc. sold another house’); end; / Show errors xyz is bad programming because the Oracle tp system is NOT CONNECTED to any distributed tr system for social media What if 10 row updates are done on table someTable, but all these updates are rolled back ? = => 10 messages have been sent out to the world about events that never happened
43
Cascading triggers One trigger execution might result in other triggers also firing (cascading) One aspect of “trigger management” (assessing their OVERuse) is the DD views user_triggers and all_triggers
44
More notes on tr scope in PL/SQL modules
Calling/Called module tr scope A PL/SQL module “M” begins execution, and assume that tr “x” is also initiated along with M During execution of M and execution of any blocks that M calls, assume that no DCL/DDL commands (such as: COMMIT;, ROLLBACK; or create table, etc. ) are issued On return to M from any called module, tr x is still the current tr Triggers and DCL commands – do not use them together Triggers are, in one sense similar to hardware interrupts, intended to execute with as little overhead as possible. Also, COMMIT/ROLLBACK/savepoint should NOT appear in a trigger body (as previous slide showed) Recall that executing PL/SQL code (same as Oracle SQL at SQL*Plus command level) always has an associated ongoing transaction tr A trigger execution should NOT determine whether or not the tr terminates. Unfortunately, the PL/SQL translator does NOT throw an error at compile time, even if trigger body contains a DCL statement such as commit. Instead, a trigger execution-time error occurs when a DCL command is encountered in a trigger body: SQL> insert into a values (2,0); < - - Assume a trigger on table A contains a DCL command insert into A values (2,0) * ERROR at line 1: < - - The following Oracle software stack unwind is thrown ORA-04092: cannot COMMIT in a trigger ORA-06512: at "CS NODCL", line 2 ORA-04088: error during execution of trigger 'CS NODCL‘ Note: Autonomous trs provide a way for a user to log failed or committed DB changes
45
Trigger processing issue – mutating table errors
Def – a “mutating table” is a table that is currently undergoing changes in row content A row-level trigger cannot change a table (specifically, change >= 1 row) that the trigger also queries as well. Breaking this rule results in a mutating table error Note - There is no such problem/error with a statement level trigger Notes – “Mutating table” refers only to a table whose row content is currently changing a mutating table presents a conflict regarding the consistency of results of a SQL SELECT applied concurrently with the mutation Why Oracle throws an error when a trigger body queries a mutating table The Oracle SQL statement processing architecture guarantees: The execution of each statement S is atomic (all rows affected by S are processed) Each statement S must see a consistent view of data (by the principle of statement read-consistency) 1) and 2) are significant concerning row-level triggers Consider an INSERT affecting n rows for a row-level trigger; you would expect a query in such a trigger to see all the rows inserted as the trigger executes … Since the INSERT is not finished yet as successive rows are inserted, seeing m of n inserted rows would be an unpredictable read result Because of such ambiguities about the data set a query would access, Oracle throws a ‘mutating table error’ rather than allowing inconsistent/ambiguous SELECT results
46
Mutating table errors - demo
Consider the anonymous plsql block below – it initializes the demo -- mutating_table_error_demo_s18.plsql /* mutating_table_error_demo_s17.plsql */ drop table t purge; create table t (c number); insert into t values(1); insert into t values(2); insert into t values(4); commit; create or replace trigger t_trig after update on t for each row < - - Row level trigger declare v_t_tot t.c%type; begin select sum(c) into v_t_tot from t; < - - reading from the mutating table end; / show errors ============================================================================== SQL> update t < - - Trigger execution affects more than 1 row 2 set c = -1 where c> 1; update t * ERROR at line 1: ORA-04091: table CS T is mutating, trigger/function may not see it < - - Standard Oracle mutating table error ORA-06512: at "CS T_TRIG", line 4 ORA-04088: error during execution of trigger 'CS T_TRIG‘ ++ Add a dbms_output.put_line statement after the ‘select sum…’ query to see that v_tot is NOT modified by trigger execution, thus the effects of trigger body execution are discarded
47
This slide is intentionally blank
No title This slide is intentionally blank
48
This topic will not be covered in CSC204, fall 2019
Start PL/SQL packages This topic will not be covered in CSC204, fall 2019
49
PL/SQL packages A package is a collection of PL/SQL objects
Large-scale database applications should be developed as (one or more) PL/SQL package(s) Objects in a package are grouped within BEGIN END blocks Allowable package objects (* items will be covered later): - cursor - scalar variable - composite variable * - constant - exception names * - TYPE declarations for records* and tables - procedure - function Package objects can be declared as public or private (within the package) Object access can be just to the specification (allowing use/calls), but can hide the implementation code from users/callers Oracle implements many packages, among them: DBMS_OUTPUT, STANDARD, HTP, and many XML-related Each package must have a 1) specification and 2) body, aka 1) signature and 2) implementation
50
Package specification
CREATE [OR REPLACE] PACKAGE PackageName IS [ constant, variable, and type declarations ] [ exception declarations ] [ cursor specifications ] [ function specifications ] [procedure specifications ] END [ PackageName ]; Example: PACKAGE bb_team total_players CONSTANT INTEGER := 12; player_on_dl EXCEPTION; FUNCTION team_average (points IN NUMBER, players IN NUMBER) RETURN NUMBER; END bb_team;
51
Package body The body contains the code that implements the items described in the specification. In addition, there can be private/hidden elements (not visible outside of the package body), not in the specification, that must be implemented in the body. PACKAGE BODY PackageName IS [ variable and type declarations ] [ cursor specifications and SELECT queries ] [ specification and body of functions ] [ specification and body of procedures ] [ BEGIN executable statements ] [ EXCEPTION exception handlers ] END [ PackageName ]; Within a package body, you do not need to use dot notation to reference an object. However, you must use the dot notation to reference an object in another package. For example: IF bb_team.total_players < 10 THEN EXCEPTION WHEN bb_team.player_on_dl THEN
52
PL/SQL Package Code examples
Package body Rules for writing package body - Any item declared in the specification must not be declared again - The number of cursor and module definitions in the specification must match the number of cursor and module headers in the body - Any element declared in the specification can be referenced in the body - Body elements can be defined in any order PL/SQL Package Code examples Google returns almost an infinite number of hits for a search such as: ‘oracle package code examples’ The 2nd returned URL is:
53
Package use There are several very important reasons why packages should be used instead of a large group of stand-alone procedures & functions - Reduce or remove the effects of cascading invalidations *** (for example, a table change using alter table could cause recompilation of many other modules when not using a package) - More namespace repetition (instead of just one proc name “p”, you can have many “p” spread over many packages) - One package can contain many overloads of the same procedure, and package body details can be hidden within a package In more complex environments, Can have package variables that retain their values within a database session (that is, during a database connection) Package initialization code can be specified for the first time that a session references that package *** Procedure, function, view, trigger, etc, management becomes more complex with an increasing number of objects;
54
STATIC SQL AND DYNAMIC SQL will be covered in another MODULE
Similar presentations
© 2025 SlidePlayer.com Inc.
All rights reserved.