Escolar Documentos
Profissional Documentos
Cultura Documentos
Triggers Concepts - 2
BEFORE STATEMENT IS
BEGIN
...
END BEFORE STATEMENT;
BEFORE EACH ROW IS
BEGIN
...
END BEFORE EACH ROW;
AFTER STATEMENT IS
BEGIN
...
END AFTER STATEMENT;
AFTER EACH ROW IS
BEGIN
...
END AFTER EACH ROW;
END compound_trigger;
/
CREATE TABLE test AS
SELECT table_name, tablespace_name
FROM user_tables;
set serveroutput on
CREATE OR REPLACE TRIGGER compound_trig
FOR INSERT ON test
COMPOUND TRIGGER
------------------------------BEFORE STATEMENT IS
BEGIN
dbms_output.put_line('BEFORE STATEMENT LEVEL');
END BEFORE STATEMENT;
------------------------------BEFORE EACH ROW IS
BEGIN
dbms_output.put_line('BEFORE ROW LEVEL');
END BEFORE EACH ROW;
------------------------------AFTER STATEMENT IS
BEGIN
dbms_output.put_line('AFTER STATEMENT LEVEL');
END AFTER STATEMENT;
-------------------------------
String Functions
ASCII
Get The ASCII Value Of A Character
ASCII(ch VARCHAR2 CHARACTER SET ANY_CS) RETURN PLS_INTEGER;
SELECT ASCII('A') FROM dual;
SELECT ASCII('Z') FROM dual;
SELECT ASCII('a') FROM dual;
SELECT ASCII('z') FROM dual;
SELECT ASCII(' ') FROM dual;
CASE Related Functions
Upper Case UPPER(ch VARCHAR2 CHARACTER SET ANY_CS)
RETURN VARCHAR2 CHARACTER SET ch%CHARSET;
SELECT UPPER('Dan Morgan') FROM dual;
Lower Case LOWER(ch VARCHAR2 CHARACTER SET ANY_CS)
RETURN VARCHAR2 CHARACTER SET ch%CHARSET;
SELECT LOWER('Dan Morgan') FROM dual;
Initial Letter Upper Case INITCAP(ch VARCHAR2 CHARACTER SET ANY_CS)
RETURN VARCHAR2 CHARACTER SET ch%CHARSET;
SELECT INITCAP('DAN MORGAN') FROM dual;
NLS Upper Case NLS_UPPER()
SELECT NLS_UPPER('Dan Morgan', 'NLS_SORT = XDanish')
FROM dual;
NLS Lower Case NLS_LOWER()
SELECT NLS_LOWER('Dan Morgan', 'NLS_SORT = XFrench')
FROM dual;
NLS Initial Letter Upper Case NLS_INITCAP()
SELECT NLS_INITCAP('DAN MORGAN', 'NLS_SORT = XGerman')
FROM dual;
CHR
Character CHR(n PLS_INTEGER) RETURN VARCHAR2;
SELECT(CHR(68) CHR(65) CHR(78)) FROM dual;
INTO
INTO
INTO
INTO
test
test
test
test
VALUES
VALUES
VALUES
VALUES
FROM user_tables;
MIN
The Minimum String based on the current sort parameter MIN()
SELECT MIN(table_name)
FROM user_tables;
NLSSORT
Returns the string of bytes used to sort a string.
The string returned is of RAW data type NLSSORT(, 'NLS_SORT = );
CREATE TABLE test (name VARCHAR2(15));
INSERT INTO test VALUES ('Gaardiner');
INSERT INTO test VALUES ('Gaberd');
INSERT INTO test VALUES ('Grd');
COMMIT;
SELECT * FROM test ORDER BY name;
SELECT * FROM test
ORDER BY NLSSORT(name, 'NLS_SORT = XDanish');
SELECT * FROM test
ORDER BY NLSSORT(name, 'NLS_SORT = BINARY_CI');
Quote Delimiters
q used to define a quote delimiter for PL/SQL q'';
set serveroutput on
DECLARE
s1 VARCHAR2(20);
s2 VARCHAR2(20);
s3 VARCHAR2(20);
BEGIN
s1 := q'[Isn't this cool]';
s2 := q'"Isn't this cool"';
s3 := q'Isn't this cool';
dbms_output.put_line(s1);
dbms_output.put_line(s2);
dbms_output.put_line(s3);
END;
/
REVERSE
Reverse REVERSE()
SELECT REVERSE('Dan Morgan') FROM dual;
SELECT DUMP('Dan Morgan') FROM dual;
SELECT DUMP(REVERSE('Dan Morgan')) FROM dual;
RPAD
Right Pad
Overload 1 RPAD(str1 VARCHAR2 CHARACTER SET ANY_CS, len PLS_INTEGER,
pad VARCHAR2 CHARACTER SET STR1%CHARSET)
RETURN VARCHAR2 CHARACTER SET STR1%CHARSET;
SELECT RPAD('Dan Morgan', 25, 'x') FROM dual;
Overload 2 RPAD(str1 VARCHAR2 CHARACTER SET ANY_CS, len PLS_INTEGER)
RETURN VARCHAR2 CHARACTER SET STR1%CHARSET;
SELECT RPAD('Dan Morgan', 25) '<-' FROM dual; RTRIM Right Trim Overload 1 RTRIM( str1
VARCHAR2 CHARACTER SET ANY_CS := ' ', tset VARCHAR2 CHARACTER SET
STR1%CHARSET) RETURN VARCHAR2 CHARACTER SET STR1%CHARSET; SELECT '->'
RTRIM(' Dan Morganxxx') '<-' FROM dual; SELECT '->' RTRIM(' Dan Morganxxx', 'xxx') '<-'
FROM dual; Overload 2 RTRIM( str1 VARCHAR2 CHARACTER SET ANY_CS := ' ') RETURN
VARCHAR2 CHARACTER SET STR1%CHARSET; SELECT '->' RTRIM(' Dan Morgan ') '<-'
FROM dual; SOUNDEX Returns Character String Containing The Phonetic Representation Of
Another String Rules: Retain the first letter of the string and remove all other occurrences of
the following letters: a, e, h, i, o, u, w, y Assign numbers to the remaining letters (after the
first) as follows: b, f, p, v = 1 c, g, j, k, q, s, x, z = 2 d, t = 3 l = 4 m, n = 5 r = 6 If two or
more letters with the same number were adjacent in the original name (before step 1), or
adjacent except for any intervening h and w, then omit all but the first. Return the first four
bytes padded with 0. SOUNDEX(ch VARCHAR2 CHARACTER SET ANY_CS) RETURN
VARCHAR2 CHARACTER SET ch%CHARSET; CREATE TABLE test ( namecol VARCHAR2(15));
INSERT INTO test (namecol) VALUES ('Smith'); INSERT INTO test (namecol) VALUES
('Smyth'); INSERT INTO test (namecol) VALUES ('Smythe'); INSERT INTO test (namecol)
VALUES ('Smither'); INSERT INTO test (namecol) VALUES ('Smidt'); INSERT INTO test
(namecol) VALUES ('Smick'); INSERT INTO test (namecol) VALUES ('Smiff'); COMMIT;
SELECT name, SOUNDEX(namecol) FROM test; SELECT * FROM test WHERE
SOUNDEX(namecol) = SOUNDEX('SMITH'); SUBSTR See links at page bottom SUBSTRB
Returns a substring counting bytes rather than characters SUBSTRB( STR1 VARCHAR2
CHARACTER SET ANY_CS, POS PLS_INTEGER, -- starting position LEN PLS_INTEGER :=
2147483647) -- number of characters RETURN VARCHAR2 CHARACTER SET
STR1%CHARSET; SUBSTRC( STR1 VARCHAR2 CHARACTER SET ANY_CS, POS
PLS_INTEGER, -- starting position LEN PLS_INTEGER := 2147483647) -- number of
characters RETURN VARCHAR2 CHARACTER SET STR1%CHARSET; SUBSTR2( STR1
VARCHAR2 CHARACTER SET ANY_CS, POS PLS_INTEGER, -- starting position LEN
PLS_INTEGER := 2147483647) -- number of characters RETURN VARCHAR2 CHARACTER
SET STR1%CHARSET; SUBSTR4( STR1 VARCHAR2 CHARACTER SET ANY_CS, POS
PLS_INTEGER, -- starting position LEN PLS_INTEGER := 2147483647) -- number of
characters RETURN VARCHAR2 CHARACTER SET STR1%CHARSET;
TREAT Changes The Declared Type Of An Expression TREAT ( AS REF schema.type))
SELECT name, TREAT(VALUE(p) AS employee_t).salary SALARY
FROM persons p;
TRIM (variations are LTRIM and RTRIM)
Trim Spaces TRIM()
SELECT ' Dan Morgan ' FROM dual;
SELECT TRIM(' Dan Morgan ') FROM dual;
Trim Other Characters TRIM( FROM )
SELECT TRIM('D' FROM 'Dan Morgan') FROM dual;
Trim By CHR value TRIM()
SELECT ASCII(SUBSTR('Dan Morgan',1,1)) FROM dual;
SELECT SUBSTR(, )
FROM dual;
SELECT SUBSTR('Take the first four characters', 16) SIXTEEN_TO_END
FROM dual;
SELECT SUBSTR('Take the first four characters', -4) FINAL_FOUR
FROM dual;
INSTR (Instring) Built-in String Function
INSTR (overload 1)
INSTR(
STR1 VARCHAR2 CHARACTER SET ANY_CS, -- test string
STR2 VARCHAR2 CHARACTER SET STR1%CHARSET, -- string to locate
POS PLS_INTEGER := 1, -- position
NTH POSITIVE := 1) -- occurrence number
RETURN PLS_INTEGER;
INSTR (overload 2)
INSTR(
STR1 CLOB CHARACTER SET ANY_CS, -- test string
STR2 CLOB CHARACTER SET STR1%CHARSET, -- string to locate
POS INTEGER := 1, -- position
NTH POSITIVE := 1) -- occurrence number
RETURN INTEGER;
Instring For Matching First Value Found
SELECT INSTR(, , ,
FROM dual;
SELECT INSTR('Take the first four characters', 'a', 1, 1) FOUND_1
FROM dual;
Instring If No Matching Second Value Found
SELECT INSTR('Take the first four characters', 'a', 1, 2) FOUND_2
FROM dual;
Instring For Multiple Characters
SELECT INSTR('Take the first four characters', 'four', 1, 1) MCHARS
FROM dual;
Reverse Direction Search
SELECT INSTR('Take the first four characters', 'a', -1, 1) REV_SRCH
FROM dual;
Reverse Direction Search Second Match
y NUMBER := NULL;
BEGIN
IF x != y THEN -- yields NULL, not TRUE
dbms_output.put_line('x != y'); -- not executed
ELSIF x = y THEN -- also yields NULL
dbms_output.put_line('x = y');
ELSE
dbms_output.put_line('Can''t tell if x and y are equal or not...');
END IF;
END;
/
In the next example, you might expect the sequence of statements to execute because a and b
seem equal. But, again, that is unknown, so the IF condition yields NULL and the sequence of
statements is bypassed.
DECLARE
a NUMBER := NULL;
b NUMBER := NULL;
BEGIN
IF a = b THEN -- yields NULL, not TRUE
dbms_output.put_line('a = b'); -- not executed
ELSIF a != b THEN -- yields NULL, not TRUE
dbms_output.put_line('a != b'); -- not executed
ELSE
dbms_output.put_line('Can''t tell if two NULLs are equal');
END IF;
END;
/
NULLs and the NOT Operator
Recall that applying the logical operator NOT to a null yields NULL. Thus, the following two
statements are not always equivalent:
IF x > y THEN | IF NOT x > y THEN
high := x; | high := y;
ELSE | ELSE
high := y; | high := x;
END IF; | END IF;
The sequence of statements in the ELSE clause is executed when the IF condition yields FALSE
or NULL. If neither x nor y is null, both IF statements assign the same value to high. However, if
either x or y is null, the first IF statement assigns the value of y to high, but the second IF
statement assigns the value of x to high.
NULLs and Zero-Length Strings
PL/SQL treats any zero-length string like a null. This includes values returned by character
functions and Boolean expressions. For example, the following statements assign nulls to the
target variables:
DECLARE
null_string VARCHAR2(80) := TO_CHAR('');
address VARCHAR2(80);
zip_code VARCHAR2(80) := SUBSTR(address, 25, 0);
name VARCHAR2(80);
valid BOOLEAN := (name != '');
BEGIN
NULL;
END;
/
Use the IS NULL operator to test for null strings, as follows:
IF my_string IS NULL THEN ...
NULLs and the Concatenation Operator
The concatenation operator ignores null operands. For example, the expression
'apple' || NULL || NULL || 'sauce'
returns the following value:
'applesauce'
NULLs as Arguments to Built-In Functions
If a null argument is passed to a built-in function, a null is returned except in the following cases.
The function DECODE compares its first argument to one or more search expressions, which are
paired with result expressions. Any search or result expression can be null. If a search is
successful, the corresponding result is returned. In the following example, if the column rating is
null, DECODE returns the value 1000:
DECLARE
the_manager VARCHAR2(40);
name employees.last_name%TYPE;
BEGIN
-- NULL is a valid argument to DECODE. In this case, manager_id is null
-- and the DECODE function returns 'nobody'.
SELECT DECODE(manager_id, NULL, 'nobody', 'somebody'), last_name
INTO the_manager, name FROM employees WHERE employee_id = 100;
dbms_output.put_line(name || ' is managed by ' || the_manager);
END;
/
The function NVL returns the value of its second argument if its first argument is null. In the
following example, if the column specified in the query is null, the function returns the value -1
to signify a non-existent employee in the output:
DECLARE
the_manager employees.manager_id%TYPE;
name employees.last_name%TYPE;
BEGIN
-- NULL is a valid argument to NVL. In this case, manager_id is null
-- and the NVL function returns -1.
SELECT NVL(manager_id, -1), last_name
INTO the_manager, name FROM employees WHERE employee_id = 100;
dbms_output.put_line(name || ' is managed by employee #' || the_manager);
END;
/
The function REPLACE returns the value of its first argument if its second argument is null,
whether the optional third argument is present or not. For example, the following call to
REPLACE does not make any change to the value of OLD_STRING:
DECLARE
string_type VARCHAR2(60);
old_string string_type%TYPE := 'Apples and oranges';
my_string string_type%TYPE := 'more apples';
-- NULL is a valid argument to REPLACE, but does not match
-- anything so no replacement is done.
new_string string_type%TYPE := REPLACE(old_string, NULL, my_string);
BEGIN
dbms_output.put_line('Old string = ' || old_string);
dbms_output.put_line('New string = ' || new_string);
END;
/
If its third argument is null, REPLACE returns its first argument with every occurrence of its
second argument removed. For example, the following call to REPLACE removes all the dashes
from DASHED_STRING, instead of changing them to another character:
DECLARE
string_type VARCHAR2(60);
dashed string_type%TYPE := 'Gold-i-locks';
-- When the substitution text for REPLACE is NULL,
-- the text being replaced is deleted.
name string_type%TYPE := REPLACE(dashed, '-', NULL);
BEGIN
dbms_output.put_line('Dashed name = ' || dashed);
dbms_output.put_line('Dashes removed = ' || name);
END;
/
If its second and third arguments are null, REPLACE just returns its first argument.
PL/SQL -Advantages
Advantages of PL/SQL
PL/SQL is a completely portable, high-performance transaction processing language that offers
the following advantages:
Support for SQL
Support for object-oriented programming
Better performance
Higher productivity
Full portability
Tight integration with Oracle
Tight security
Tight Integration with SQL
The PL/SQL language is tightly integrated with SQL. You do not have to translate between SQL
and PL/SQL datatypes: a NUMBER or VARCHAR2 column in the database is stored in a
NUMBER or VARCHAR2 variable in PL/SQL. This integration saves you both learning time
and processing time. Special PL/SQL language features let you work with table columns and
rows without specifying the datatypes, saving on maintenance work when the table definitions
change.
Running a SQL query and processing the result set is as easy in PL/SQL as opening a text file
and processing each line in popular scripting languages.
Using PL/SQL to access metadata about database objects and handle database error conditions,
you can write utility programs for database administration that are reliable and produce readable
output about the success of each operation.
Many database features, such as triggers and object types, make use of PL/SQL. You can write
the bodies of triggers and methods for object types in PL/SQL.
Support for SQL
SQL has become the standard database language because it is flexible, powerful, and easy to
learn. A few English-like commands such as SELECT, INSERT, UPDATE, and DELETE make it
easy to manipulate the data stored in a relational database.
PL/SQL lets you use all the SQL data manipulation, cursor control, and transaction control
commands, as well as all the SQL functions, operators, and pseudocolumns. This extensive SQL
support lets you manipulate Oracle data flexibly and safely. Also, PL/SQL fully supports SQL
datatypes, reducing the need to convert data passed between your applications and the database.
PL/SQL also supports dynamic SQL, a programming technique that makes your applications
more flexible and versatile. Your programs can build and process SQL data definition, data
control, and session control statements at run time, without knowing details such as table names
and WHERE clauses in advance.
Better Performance
Without PL/SQL, Oracle must process SQL statements one at a time. Programs that issue many
SQL statements require multiple calls to the database, resulting in significant network and
performance overhead.
With PL/SQL, an entire block of statements can be sent to Oracle at one time. This can
drastically reduce network traffic between the database and an application. PL/SQL even has
language features to further speed up SQL statements that are issued inside a loop.
PL/SQL stored procedures are compiled once and stored in executable form, so procedure calls
are efficient. Because stored procedures execute in the database server, a single call over the
network can start a large job. This division of work reduces network traffic and improves
response times. Stored procedures are cached and shared among users, which lowers memory
requirements and invocation overhead.
Higher Productivity
PL/SQL extends tools such as Oracle Forms and Oracle Reports. With PL/SQL in these tools,
you can use familiar language constructs to build applications. For example, you can use an
entire PL/SQL block in an Oracle Forms trigger, instead of multiple trigger steps, macros, or user
exits.
PL/SQL is the same in all environments. Once you learn PL/SQL with one Oracle tool, you can
transfer your knowledge to other tools.
Full Portability
Applications written in PL/SQL can run on any operating system and platform where the Oracle
database runs. With PL/SQL, you can write portable program libraries and reuse them in
different environments.
Tight Security
PL/SQL stored procedures move application code from the client to the server, where you can
protect it from tampering, hide the internal details, and restrict who has access. For example, you
can grant users access to a procedure that updates a table, but not grant them access to the table
itself or to the text of the UPDATE statement.
Triggers written in PL/SQL can control or record changes to data, making sure that all changes
obey your business rules.
Support for Object-Oriented Programming
Object types are an ideal object-oriented modeling tool, which you can use to reduce the cost and
time required to build complex applications. Besides allowing you to create software
components that are modular, maintainable, and reusable, object types allow different teams of
programmers to develop software components concurrently.
By encapsulating operations with data, object types let you move data-maintenance code out of
SQL scripts and PL/SQL blocks into methods. Also, object types hide implementation details, so
that you can change the details without affecting client programs.
In addition, object types allow for realistic data modeling. Complex real-world entities and
relationships map directly into object types. This direct mapping helps your programs better
reflect the world they are trying to simulate.
PL/SQL Packages
PL/SQL Packages
A package is an encapsulated collection of related program objects (for example, procedures,
functions, variables, constants, cursors, and exceptions) stored together in the database.
Using packages is an alternative to creating procedures and functions as standalone schema
objects. Packages have many advantages over standalone procedures and functions. For example,
they:
Let you organize your application development more efficiently.
Let you grant privileges more efficiently.
Let you modify package objects without recompiling dependent schema objects.
Enable Oracle Database to read multiple package objects into memory at once.
Can contain global variables and cursors that are available to all procedures and functions in the
package.
Let you overload procedures or functions. Overloading a procedure means creating multiple
procedures with the same name in the same package, each taking arguments of different number
or datatype.
The specification part of a package declares the public types, variables, constants, and
subprograms that are visible outside the immediate scope of the package. The body of a package
defines the objects declared in the specification, as well as private objects that are not visible to
applications outside the package.
Example of a PL/SQL Package Specification and Body
The following example shows a package specification for a package named
Employee_management. The package contains one stored function and two stored procedures.
The body for this package defines the function and the procedures:
CREATE PACKAGE BODY Employee_management AS
FUNCTION Hire_emp (Name VARCHAR2, Job VARCHAR2,
Mgr NUMBER, Hiredate DATE, Sal NUMBER, Comm NUMBER,
Deptno NUMBER) RETURN NUMBER IS
New_empno NUMBER(10);
-- This function accepts all arguments for the fields in
-- the employee table except for the employee number.
-- A value for this field is supplied by a sequence.
-- The function returns the sequence number generated
-- by the call to this function.
BEGIN
SELECT Emp_sequence.NEXTVAL INTO New_empno FROM dual;
INSERT INTO Emp_tab VALUES (New_empno, Name, Job, Mgr,
Hiredate, Sal, Comm, Deptno);
RETURN (New_empno);
END Hire_emp;
PROCEDURE fire_emp(emp_id IN NUMBER) AS
-- This procedure deletes the employee with an employee
-- number that corresponds to the argument Emp_id. If
-- no employee is found, then an exception is raised.
BEGIN
DELETE FROM Emp_tab WHERE Empno = Emp_id;
IF SQL%NOTFOUND THEN
Raise_application_error(-20011, 'Invalid Employee
Number: ' || TO_CHAR(Emp_id));
END IF;
END fire_emp;
PROCEDURE Sal_raise (Emp_id IN NUMBER, Sal_incr IN NUMBER) AS
-- This procedure accepts two arguments. Emp_id is a
-- number that corresponds to an employee number.
-- SAL_INCR is the amount by which to increase the
-- employee's salary. If employee exists, then update
-- salary with increase.
BEGIN
UPDATE Emp_tab
SET Sal = Sal + Sal_incr
WHERE Empno = Emp_id;
IF SQL%NOTFOUND THEN
Raise_application_error(-20011, 'Invalid Employee
Number: ' || TO_CHAR(Emp_id));
END IF;
END Sal_raise;
END Employee_management;
-------------------------------------------------------------------------------Note:
If you want to try this example, then first create the sequence number Emp_sequence. Do this
with the following SQL*Plus statement:
SQL> CREATE SEQUENCE Emp_sequence
> START WITH 8000 INCREMENT BY 10;
Creating Packages
Each part of a package is created with a different statement. Create the package specification
using the CREATE PACKAGE statement. The CREATE PACKAGE statement declares public
package objects.
To create a package body, use the CREATE PACKAGE BODY statement. The CREATE
PACKAGE BODY statement defines the procedural code of the public procedures and functions
declared in the package specification.
You can also define private, or local, package procedures, functions, and variables in a package
body. These objects can only be accessed by other procedures and functions in the body of the
same package. They are not visible to external users, regardless of the privileges they hold.
It is often more convenient to add the OR REPLACE clause in the CREATE PACKAGE or
CREATE PACKAGE BODY statements when you are first developing your application. The
effect of this option is to drop the package or the package body without warning. The CREATE
statements would then be the following:
CREATE OR REPLACE PACKAGE Package_name AS ...
and
CREATE OR REPLACE PACKAGE BODY Package_name AS ...
Creating Packaged Objects
The body of a package can contain include:
Procedures and functions declared in the package specification.
Definitions of cursors declared in the package specification.
Local procedures and functions, not declared in the package specification.
Local variables.
Procedures, functions, cursors, and variables that are declared in the package specification are
global. They can be called, or used, by external users that have EXECUTE permission for the
package or that have EXECUTE ANY PROCEDURE privileges.
When you create the package body, make sure that each procedure that you define in the body
has the same parameters, by name, datatype, and mode, as the declaration in the package
specification. For functions in the package body, the parameters and the return type must agree in
name and type.
Privileges to Create or Drop Packages
The privileges required to create or drop a package specification or package body are the same as
those required to create or drop a standalone procedure or function.