ibm-information-center/dist/eclipse/plugins/i5OS.ic.sqlp_5.4.0.1/rbafyinsteadofsql.htm

144 lines
9.3 KiB
HTML
Raw Permalink Normal View History

2024-04-02 14:02:31 +00:00
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en-us" xml:lang="en-us">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="security" content="public" />
<meta name="Robots" content="index,follow" />
<meta http-equiv="PICS-Label" content='(PICS-1.1 "http://www.icra.org/ratingsv02.html" l gen true r (cz 1 lz 1 nz 1 oz 1 vz 1) "http://www.rsac.org/ratingsv01.html" l gen true r (n 0 s 0 v 0 l 0) "http://www.classify.org/safesurf/" l gen true r (SS~~000 1))' />
<meta name="DC.Type" content="reference" />
<meta name="DC.Title" content="INSTEAD OF SQL triggers" />
<meta name="abstract" content="An INSTEAD OF trigger is an SQL trigger that is processed “instead of” an SQL UPDATE, DELETE or INSERT statement. Unlike SQL BEFORE and AFTER triggers, an INSTEAD OF trigger can only be defined on a view, not a table." />
<meta name="description" content="An INSTEAD OF trigger is an SQL trigger that is processed “instead of” an SQL UPDATE, DELETE or INSERT statement. Unlike SQL BEFORE and AFTER triggers, an INSTEAD OF trigger can only be defined on a view, not a table." />
<meta name="DC.Relation" scheme="URI" content="rbafysqltrig.htm" />
<meta name="copyright" content="(C) Copyright IBM Corporation 1998, 2006" />
<meta name="DC.Rights.Owner" content="(C) Copyright IBM Corporation 1998, 2006" />
<meta name="DC.Format" content="XHTML" />
<meta name="DC.Identifier" content="rbafyinsteadofsql" />
<meta name="DC.Language" content="en-us" />
<!-- All rights reserved. Licensed Materials Property of IBM -->
<!-- US Government Users Restricted Rights -->
<!-- Use, duplication or disclosure restricted by -->
<!-- GSA ADP Schedule Contract with IBM Corp. -->
<link rel="stylesheet" type="text/css" href="./ibmdita.css" />
<link rel="stylesheet" type="text/css" href="./ic.css" />
<title>INSTEAD OF SQL triggers</title>
</head>
<body id="rbafyinsteadofsql"><a name="rbafyinsteadofsql"><!-- --></a>
<img src="./delta.gif" alt="Start of change" /><!-- Java sync-link --><script language="Javascript" src="../rzahg/synch.js" type="text/javascript"></script>
<h1 class="topictitle1">INSTEAD OF SQL triggers</h1>
<div><p>An INSTEAD OF trigger is an SQL trigger that is processed “instead
of” an SQL UPDATE, DELETE or INSERT statement. Unlike SQL BEFORE and AFTER
triggers, an INSTEAD OF trigger can only be defined on a view, not a table.</p>
<div class="section"><p>An INSTEAD OF trigger allows a view, which is not inherently insertable,
updatable, or deletable, to be inserted into, updated, or deleted from. See <a href="../db2/rbafzmsthcview.htm">CREATE VIEW</a> for more
information about deleteable, updatable, and insertable views.</p>
<p>After
an SQL INSTEAD OF trigger is added to a view, the view which previously could
only be read from can be used as the target of an insert, update, or delete
operation. The INSTEAD OF trigger defines the operations which need to be
performed to maintain the view.</p>
<p>A view can be used to control access
to tables. INSTEAD OF triggers can simplify the maintenance of access control
to tables.</p>
</div>
<div class="section"><h4 class="sectiontitle">Use an INSTEAD OF trigger</h4><div class="p">The definition of the
following view V1 is updatable, deletable, and insertable:<pre><strong>CREATE TABLE</strong> T1 (C1 <strong>VARCHAR</strong>(10), C2 <strong>INT</strong>)
<strong>CREATE VIEW</strong> V1(X1) <strong>AS SELECT</strong> C1 <strong>FROM</strong> T1 <strong>WHERE</strong> C2 &gt; 10</pre>
</div>
<div class="p">For
the following insert statement, C1 in table T1 will be assigned a value of
'A'. C2 will be assigned the NULL value. The NULL value would cause the
new row to not match the selection criteria C2 &gt; 10 for the view V1.<pre><strong>INSERT INTO</strong> V1 <strong>VALUES</strong>('A')</pre>
</div>
<div class="p">Adding
the INSTEAD OF trigger IOT1 can provide a different value for the row that
will be selected by the view:<pre><strong>CREATE TRIGGER</strong> IOT1 <strong>INSTEAD OF INSERT ON</strong> V1
<strong>REFERENCING NEW AS</strong> NEW_ROW
<strong>FOR EACH ROW MODE DB2SQL
INSERT INTO</strong> T1 <strong>VALUES</strong>(NEW_ROW.X1, 15)</pre>
</div>
</div>
<div class="section"><h4 class="sectiontitle">Make a view deletable</h4><div class="p">The definition of the following
join view V3 is not updatable, deletable, or insertable:<pre><strong>CREATE TABLE</strong> A (A1 <strong>VARCHAR</strong>(10), A2 <strong>INT</strong>)
<strong>CREATE VIEW</strong> V1(X1) <strong>AS SELECT</strong> A1 <strong>FROM</strong> A
<strong>CREATE TABLE</strong> B (B1 <strong>VARCHAR</strong>(10), B2 <strong>INT</strong>)
<strong>CREATE VIEW</strong> V2(Y1) <strong>AS SELECT</strong> B1 <strong>FROM</strong> B
<strong>CREATE VIEW</strong> V3(Z1, Z2) <strong>AS SELECT</strong> V1.X1, V2.Y1 <strong>FROM</strong> V1, V2 <strong>WHERE</strong> V1.X1 = 'A' <strong>AND</strong> V2.Y1 &gt; 'B'</pre>
</div>
<div class="p">Adding the INSTEAD OF trigger IOT2, makes the view V3 deletable:<pre><strong>CREATE TRIGGER</strong> IOT2 <strong>INSTEAD OF DELETE</strong> ON V3
<strong>REFERENCING OLD AS</strong> OLD_ROW
<strong>FOR EACH ROW MODE DB2SQL</strong>
<strong>BEGIN</strong>
<strong>DELETE FROM</strong> A <strong>WHERE</strong> A1 = OLD_ROW.Z1;
<strong>DELETE FROM</strong> B <strong>WHERE</strong> B1 = OLD_ROW.Z2;
<strong>END</strong></pre>
</div>
<div class="p">With this trigger, the following DELETE statement
is allowed. It deletes all rows from table A having an A1 value of 'A', and
all rows from table B having a B1 value of 'X'.<pre><strong>DELETE FROM</strong> V3 <strong>WHERE</strong> Z1 = 'A' <strong>AND</strong> Z2 = 'X'</pre>
</div>
</div>
<div class="section"><h4 class="sectiontitle">INSTEAD OF triggers with views defined on views</h4><div class="p">The
following definition of view V2 defined on V1 is not inherently insertable,
updatable, or deletable:<pre><strong>CREATE TABLE</strong> T1 (C1 <strong>VARCHAR</strong>(10), C2 <strong>INT</strong>)
<strong>CREATE TABLE</strong> T2 (D1 <strong>VARCHAR</strong>(10), D2 <strong>INT</strong>)
<strong>CREATE VIEW</strong> V1(X1, X2) <strong>AS SELECT</strong> C1, C2 <strong>FROM</strong> T1
<strong>UNION SELECT</strong> D1, D2 <strong>FROM</strong> T2
<strong>CREATE VIEW</strong> V2(Y1, Y2) <strong>AS SELECT</strong> X1, X2 <strong>FROM</strong> V1</pre>
</div>
<div class="p">Adding
the INSTEAD OF trigger IOT1 to V1, does not make V2 updatable:<pre><strong>CREATE TRIGGER</strong> IOT1 <strong>INSTEAD OF UPDATE ON</strong> V1
<strong>REFERENCING OLD AS</strong> OLD_ROW NEW <strong>AS</strong> NEW_ROW
<strong>FOR EACH ROW MODE DB2SQL</strong>
<strong>BEGIN</strong>
<strong>UPDATE</strong> T1 <strong>SET</strong> C1 = NEW_ROW.X1, C2 = NEW_ROW.X2 <strong>WHERE</strong>
C1 = OLD_ROW.X1 <strong>AND</strong> C2 = OLD_ROW.X2;
<strong>UPDATE</strong> T2 <strong>SET</strong> D1 = NEW_ROW.X1, D2 = NEW_ROW.D2 <strong>WHERE</strong>
D1 = OLD_ROW.X1 <strong>AND</strong> D2 = OLD_ROW.X2;
<strong>END</strong></pre>
</div>
<p>View V2 remains not updatable since
the original definition of view V2 remains not updatable.</p>
</div>
<div class="section"><h4 class="sectiontitle">Use INSTEAD OF triggers with BEFORE and AFTER triggers</h4><div class="p">The
addition of an INSTEAD OF trigger to a view does not cause any conflicts with
BEFORE and AFTER triggers defined on the base tables:<pre><strong>CREATE TABLE</strong> T1 (C1 <strong>VARCHAR</strong>(10), C2 <strong>DATE</strong>)
<strong>CREATE TABLE</strong> T2 (D1 <strong>VARCHAR</strong>(10))
<strong>CREATE TRIGGER</strong> AFTER1 <strong>AFTER DELETE ON</strong> T1
<strong>REFERENCING OLD AS</strong> OLD_ROW
<strong>FOR EACH ROW MODE DB2SQL
DELETE FROM</strong> T2 <strong>WHERE</strong> D1 = OLD_ROW.C1
<strong>CREATE VIEW</strong> V1(X1, X2) <strong>AS SELECT</strong> <strong>SUBSTR</strong>(T1.C1, 1, 1), <strong>DAYOFWEEK_ISO</strong>(T1.C2) <strong>FROM</strong> T1
<strong>CREATE TRIGGER</strong> IOT1 <strong>INSTEAD OF DELETE ON</strong> V1
<strong>REFERENCING OLD AS</strong> OLD_ROW
<strong>FOR EACH ROW MODE DB2SQL
DELETE FROM</strong> T1 <strong>WHERE</strong> C1 <strong>LIKE</strong> (OLD_ROW.X1 <strong>CONCAT</strong> '%')</pre>
</div>
<p>Any
delete operations for view V1 result in the AFTER DELETE trigger AFTER1 being
activated also because trigger IOT1 performs a delete on table T1. The delete
for table T1 causes the AFTER1 trigger to be activated.</p>
</div>
<div class="section"><h4 class="sectiontitle">Dependent views and INSTEAD OF triggers</h4><p>When adding
an INSTEAD OF trigger to a view, if the view definition references views that
also have INSTEAD OF triggers defined, you should define INSTEAD OF triggers
for all three operations, UPDATE, DELETE, and INSERT, to avoid confusion on
what capabilities the view being defined contains versus what the capabilities
of any dependent views have.</p>
</div>
</div>
<div>
<div class="familylinks">
<div class="parentlink"><strong>Parent topic:</strong> <a href="rbafysqltrig.htm" title="The SQL CREATE TRIGGER statement provides a way for the database management system to actively control, monitor, and manage a group of tables and views whenever an insert, update, or delete operation is performed.">SQL triggers</a></div>
</div>
</div>
<img src="./deltaend.gif" alt="End of change" /></body>
</html>