1 Triggers. 2 PL/SQL reminder We presented PL/SQL- a Procedural extension to the SQL language. We...
-
date post
22-Dec-2015 -
Category
Documents
-
view
232 -
download
1
Transcript of 1 Triggers. 2 PL/SQL reminder We presented PL/SQL- a Procedural extension to the SQL language. We...
1
TriggersTriggers
2
PL/SQL reminderPL/SQL reminder
• We presented PL/SQL- a Procedural
extension to the SQL language.
• We reviewed the structure of an anonymous
PL/SQL block:
DECLARE (optional) /* Variable declaration */
BEGIN (mandatory) /* Block action*/
EXCEPTION (optional) /* Exception handling */
END; (optional)/
3
Example from last weekExample from last weekDECLARE
e_number1 EXCEPTION;
cnt NUMBER;
BEGIN
select count(*)
into cnt
from number_table;
IF cnt = 1 THEN RAISE e_number1;
ELSE dbms_output.put_line(cnt);
END IF;
EXCEPTION
WHEN e_number1 THEN
dbms_output.put_line('Count = 1');
end;
4
PL/SQL reminder-cont.PL/SQL reminder-cont.• We also showed the structures of procedures
and functions:
create or replace procedure num_logged(person IN mylog.who%TYPE, num OUT mylog.logon_num%TYPE)ISBEGIN select logon_num into num from mylog where who = person;END;/
create or replace procedure num_logged(person IN mylog.who%TYPE, num OUT mylog.logon_num%TYPE)ISBEGIN select logon_num into num from mylog where who = person;END;/
5
Triggers- introductionTriggers- introduction
• A trigger is an action which the Database
should perform when some DB event has
occurred.
• For example (in pseudocode):
TriggerA:
For any row that is inserted into table Sailors:
if age>30 -> insert this row into oldSailors;
else-> insert this row into youngSailors;
6
Trigger introduction cont.Trigger introduction cont.
• The code within the trigger, called the trigger body, is made up of PL/SQL blocks
• The “firing” of a trigger is transparent to the user.
• There are many optional triggering events, but we will focus on update, delete, and insert.
• Triggers can be used to check for data integrity, but should be used so only if it is not possible through other means.
7
Types of triggersTypes of triggers
1. Row level triggers: The code in the trigger is executed once for every row updated.
2. Statement level triggers (Default): The code in the trigger is performed once per statement.
• For example: if the triggering event was an update which updates 100 rows, a row-level trigger will execute 100 times, and a statement level trigger will execute once.
8
Types of triggers-cont.Types of triggers-cont.
1.BEFORE triggers: The trigger fires immediately BEFORE the triggering event executes.
2.AFTER triggers: The trigger fires immediately AFTER the triggering event executes.
3.INSTEAD OF triggers: The trigger fires INSTEAD of the triggering event.
• We can reference the “old” and “new” values.
• If we want to change rows which will be inserted, we have to use a BEFORE trigger and change the ‘new’ values. Using an AFTER trigger will not allow the change.
9
Example (pseudocode)Example (pseudocode)
Create Before-Trigger:
– For every string inserted into sailorName,
turn it into upper case before insertion
10
Trigger syntaxTrigger syntax
CREATE [or REPLACE] TRIGGER trig_name{BEFORE | AFTER | INSTEAD OF}{DELETE | INSERT | UPDATE}
[of column1, column2,…] [or {DELETE | INSERT | UPDATE]
[of columnA, columnB,…]
on table_name
[FOR EACH ROW][WHEN (condition)]
PL/SQL block
Further restricts when trigger is
fired
Triggering event
Trigger timing
11
Backing Up DataBacking Up Data
create table sailors_backup( who varchar2(30), when_chngd date, sid number, old_rating number, new_rating number);
create table sailors(sid number,sname VARCHAR2(30),rating number check(rating <= 10),age number
);
12
sailors(sid,sname,rating,age);sailors(sid,sname,rating,age);sailors_backup(who,when_chngd,sid, sailors_backup(who,when_chngd,sid,
old_rating,new_rating);old_rating,new_rating);
• Q: Why AFTER Trigger?
• A: Because in that case, the firing of the trigger occurs only when the inserted data complies with the table integrity (check..)
CREATE or REPLACE TRIGGER backup_trigAFTER UPDATE of Rating on SailorsFOR EACH ROW WHEN (old.rating < new.rating)BEGIN
INSERT INTO sailors_backupVALUES (USER, SYSDATE, :old.sid,
:old.rating, :new.rating);END;/
13
Ensuring Upper CaseEnsuring Upper Case
CREATE or REPLACE TRIGGER sname_trigBEFORE INSERT or UPDATE of snameon SailorsFOR EACH ROWBEGIN
:new.sname := UPPER(:new.sname);
END;/
• Q: Why BEFORE Trigger?
• A: You cannot update inserted values after insertion
14
Instead Of TriggerInstead Of Triggercreate view sailors_reserves asselect sailors.sname, reserves.bidfrom sailors, reserveswhere sailors.sid = reserves.sid;
CREATE or REPLACE TRIGGER view_trigINSTEAD OF INSERT on sailors_reservesFOR EACH ROWBEGININSERT INTO sailors values(:new.sname);INSERT INTO reserves values(:new.bid);END;/
15
Statement TriggerStatement TriggerCREATE or REPLACE TRIGGER no_work_on_shabbat_trigBEFORE INSERT or DELETE or UPDATEon reservesDECLARE
shabbat_exception EXCEPTION;
BEGINif (TO_CHAR(sysdate,'DY')='SAT') then
raise shabbat_exception;end if;
END;/
16
Another exampleAnother examplecreate or replace trigger trig2
after update of rating on sailors
for each row
DECLARE
diff number:=abs((:old.rating)-(:new.rating));
BEGIN
If ((:old.rating)>(:new.rating)) then dbms_output.put_line('The rating of '||:old.sname||' has dropped by '||diff);
elsif ((:old.rating)<(:new.rating)) then dbms_output.put_line('The rating of '||:old.sname||' has been raised by '||diff);
else dbms_output.put_line('The rating of '||:old.sname||' has remained the same');
end if;
END;
/
17
Trigger Compilation ErrorsTrigger Compilation Errors
• As with procedures and functions, when creating a Trigger with errors, you will get the message:
“Warning: Trigger created with compilation errors.”
To view the errors, type:
SHOW ERRORS TRIGGER myTrigger
• To drop a trigger write
drop trigger myTrig
• To disable/enable a trigger write
alter trigger myTrig disable/enable
18
Additional Types of Additional Types of TriggersTriggers
• Can also define triggers for
– logging in and off
– create/drop table events
– system errors
– etc.
19
JDBCJDBCTMTM
"Java Database Connectivity""Java Database Connectivity"
20
• Getting Started Guide:
http://java.sun.com/j2se/1.5.0/docs/guide/jdbc/
getstart/GettingStartedTOC.fm.html
• java.sql Package API:
http://java.sun.com/j2se/1.5.0/docs/api/java/sql/package-summary.html
Useful JDBC LinksUseful JDBC Links
21
Introduction to JDBCIntroduction to JDBC
• JDBC allows for convenient database
access from Java applications
• Data is transferred from relations to
objects and vice-versa
– databases optimized for searching/indexing
– objects optimized for engineering/flexibility
22
Why Access a Database from Why Access a Database from within a Program?within a Program?
• As we saw last week, some queries can’t be computed in SQL.
• PL/SQL includes more programming tools than SQL
• However, sometimes using PL/SQL will not be suitable:
– If we require object-oriented programming
– If accessing the database is a small part of a large Java application
– If we would like to access other DBMSes than Oracle
– Etc.
• Why not keep all the data in Java objects?
• “Separation of concerns”: DBMSes concentrate on data storage and access; programs concentrate on algorithms, networking, etc.
23
Six StepsSix Steps
• Load the driver
• Establish the Connection
• Create a Statement object
• Execute a query
• Process the result
• Close the connection
24
Packages to ImportPackages to Import
• In order to connect to the Oracle
database from java, import the
following packages:
– java.sql.*; (usually enough)
– javax.sql.* (for advanced features, such
as scrollable result sets)
JDBC Architecture (1)JDBC Architecture (1)
Application
• DriverManager is provided by Java
Software as part of the Java 2
Platform.
• Drivers are provided by DBMS
vendors.
Driver
DriverManager
DBMS
JDBC Architecture (2)JDBC Architecture (2)
• The application creates a driver instance and registers it with the DriverManager.
• The DriverManager tells the driver to connect to the DB
• The DriverManager keeps track of registered driver instances and their connections to DB’s.
• The Driver “talks” to a particular DB through the connection
27
ConnectingConnecting
1. Initializing a driver: new oracle.jdbc.driver.OracleDriver()
2. Registering it with the DriverManager: DriverManager.registerDriver(…)
3. Getting a connection:
DriverManager.getConnection(URL)Note:
• Stages 1+2 may be combined with Class.forName(“oracle.jdbc.driver.OracleDriver");
• In Stage 3, the Manager tries all drivers and assigns a connection to the first driver that succeeds.
28
Connecting to the Connecting to the DatabaseDatabase
String path = "jdbc:oracle:thin:";String host = "sol4";String port = "1521";String db = "stud";String login = “sqlUser";String password = “passwd”;String url = path + login + "/" + password +
"@" + host +":" + port + ":" + db;
Class.forName("oracle.jdbc.driver.OracleDriver");Connection con = DriverManager.getConnection(url);
StatementsStatements
1. Statement createStatement()
– returns a new Statement object
2. PreparedStatement
prepareStatement(String)
– returns a new PreparedStatement object
• Both are used to send SQL commands to the DB
• Both are created via the connection object
“prepared” because it already includes the query string
30
Statement query methodsStatement query methods
1. executeQuery(String query): for queries
that return a single ResultSet object
(typically select)
2. executeUpdate(String query): for
INSERT, UPDATE, DELETE, and SQL DDL
directives
31
CompilationCompilation
• When executing an SQL statement via
JDBC, it is not checked for errors until it
is run (Not checked during compilation)
32
executeQueryexecuteQuery
String queryStr = "SELECT * FROM Sailors " +"WHERE Name = 'joe smith'";
Statement stmt = con.createStatement();ResultSet rs = stmt.executeQuery(queryStr);
• The executeQuery method returns a ResultSet object representing the query result.
No semi-colon(;)
33
executeUpdateexecuteUpdate
String deleteStr = “DELETE FROM Sailors " +"WHERE sid = 15";
Statement stmt = con.createStatement();int delnum = stmt.executeUpdate(deleteStr);
•executeUpdate returns the number of rows modified
No semi-colon(;)
34
PreparedStatement PreparedStatement motivationmotivation
• Suppose we would like to run the query
SELECT * FROM Emp
where name=‘moshe’;
• But we would like to run this for all employees (separately), not only ‘moshe’…
• Could we create a variable instead of ‘moshe’ which would get a different name every time??..
35
Prepared StatementsPrepared Statements
• Prepared Statements are used for queries that
are executed many times with possibly
different contents.
• A PreparedStatement object includes the query
and is prepared for execution (precompiled).
• Question marks can be inserted as variables.
-setString(i, value)
-setInt(i, value)The i-th question
mark is set to the
given value.
36
PreparedStatement.executeQueryPreparedStatement.executeQuery() ()
String queryStr = "SELECT * FROM Sailors " +"WHERE Name = ? and Rating < ?”;
PreparedStatement pstmt = con.prepareStatement(queryStr);
pstmt.setString(1, “Joe”);pstmt.setInt(2, 8);
ResultSet rs = pstmt.executeQuery();
1st question
mark
Value to insert
37
PreparedStatement.executeUpdatePreparedStatement.executeUpdate()()
String deleteStr = “DELETE FROM Boats " +"WHERE Name = ? and Color = ?”;
PreparedStatement pstmt = con.prepareStatement(deleteStr);
pstmt.setString(1, “Fluffy”);pstmt.setString(2, "red");
int delnum = pstmt.executeUpdate();
38
• Will this work?
PreparedStatement pstmt = con.prepareStatement(“select * from ?”);
pstmt.setString(1, "Sailors");
No! We may put ? only instead of values
ResultSet (1)ResultSet (1)• A ResultSet is an object which contains the
result of a query - a “table”.
• At most one ResultSet per Statement can be open at the same time(!!).
• A ResultSet maintains a cursor pointing to its current row of data.
• The 'next' method moves the cursor to the next row
• As of JDBC 2.0, scrollable ResultSets are available, which also include ‘previous’, ’first’, ‘last’, etc..
ResultSet (2)ResultSet (2)
• resultSet methods work on the
current row.
• The cursor is positioned before
the first row upon creation.
ResultSet (3)ResultSet (3)
Statement stmt=
con.createStatement();
ResultSet rs =
stmt.executeQuery (
"SELECT * FROM Table1");
while (rs.next()) {
//something…
}
42
ResultSet methodsResultSet methods
• Getting the value in some column (for the current row):– getString(int columnNum);
– getString(String columnName);
– getInt(int columnNum);
– getInt(String columnName);
– Etc…
• To check if NULL was returned, you have to use wasNull() on the ResultSet after getting the value.
String s = rs.getString(“column1");
43
Example revisitedExample revisited
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table1");
// retrieve and print the values for the current row
while (rs.next()) {
int i = rs.getInt("a");
String s = rs.getString("b");
float f = rs.getFloat("c");
System.out.println("ROW = " + i + " " + s + " " + f);
}
44
ResultSetMetaData ResultSetMetaData
ResultSetMetaData rsmd = rs.getMetaData();int numcols = rsmd.getColumnCount();
for (int i = 1 ; i <= numcols; i++) {if (i > 1) System.out.print(",");System.out.print(rsmd.getColumnLabel(i));
}
An object created by the ResultSet which holds information about its columns
45
Mapping SQL and Java Mapping SQL and Java Types Types
• SQL and Java data types are not identical
• There are significant variations between the SQL types supported by different database products
• JDBC defines a set of generic SQL type identifiers in the class java.sql.Types
• The driver is responsible for mapping between the DB SQL types and JDBC SQL types
46
Some JDBC SQL Types Some JDBC SQL Types
• CHAR
• DATE
• BOOLEAN
• INTEGER
• TINYINT
• VARCHAR
• FLOAT
• DOUBLE
• BIGINT
• BINARY
• CLOB
• BLOB
• ARRAY
• OTHER
47
JDBC to Java Type Mapping JDBC to Java Type Mapping
• Each getXXX() and setXXX() method is allowed to get/set columns of certain JDBC types
• For example getDate() is allowed to access columns of types CHAR, VARCHAR, LONGVARCHAR, DATE, and TIMESTAMP
• getDate() is the recommended method to access DATE columns
48
Printing Query Output: Printing Query Output: Result Set (2) Result Set (2)
while (rs.next()) {for (int i = 1 ; i <= numcols; i++) {
if (i > 1) System.out.print(",");System.out.print(rs.getString(i));
}System.out.println("");
}
• getString() is allowed to access all simple JDBC types
49
Cleaning Up After YourselfCleaning Up After Yourself
• Remember to close the Connections, Statements, PreparedStatements and ResultSets
con.close();stmt.close();pstmt.close();rs.close();
50
Dealing With ExceptionsDealing With Exceptions
catch (SQLException e) {//human readable message about the
exceptionSystem.out.println(e.getMessage());
//String describing the reason of the exception
System.out.println(e.getSQLState());//driver-dependent code for the exceptionSystem.out.println(e.getErrorCode());
}
51
Transactions in JDBCTransactions in JDBC
52
TransactionsTransactions
• Transaction = 2 or more statements which
must all succeed (or all fail) together
• If one fails, the system must reverse all
previous actions
• Aim: don’t leave DB in inconsistent state
halfway through a transaction
• COMMIT = complete transaction
• ROLLBACK = abort
53
ExampleExample
• Suppose we want to transfer money from
bank account 13 to account 72:
PreparedStatement pstmt = con.prepareStatement(“UPDATE BankAccount
SET amount = amount + ?
WHERE accountId = ?”);pstmt.setInt(1,-100); pstmt.setInt(2, 13);pstmt.executeUpdate();pstmt.setInt(1, 100); pstmt.setInt(2, 72);pstmt.executeUpdate();
What happens if this update fails?
54
Transaction ManagementTransaction Management
• The connection has a state called
AutoCommit mode
• if AutoCommit is true, then every statement
is automatically committed
• if AutoCommit is false, then every statement
is added to an ongoing transaction
• Default: true
55
AutoCommitAutoCommit
• If you set AutoCommit to false, you must
explicitly commit or rollback the transaction
using Connection.commit() and
Connection.rollback()
con.setAutoCommit(boolean val)
56
ExampleExamplecon.setAutoCommit(false);try { PreparedStatement pstmt = con.prepareStatement(“update BankAccount
set amount = amount + ? where accountId = ?”);
pstmt.setInt(1,-100); pstmt.setInt(2, 13); pstmt.executeUpdate(); pstmt.setInt(1, 100); pstmt.setInt(2, 72); pstmt.executeUpdate(); con.commit();}catch (SQLException e) { con.rollback();}