ocl3 oracle 10 g : sql & pl/sql session #9
DESCRIPTION
OCL3 Oracle 10 g : SQL & PL/SQL Session #9. Matthew P. Johnson CISDD, CUNY June, 2005. Agenda. Triggers Transactions Oracle’s bulk loader Go over some labs Do some more labs. New topic: Triggers. PL/SQL programs that run automatically (are “triggered”) when a certain event occurs - PowerPoint PPT PresentationTRANSCRIPT
1Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
OCL3 Oracle 10g:SQL & PL/SQLSession #9
Matthew P. Johnson
CISDD, CUNY
June, 2005
2Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
Agenda Triggers Transactions Oracle’s bulk loader
Go over some labs Do some more labs
3Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
New topic: Triggers PL/SQL programs that run automatically (are
“triggered”) when a certain event occurs
E.g.: on insert to some table On system start-up On delete from table
Big benefit: need not be called explicitly However row in table x is deleted, the trigger
gets called
4Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
Trigger events Trigger code may be “triggered” by many kinds of
events: Oracle start-up/shut-down
Triggers may replace initialization scripts
Data updates: Delete: maybe delete related rows Inserts Updates: maybe make other rows consistent Delete: maybe prevent
DDL statements Log creation of all objects, e.g.
5Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
Triggers Constraints state what must remain true
DBMS decides when to check Triggers are instructions to perform at explicitly
specified times
Three aspects: An event (e.g., update to an attribute) A condition (e.g., a test of that update value) An action (the trigger’s effect) (deletion, update, insertion)
When the event occurs, DBMS checks the constraint, and if it is satisfied, performs the action
6Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
DML trigger options The trigger may be:
Statement-level (e.g., a DELETE WHERE statement) or Row-level (e.g., for each row deleted)
The trigger may run BEFORE AFTER or INSTEAD OF the statement (in Oracle, not in others)
It may be triggered by INSERTs UPDATEs DELETEs
7Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
Trigger formCREATE [OR REPLACE] TRIGGER trigger name{BEFORE | AFTER | INSTEAD OF} {INSERT | DELETE | UPDATE | UPDATE OF column list} ON table name[FOR EACH ROW][WHEN (...)][DECLARE ... ]BEGIN ... executable statements ...[EXCEPTION ... ]END [trigger name];
CREATE [OR REPLACE] TRIGGER trigger name{BEFORE | AFTER | INSTEAD OF} {INSERT | DELETE | UPDATE | UPDATE OF column list} ON table name[FOR EACH ROW][WHEN (...)][DECLARE ... ]BEGIN ... executable statements ...[EXCEPTION ... ]END [trigger name];
8Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
Trigger type examples First run copy_tables.sql
1. statement_vs_row.sql INSERT INTO to_table SELECT * FROM from_table;
2. before_vs_after.sql INSERT INTO to_table SELECT * FROM from_table;
3. one_trigger_per_type.sql INSERT INTO to_table VALUES (1);
UPDATE to_table SET col1 = 10;DELETE to_table;
9Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
DML Trigger e.g.
Q: Why is this (maybe) better than client-side validation?
CREATE OR REPLACE TRIGGER validate_employee_changes BEFORE INSERT OR UPDATE ON employee FOR EACH ROWBEGIN check_age (:NEW.date_of_birth); check_resume (:NEW.resume);END;
CREATE OR REPLACE TRIGGER validate_employee_changes BEFORE INSERT OR UPDATE ON employee FOR EACH ROWBEGIN check_age (:NEW.date_of_birth); check_resume (:NEW.resume);END;
10Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
Triggers with WHEN
NB: WHEN applies only to row-level triggers
CREATE OR REPLACE TRIGGER check_raise AFTER UPDATE OF salary, commission ON employee FOR EACH ROWWHEN ((OLD.salary != NEW.salary OR (OLD.salary IS NULL AND NEW.salary IS NULL)) OR (OLD.commission != NEW.commission OR (OLD.commission IS NULL AND NEW.commission IS NULL)))BEGIN ...END;
CREATE OR REPLACE TRIGGER check_raise AFTER UPDATE OF salary, commission ON employee FOR EACH ROWWHEN ((OLD.salary != NEW.salary OR (OLD.salary IS NULL AND NEW.salary IS NULL)) OR (OLD.commission != NEW.commission OR (OLD.commission IS NULL AND NEW.commission IS NULL)))BEGIN ...END;
11Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
Triggers with WHEN Parentheses are required Can only call built-in functions in when
Packages like DBMS_OUTPUT are not allowed
CREATE OR REPLACE TRIGGER valid_when_clauseBEFORE INSERT ON frameFOR EACH ROWWHEN ( TO_CHAR(SYSDATE,'HH24') BETWEEN 9 AND 17 ) ...
CREATE OR REPLACE TRIGGER valid_when_clauseBEFORE INSERT ON frameFOR EACH ROWWHEN ( TO_CHAR(SYSDATE,'HH24') BETWEEN 9 AND 17 ) ...
12Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
Simple trigger example R(id, data, last-modified)
data is a large string Last-modified is a newly added date field
Goal: whenever data is modified, update last-modified date
Could modify all scripts/programs that touch this table Bad idea
Better: user a trigger
CREATE TRIGGER UpdateDateTriggerAFTER UPDATE OF data ON R
REFERENCING
NEW ROW AS NewTupleFOR EACH ROWBEGIN
NewTuple.last-modified = sysdate;END;
CREATE TRIGGER UpdateDateTriggerAFTER UPDATE OF data ON R
REFERENCING
NEW ROW AS NewTupleFOR EACH ROWBEGIN
NewTuple.last-modified = sysdate;END;
13Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
Multiple DML actions DML actions may be ORed together
CREATE OR REPLACE TRIGGER three_for_the_price_of_oneBEFORE DELETE OR INSERT OR UPDATE ON account_transactionFOR EACH ROWBEGINIF INSERTING THEN :NEW.created_by := USER; :NEW.created_date := SYSDATE;ELSIF DELETING THEN audit_deletion(USER,SYSDATE);END;
CREATE OR REPLACE TRIGGER three_for_the_price_of_oneBEFORE DELETE OR INSERT OR UPDATE ON account_transactionFOR EACH ROWBEGINIF INSERTING THEN :NEW.created_by := USER; :NEW.created_date := SYSDATE;ELSIF DELETING THEN audit_deletion(USER,SYSDATE);END;
To find actual action, check: INSERTING DELETING UPDATING
14Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
More on UPDATING UPDATING may be called for partic. columns
CREATE OR REPLACE TRIGGER validate_updateBEFORE UPDATE ON account_transactionFOR EACH ROWBEGIN IF UPDATING ('ACCOUNT_NO') THEN errpkg.raise('Account number cannot be updated'); END IF;END;
CREATE OR REPLACE TRIGGER validate_updateBEFORE UPDATE ON account_transactionFOR EACH ROWBEGIN IF UPDATING ('ACCOUNT_NO') THEN errpkg.raise('Account number cannot be updated'); END IF;END;
15Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
Extended auditing example Tables: grades, grades_audit Run: grades_tables.sql, grades_audit.sql Cases: hacker changes grades, deletes
others UPDATE gradesSET grade = 'A+'WHERE student_id = 1AND class_id = 101;
UPDATE gradesSET grade = 'A+'WHERE student_id = 1AND class_id = 101;
DELETE gradesWHERE student_id = 2AND class_id = 101;
DELETE gradesWHERE student_id = 2AND class_id = 101;
16Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
Extended auditing example Run: grades_tables.sql, grades_audit2.sql Cases: hacker changes student or class ids
UPDATE grades SET student_id = 3WHERE student_id = 1 AND class_id = 101;
UPDATE grades SET student_id = 1WHERE student_id = 2 AND class_id = 101;
UPDATE grades SET student_id = 2 WHERE student_id = 3 AND class_id = 101;
UPDATE grades SET student_id = 3WHERE student_id = 1 AND class_id = 101;
UPDATE grades SET student_id = 1WHERE student_id = 2 AND class_id = 101;
UPDATE grades SET student_id = 2 WHERE student_id = 3 AND class_id = 101;
17Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
DDL Triggers Respond to DDL events
Creating/dropping tables, indices, etc. ALTER TABLE etc.
General form:CREATE [OR REPLACE] TRIGGER trigger name{BEFORE | AFTER| {DDL event} ON
{DATABASE | SCHEMA}DECLARE Variable declarationsBEGIN... some code...END;
CREATE [OR REPLACE] TRIGGER trigger name{BEFORE | AFTER| {DDL event} ON
{DATABASE | SCHEMA}DECLARE Variable declarationsBEGIN... some code...END;
18Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
DDL trigger e.g. Town crier examples triggered by creates:
uninformed_town_crier.sql
informed_town_crier.sql
19Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
Available DDL events CREATE, ALTER, DROP, GRANT, RENAME,
REVOKE, TRUNCATE DDL: any DDL event
Q: Does this work??
CREATE OR REPLACE TRIGGER no_create AFTER CREATE ON SCHEMABEGIN RAISE_APPLICATION_ERROR (-20000,
'ERROR : Objects cannot be created in the production database.');
END;
CREATE OR REPLACE TRIGGER no_create AFTER CREATE ON SCHEMABEGIN RAISE_APPLICATION_ERROR (-20000,
'ERROR : Objects cannot be created in the production database.');
END;
20Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
DB Event triggers Form similar to DDL triggers:
Triggering events: STARTUP, SHUTDOWN, SERVERERROR, LOGON, LOGOFF
CREATE [OR REPLACE] TRIGGER trigger name{BEFORE | AFTER} {database event} ON {DATABASE | SCHEMA}DECLARE Variable declarationsBEGIN... some code...END;
CREATE [OR REPLACE] TRIGGER trigger name{BEFORE | AFTER} {database event} ON {DATABASE | SCHEMA}DECLARE Variable declarationsBEGIN... some code...END;
21Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
DB event restrictions Have BEFORE and AFTER as above, but they
don’t always apply:
No BEFORE STARTUP/LOGON/SERVERERROR
No AFTER SHUTDOWN/LOGOFF
22Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
DB Trigger e.g. Gather stats before shutdown:
Log error messages
CREATE OR REPLACE TRIGGER on_shutdownBEFORE SHUTDOWN ON DATABASEBEGIN gather_system_stats;END;
CREATE OR REPLACE TRIGGER on_shutdownBEFORE SHUTDOWN ON DATABASEBEGIN gather_system_stats;END;
23Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
Trigger maintenance Enabling & disabling:
ALTER TRIGGER emp_after_insert DISABLE; ALTER TRIGGER emp_after_insert ENABLE;
Deleting: DROP TRIGGER emp_after_insert;
Viewing: select trigger_name from user_triggers; select text from user_source where name='TOWN_CRIER';
Check validity: select object_name, status from user_objects where
object_type='TRIGGER';
24Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
Triggers – important points Can replace old row (result of event) with new row Action may be performed before or after event Can refer to old row and new row WHEN clauses tests whether to continue Action may be performed either
For each row involved in event Once per event
Oracle does triggers as PL/SQL programs A trigger runs in the same transaction as the event
triggering it
25Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
Elements of Triggers Timing of action execution: before, after or instead
of triggering event The action can refer to both the old and new state of
the database Update events may specify a particular column or
set of columns A condition is specified with an optional WHEN
clause The action can be performed either for
once for every tuple or once for all the tuples that are changed by the database
operation
26Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
Intermission Go over previous labs
Begin lab…
Break
27Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
New-old topic: Transactions So far, have simply issued commands
Ignored xacts
Recall, though: an xact is an operation/set of ops executed atomically In one instant
ACID test: Xacts are atomic Each xact (not each statement) must leave the DB
consistent
28Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
Default xact behavior An xact begins upon login By default, xact lasts until logoff
Except for DDL statements They automatically commit
Examples with two views of emp…
29Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
Direct xact instructions At any point, may explicitly COMMIT:
SQL> COMMIT; Saves all statements entered up to now Begins new xact
Conversely, can ROLLBACK SQL> ROLLBACK; Cancels all statements entered since start of xact
Example: delete from emp; or delete junk;
30Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
Direct xact instructions Remember, DDL statements are auto-
committed They cannot be rollbacked
Examples:
Q: Why doesn’t rollback “work”?
drop table junk;rollback;
drop table junk;rollback;
truncate table junk;rollback;
truncate table junk;rollback;
31Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
Savepoints Xacts are atomic Can rollback to beginning of current xact
But might want to rollback only part way
Make 10 changes, make one bad change Want to: roll back to before last change
Don’t have Word-like multiple undo But do have savepoints
32Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
Savepoints Create a savepoint:
emp example:--changesSAVEPOINT sp1;--changesSAVEPOINT sp2;--changesSAVEPOINT sp3--changesROLLBACK TO sp2;ROLLBACK TO sp1;
--changesSAVEPOINT sp1;--changesSAVEPOINT sp2;--changesSAVEPOINT sp3--changesROLLBACK TO sp2;ROLLBACK TO sp1;
SAVEPOINT savept_name; SAVEPOINT savept_name;
Can skip savepoints But can ROLLBACK
only backwards Can ROLLBACK
only to last COMMIT
33Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
AUTOCOMMIT Finally, can turn AUTOCOMMIT on:
SQL> SET AUTOCOMMIT ON;
Then each statement is auto-committed as its own xact Not just DDL statements
34Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
New topic: the bulk loader To insert data, can insert rows one at a time
with INSERT INTO <table> VALUES(<>) If data is in/can be computed from other
tables, can use INSERT INTO <table> SELECT …
Often, have text file of data Oracle’s bulk loader will parse file and insert
all into the database
35Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
Using the bulk loader The bulk loader takes two files:
The data file The control file, specifying how to load the data
Control file form:
LOAD DATAINFILE <dataFile><APPEND> INTO TABLE <tableName>FIELDS TERMINATED BY '<separator>'(<list of all attribute names to load>)
LOAD DATAINFILE <dataFile><APPEND> INTO TABLE <tableName>FIELDS TERMINATED BY '<separator>'(<list of all attribute names to load>)
36Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
The control file
Default data file extension: .dat Default control file extension: .ctl If APPEND is omitted, the table must be empty, else
error Attribute list is comma-separated, but order doesn’t
matter Separator can be multi-char
LOAD DATAINFILE <dataFile><APPEND> INTO TABLE <tableName>FIELDS TERMINATED BY '<separator>'(<list of all attribute names to load>)
LOAD DATAINFILE <dataFile><APPEND> INTO TABLE <tableName>FIELDS TERMINATED BY '<separator>'(<list of all attribute names to load>)
37Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
The control file Example control file:
LOAD DATAINFILE test.datINTO TABLE testFIELDS TERMINATED BY '|'(i, s)
LOAD DATAINFILE test.datINTO TABLE testFIELDS TERMINATED BY '|'(i, s)
38Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
The data file Plain text file Each line one row in the table Example data file:
1|foo2|bar3| baz
1|foo2|bar3| baz
39Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
Running the bulk loader The bulk loader is a command-line program
sqlldr, separate from SQL*Plus:
At cmd line, specify: user/pass (pass is optional here) the control file (which specifies data file), and (optionally) a log file (dft ext: .log) (optionally) a bad file (dft ext: .bad)
c:\ sqlldr scott/tiger control=test log=test bad=badc:\ sqlldr scott/tiger control=test log=test bad=bad
40Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
Data in the control file Can also merge the data and control file
(onefile.ctl):
The * indicates that the data is in this file
LOAD DATAINFILE *INTO TABLE testFIELDS TERMINATED BY '|'(i, s)BEGINDATA1|foo2|bar3| baz
LOAD DATAINFILE *INTO TABLE testFIELDS TERMINATED BY '|'(i, s)BEGINDATA1|foo2|bar3| baz
41Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
Loading dates In the control file’s attribute list, follow a data
field with a date mask Date masks are case-INsensitive and include:
d - day m - month y - year
withdates.ctl:
LOAD DATAINFILE *INTO TABLE fooFIELDS TERMINATED BY '|'(i, d DATE 'dd-mm-yyyy')BEGINDATA1|01-01-19902|4-1-1998
LOAD DATAINFILE *INTO TABLE fooFIELDS TERMINATED BY '|'(i, d DATE 'dd-mm-yyyy')BEGINDATA1|01-01-19902|4-1-1998
42Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
Loading timestamps Similar to dates but includes more chars:
Mi – minutes ss – seconds hh – hour hh24: 24-hour hour ff – millisecond (fractional seconds)
withtimestamps.ctl:
LOAD DATAINFILE *APPEND INTO TABLE tsFIELDS TERMINATED BY ','(s, t timestamp 'yyyymmddhh24miss.ff' )BEGINDATA1,20041012081522.1231,10661012081522.321
LOAD DATAINFILE *APPEND INTO TABLE tsFIELDS TERMINATED BY ','(s, t timestamp 'yyyymmddhh24miss.ff' )BEGINDATA1,20041012081522.1231,10661012081522.321
43Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
Loading nulls Two adjacent separators
are interpreted as a null value in the field:
What if null in last field? Two options:
Put TRAILING NULLCOLS following field-term df
Append an extra field sep to end
withnulls.ctl:
3||5|2|41||6||7
3||5|2|41||6||7
LOAD DATAINFILE *APPEND INTO TABLE numsFIELDS TERMINATED BY '|'TRAILING NULLCOLS (a,b,c)BEGINDATA3||5|2|41|2|1|2||
LOAD DATAINFILE *APPEND INTO TABLE numsFIELDS TERMINATED BY '|'TRAILING NULLCOLS (a,b,c)BEGINDATA3||5|2|41|2|1|2||
44Matthew P. Johnson, OCL3, CISDD CUNY, June 2005
Lecture 10… regexps
Web apps/security
Data warehousing extensions
XML