]> begriffs open source - ai-pg/blob - full-docs/html/sql-createtrigger.html
Include latest toc output
[ai-pg] / full-docs / html / sql-createtrigger.html
1 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>CREATE TRIGGER</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="sql-createtransform.html" title="CREATE TRANSFORM" /><link rel="next" href="sql-createtype.html" title="CREATE TYPE" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">CREATE TRIGGER</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="sql-createtransform.html" title="CREATE TRANSFORM">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><th width="60%" align="center">SQL Commands</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 18.0 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="sql-createtype.html" title="CREATE TYPE">Next</a></td></tr></table><hr /></div><div class="refentry" id="SQL-CREATETRIGGER"><div class="titlepage"></div><a id="id-1.9.3.93.1" class="indexterm"></a><a id="id-1.9.3.93.2" class="indexterm"></a><div class="refnamediv"><h2><span class="refentrytitle">CREATE TRIGGER</span></h2><p>CREATE TRIGGER — define a new trigger</p></div><div class="refsynopsisdiv"><h2>Synopsis</h2><pre class="synopsis">
3 CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER <em class="replaceable"><code>name</code></em> { BEFORE | AFTER | INSTEAD OF } { <em class="replaceable"><code>event</code></em> [ OR ... ] }
4     ON <em class="replaceable"><code>table_name</code></em>
5     [ FROM <em class="replaceable"><code>referenced_table_name</code></em> ]
6     [ NOT DEFERRABLE | [ DEFERRABLE ] [ INITIALLY IMMEDIATE | INITIALLY DEFERRED ] ]
7     [ REFERENCING { { OLD | NEW } TABLE [ AS ] <em class="replaceable"><code>transition_relation_name</code></em> } [ ... ] ]
8     [ FOR [ EACH ] { ROW | STATEMENT } ]
9     [ WHEN ( <em class="replaceable"><code>condition</code></em> ) ]
10     EXECUTE { FUNCTION | PROCEDURE } <em class="replaceable"><code>function_name</code></em> ( <em class="replaceable"><code>arguments</code></em> )
11
12 <span class="phrase">where <em class="replaceable"><code>event</code></em> can be one of:</span>
13
14     INSERT
15     UPDATE [ OF <em class="replaceable"><code>column_name</code></em> [, ... ] ]
16     DELETE
17     TRUNCATE
18 </pre></div><div class="refsect1" id="id-1.9.3.93.6"><h2>Description</h2><p>
19    <code class="command">CREATE TRIGGER</code> creates a new trigger.
20    <code class="command">CREATE OR REPLACE TRIGGER</code> will either create a
21    new trigger, or replace an existing trigger.  The
22    trigger will be associated with the specified table, view, or foreign table
23    and will execute the specified
24    function <em class="replaceable"><code>function_name</code></em> when
25    certain operations are performed on that table.
26   </p><p>
27    To replace the current definition of an existing trigger, use
28    <code class="command">CREATE OR REPLACE TRIGGER</code>, specifying the existing
29    trigger's name and parent table.  All other properties are replaced.
30   </p><p>
31    The trigger can be specified to fire before the
32    operation is attempted on a row (before constraints are checked and
33    the <code class="command">INSERT</code>, <code class="command">UPDATE</code>, or
34    <code class="command">DELETE</code> is attempted); or after the operation has
35    completed (after constraints are checked and the
36    <code class="command">INSERT</code>, <code class="command">UPDATE</code>, or
37    <code class="command">DELETE</code> has completed); or instead of the operation
38    (in the case of inserts, updates or deletes on a view).
39    If the trigger fires before or instead of the event, the trigger can skip
40    the operation for the current row, or change the row being inserted (for
41    <code class="command">INSERT</code> and <code class="command">UPDATE</code> operations
42    only). If the trigger fires after the event, all changes, including
43    the effects of other triggers, are <span class="quote">“<span class="quote">visible</span>”</span>
44    to the trigger.
45   </p><p>
46    A trigger that is marked <code class="literal">FOR EACH ROW</code> is called
47    once for every row that the operation modifies. For example, a
48    <code class="command">DELETE</code> that affects 10 rows will cause any
49    <code class="literal">ON DELETE</code> triggers on the target relation to be
50    called 10 separate times, once for each deleted row. In contrast, a
51    trigger that is marked <code class="literal">FOR EACH STATEMENT</code> only
52    executes once for any given operation, regardless of how many rows
53    it modifies (in particular, an operation that modifies zero rows
54    will still result in the execution of any applicable <code class="literal">FOR
55    EACH STATEMENT</code> triggers).
56   </p><p>
57    Triggers that are specified to fire <code class="literal">INSTEAD OF</code> the trigger
58    event must be marked <code class="literal">FOR EACH ROW</code>, and can only be defined
59    on views. <code class="literal">BEFORE</code> and <code class="literal">AFTER</code> triggers on a view
60    must be marked as <code class="literal">FOR EACH STATEMENT</code>.
61   </p><p>
62    In addition, triggers may be defined to fire for
63    <code class="command">TRUNCATE</code>, though only
64    <code class="literal">FOR EACH STATEMENT</code>.
65   </p><p>
66    The following table summarizes which types of triggers may be used on
67    tables, views, and foreign tables:
68   </p><div class="informaltable" id="SUPPORTED-TRIGGER-TYPES"><table class="informaltable" border="1"><colgroup><col /><col /><col /><col /></colgroup><thead><tr><th>When</th><th>Event</th><th>Row-level</th><th>Statement-level</th></tr></thead><tbody><tr><td rowspan="2" align="center"><code class="literal">BEFORE</code></td><td align="center"><code class="command">INSERT</code>/<code class="command">UPDATE</code>/<code class="command">DELETE</code></td><td align="center">Tables and foreign tables</td><td align="center">Tables, views, and foreign tables</td></tr><tr><td align="center"><code class="command">TRUNCATE</code></td><td align="center">—</td><td align="center">Tables and foreign tables</td></tr><tr><td rowspan="2" align="center"><code class="literal">AFTER</code></td><td align="center"><code class="command">INSERT</code>/<code class="command">UPDATE</code>/<code class="command">DELETE</code></td><td align="center">Tables and foreign tables</td><td align="center">Tables, views, and foreign tables</td></tr><tr><td align="center"><code class="command">TRUNCATE</code></td><td align="center">—</td><td align="center">Tables and foreign tables</td></tr><tr><td rowspan="2" align="center"><code class="literal">INSTEAD OF</code></td><td align="center"><code class="command">INSERT</code>/<code class="command">UPDATE</code>/<code class="command">DELETE</code></td><td align="center">Views</td><td align="center">—</td></tr><tr><td align="center"><code class="command">TRUNCATE</code></td><td align="center">—</td><td align="center">—</td></tr></tbody></table></div><p>
69    Also, a trigger definition can specify a Boolean <code class="literal">WHEN</code>
70    condition, which will be tested to see whether the trigger should
71    be fired.  In row-level triggers the <code class="literal">WHEN</code> condition can
72    examine the old and/or new values of columns of the row.  Statement-level
73    triggers can also have <code class="literal">WHEN</code> conditions, although the feature
74    is not so useful for them since the condition cannot refer to any values
75    in the table.
76   </p><p>
77    If multiple triggers of the same kind are defined for the same event,
78    they will be fired in alphabetical order by name.
79   </p><p>
80    When the <code class="literal">CONSTRAINT</code> option is specified, this command creates a
81    <em class="firstterm">constraint trigger</em>.<a id="id-1.9.3.93.6.12.3" class="indexterm"></a>
82    This is the same as a regular trigger
83    except that the timing of the trigger firing can be adjusted using
84    <a class="link" href="sql-set-constraints.html" title="SET CONSTRAINTS"><code class="command">SET CONSTRAINTS</code></a>.
85    Constraint triggers must be <code class="literal">AFTER ROW</code> triggers on plain
86    tables (not foreign tables).  They
87    can be fired either at the end of the statement causing the triggering
88    event, or at the end of the containing transaction; in the latter case they
89    are said to be <em class="firstterm">deferred</em>.  A pending deferred-trigger firing
90    can also be forced to happen immediately by using <code class="command">SET
91    CONSTRAINTS</code>.  Constraint triggers are expected to raise an exception
92    when the constraints they implement are violated.
93   </p><p>
94    The <code class="literal">REFERENCING</code> option enables collection
95    of <em class="firstterm">transition relations</em>, which are row sets that include all
96    of the rows inserted, deleted, or modified by the current SQL statement.
97    This feature lets the trigger see a global view of what the statement did,
98    not just one row at a time.  This option is only allowed for
99    an <code class="literal">AFTER</code> trigger on a plain table (not a foreign table).
100    The trigger should not be a constraint trigger.  Also, if the trigger is
101    an <code class="literal">UPDATE</code> trigger, it must not specify
102    a <em class="replaceable"><code>column_name</code></em> list when using
103    this option.
104    <code class="literal">OLD TABLE</code> may only be specified once, and only for a trigger
105    that can fire on <code class="literal">UPDATE</code> or <code class="literal">DELETE</code>; it creates a
106    transition relation containing the <em class="firstterm">before-images</em> of all rows
107    updated or deleted by the statement.
108    Similarly, <code class="literal">NEW TABLE</code> may only be specified once, and only for
109    a trigger that can fire on <code class="literal">UPDATE</code> or <code class="literal">INSERT</code>;
110    it creates a transition relation containing the <em class="firstterm">after-images</em>
111    of all rows updated or inserted by the statement.
112   </p><p>
113    <code class="command">SELECT</code> does not modify any rows so you cannot
114    create <code class="command">SELECT</code> triggers.  Rules and views may provide
115    workable solutions to problems that seem to need <code class="command">SELECT</code>
116    triggers.
117   </p><p>
118    Refer to <a class="xref" href="triggers.html" title="Chapter 37. Triggers">Chapter 37</a> for more information about triggers.
119   </p></div><div class="refsect1" id="id-1.9.3.93.7"><h2>Parameters</h2><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>name</code></em></span></dt><dd><p>
120       The name to give the new trigger.  This must be distinct from
121       the name of any other trigger for the same table.
122       The name cannot be schema-qualified — the trigger inherits the
123       schema of its table.  For a constraint trigger, this is also the name to
124       use when modifying the trigger's behavior using
125       <code class="command">SET CONSTRAINTS</code>.
126      </p></dd><dt><span class="term"><code class="literal">BEFORE</code><br /></span><span class="term"><code class="literal">AFTER</code><br /></span><span class="term"><code class="literal">INSTEAD OF</code></span></dt><dd><p>
127       Determines whether the function is called before, after, or instead of
128       the event.  A constraint trigger can only be specified as
129       <code class="literal">AFTER</code>.
130      </p></dd><dt><span class="term"><em class="replaceable"><code>event</code></em></span></dt><dd><p>
131       One of <code class="literal">INSERT</code>, <code class="literal">UPDATE</code>,
132       <code class="literal">DELETE</code>, or <code class="literal">TRUNCATE</code>;
133       this specifies the event that will fire the trigger. Multiple
134       events can be specified using <code class="literal">OR</code>, except when
135       transition relations are requested.
136      </p><p>
137       For <code class="literal">UPDATE</code> events, it is possible to
138       specify a list of columns using this syntax:
139 </p><pre class="synopsis">
140 UPDATE OF <em class="replaceable"><code>column_name1</code></em> [, <em class="replaceable"><code>column_name2</code></em> ... ]
141 </pre><p>
142       The trigger will only fire if at least one of the listed columns
143       is mentioned as a target of the <code class="command">UPDATE</code> command
144       or if one of the listed columns is a generated column that depends on a
145       column that is the target of the <code class="command">UPDATE</code>.
146      </p><p>
147       <code class="literal">INSTEAD OF UPDATE</code> events do not allow a list of columns.
148       A column list cannot be specified when requesting transition relations,
149       either.
150      </p></dd><dt><span class="term"><em class="replaceable"><code>table_name</code></em></span></dt><dd><p>
151       The name (optionally schema-qualified) of the table, view, or foreign
152       table the trigger is for.
153      </p></dd><dt><span class="term"><em class="replaceable"><code>referenced_table_name</code></em></span></dt><dd><p>
154       The (possibly schema-qualified) name of another table referenced by the
155       constraint.  This option is used for foreign-key constraints and is not
156       recommended for general use.  This can only be specified for
157       constraint triggers.
158      </p></dd><dt><span class="term"><code class="literal">DEFERRABLE</code><br /></span><span class="term"><code class="literal">NOT DEFERRABLE</code><br /></span><span class="term"><code class="literal">INITIALLY IMMEDIATE</code><br /></span><span class="term"><code class="literal">INITIALLY DEFERRED</code></span></dt><dd><p>
159       The default timing of the trigger.
160       See the <a class="xref" href="sql-createtable.html" title="CREATE TABLE"><span class="refentrytitle">CREATE TABLE</span></a> documentation for details of
161       these constraint options.  This can only be specified for constraint
162       triggers.
163      </p></dd><dt><span class="term"><code class="literal">REFERENCING</code></span></dt><dd><p>
164       This keyword immediately precedes the declaration of one or two
165       relation names that provide access to the transition relations of the
166       triggering statement.
167      </p></dd><dt><span class="term"><code class="literal">OLD TABLE</code><br /></span><span class="term"><code class="literal">NEW TABLE</code></span></dt><dd><p>
168       This clause indicates whether the following relation name is for the
169       before-image transition relation or the after-image transition
170       relation.
171      </p></dd><dt><span class="term"><em class="replaceable"><code>transition_relation_name</code></em></span></dt><dd><p>
172       The (unqualified) name to be used within the trigger for this
173       transition relation.
174      </p></dd><dt><span class="term"><code class="literal">FOR EACH ROW</code><br /></span><span class="term"><code class="literal">FOR EACH STATEMENT</code></span></dt><dd><p>
175       This specifies whether the trigger function should be fired
176       once for every row affected by the trigger event, or just once
177       per SQL statement. If neither is specified, <code class="literal">FOR EACH
178       STATEMENT</code> is the default.  Constraint triggers can only
179       be specified <code class="literal">FOR EACH ROW</code>.
180      </p></dd><dt><span class="term"><em class="replaceable"><code>condition</code></em></span></dt><dd><p>
181       A Boolean expression that determines whether the trigger function
182       will actually be executed.  If <code class="literal">WHEN</code> is specified, the
183       function will only be called if the <em class="replaceable"><code>condition</code></em> returns <code class="literal">true</code>.
184       In <code class="literal">FOR EACH ROW</code> triggers, the <code class="literal">WHEN</code>
185       condition can refer to columns of the old and/or new row values
186       by writing <code class="literal">OLD.<em class="replaceable"><code>column_name</code></em></code> or
187       <code class="literal">NEW.<em class="replaceable"><code>column_name</code></em></code> respectively.
188       Of course, <code class="literal">INSERT</code> triggers cannot refer to <code class="literal">OLD</code>
189       and <code class="literal">DELETE</code> triggers cannot refer to <code class="literal">NEW</code>.
190      </p><p><code class="literal">INSTEAD OF</code> triggers do not support <code class="literal">WHEN</code>
191       conditions.
192      </p><p>
193       Currently, <code class="literal">WHEN</code> expressions cannot contain
194       subqueries.
195      </p><p>
196       Note that for constraint triggers, evaluation of the <code class="literal">WHEN</code>
197       condition is not deferred, but occurs immediately after the row update
198       operation is performed. If the condition does not evaluate to true then
199       the trigger is not queued for deferred execution.
200      </p></dd><dt><span class="term"><em class="replaceable"><code>function_name</code></em></span></dt><dd><p>
201       A user-supplied function that is declared as taking no arguments
202       and returning type <code class="literal">trigger</code>, which is executed when
203       the trigger fires.
204      </p><p>
205       In the syntax of <code class="literal">CREATE TRIGGER</code>, the keywords
206       <code class="literal">FUNCTION</code> and <code class="literal">PROCEDURE</code> are
207       equivalent, but the referenced function must in any case be a function,
208       not a procedure.  The use of the keyword <code class="literal">PROCEDURE</code>
209       here is historical and deprecated.
210      </p></dd><dt><span class="term"><em class="replaceable"><code>arguments</code></em></span></dt><dd><p>
211       An optional comma-separated list of arguments to be provided to
212       the function when the trigger is executed.  The arguments are
213       literal string constants.  Simple names and numeric constants
214       can be written here, too, but they will all be converted to
215       strings.  Please check the description of the implementation
216       language of the trigger function to find out how these arguments
217       can be accessed within the function; it might be different from
218       normal function arguments.
219      </p></dd></dl></div></div><div class="refsect1" id="SQL-CREATETRIGGER-NOTES"><h2>Notes</h2><p>
220    To create or replace a trigger on a table, the user must have the
221    <code class="literal">TRIGGER</code> privilege on the table.  The user must
222    also have <code class="literal">EXECUTE</code> privilege on the trigger function.
223   </p><p>
224    Use <a class="link" href="sql-droptrigger.html" title="DROP TRIGGER"><code class="command">DROP TRIGGER</code></a> to remove a trigger.
225   </p><p>
226    Creating a row-level trigger on a partitioned table will cause an
227    identical <span class="quote">“<span class="quote">clone</span>”</span> trigger to be created on each of its
228    existing partitions; and any partitions created or attached later will have
229    an identical trigger, too.  If there is a conflictingly-named trigger on a
230    child partition already, an error occurs unless <code class="command">CREATE OR REPLACE
231    TRIGGER</code> is used, in which case that trigger is replaced with a
232    clone trigger.  When a partition is detached from its parent, its clone
233    triggers are removed.
234   </p><p>
235    A column-specific trigger (one defined using the <code class="literal">UPDATE OF
236    <em class="replaceable"><code>column_name</code></em></code> syntax) will fire when any
237    of its columns are listed as targets in the <code class="command">UPDATE</code>
238    command's <code class="literal">SET</code> list.  It is possible for a column's value
239    to change even when the trigger is not fired, because changes made to the
240    row's contents by <code class="literal">BEFORE UPDATE</code> triggers are not considered.
241    Conversely, a command such as <code class="literal">UPDATE ... SET x = x ...</code>
242    will fire a trigger on column <code class="literal">x</code>, even though the column's
243    value did not change.
244   </p><p>
245    In a <code class="literal">BEFORE</code> trigger, the <code class="literal">WHEN</code> condition is
246    evaluated just before the function is or would be executed, so using
247    <code class="literal">WHEN</code> is not materially different from testing the same
248    condition at the beginning of the trigger function.  Note in particular
249    that the <code class="literal">NEW</code> row seen by the condition is the current value,
250    as possibly modified by earlier triggers.  Also, a <code class="literal">BEFORE</code>
251    trigger's <code class="literal">WHEN</code> condition is not allowed to examine the
252    system columns of the <code class="literal">NEW</code> row (such as <code class="literal">ctid</code>),
253    because those won't have been set yet.
254   </p><p>
255    In an <code class="literal">AFTER</code> trigger, the <code class="literal">WHEN</code> condition is
256    evaluated just after the row update occurs, and it determines whether an
257    event is queued to fire the trigger at the end of statement.  So when an
258    <code class="literal">AFTER</code> trigger's <code class="literal">WHEN</code> condition does not return
259    true, it is not necessary to queue an event nor to re-fetch the row at end
260    of statement.  This can result in significant speedups in statements that
261    modify many rows, if the trigger only needs to be fired for a few of the
262    rows.
263   </p><p>
264    In some cases it is possible for a single SQL command to fire more than
265    one kind of trigger.  For instance an <code class="command">INSERT</code> with
266    an <code class="literal">ON CONFLICT DO UPDATE</code> clause may cause both insert and
267    update operations, so it will fire both kinds of triggers as needed.
268    The transition relations supplied to triggers are
269    specific to their event type; thus an <code class="command">INSERT</code> trigger
270    will see only the inserted rows, while an <code class="command">UPDATE</code>
271    trigger will see only the updated rows.
272   </p><p>
273    Row updates or deletions caused by foreign-key enforcement actions, such
274    as <code class="literal">ON UPDATE CASCADE</code> or <code class="literal">ON DELETE SET NULL</code>, are
275    treated as part of the SQL command that caused them (note that such
276    actions are never deferred).  Relevant triggers on the affected table will
277    be fired, so that this provides another way in which an SQL command might
278    fire triggers not directly matching its type.  In simple cases, triggers
279    that request transition relations will see all changes caused in their
280    table by a single original SQL command as a single transition relation.
281    However, there are cases in which the presence of an <code class="literal">AFTER ROW</code>
282    trigger that requests transition relations will cause the foreign-key
283    enforcement actions triggered by a single SQL command to be split into
284    multiple steps, each with its own transition relation(s).  In such cases,
285    any statement-level triggers that are present will be fired once per
286    creation of a transition relation set, ensuring that the triggers see
287    each affected row in a transition relation once and only once.
288   </p><p>
289    Statement-level triggers on a view are fired only if the action on the
290    view is handled by a row-level <code class="literal">INSTEAD OF</code> trigger.
291    If the action is handled by an <code class="literal">INSTEAD</code> rule, then
292    whatever statements are emitted by the rule are executed in place of the
293    original statement naming the view, so that the triggers that will be
294    fired are those on tables named in the replacement statements.
295    Similarly, if the view is automatically updatable, then the action is
296    handled by automatically rewriting the statement into an action on the
297    view's base table, so that the base table's statement-level triggers are
298    the ones that are fired.
299   </p><p>
300    Modifying a partitioned table or a table with inheritance children fires
301    statement-level triggers attached to the explicitly named table, but not
302    statement-level triggers for its partitions or child tables.  In contrast,
303    row-level triggers are fired on the rows in affected partitions or
304    child tables, even if they are not explicitly named in the query.
305    If a statement-level trigger has been defined with transition relations
306    named by a <code class="literal">REFERENCING</code> clause, then before and after
307    images of rows are visible from all affected partitions or child tables.
308    In the case of inheritance children, the row images include only columns
309    that are present in the table that the trigger is attached to.
310   </p><p>
311    Currently, row-level triggers with transition relations cannot be defined
312    on partitions or inheritance child tables.  Also, triggers on partitioned
313    tables may not be <code class="literal">INSTEAD OF</code>.
314   </p><p>
315    Currently, the <code class="literal">OR REPLACE</code> option is not supported for
316    constraint triggers.
317   </p><p>
318    Replacing an existing trigger within a transaction that has already
319    performed updating actions on the trigger's table is not recommended.
320    Trigger firing decisions, or portions of firing decisions, that have
321    already been made will not be reconsidered, so the effects could be
322    surprising.
323   </p><p>
324    There are a few built-in trigger functions that can be used to
325    solve common problems without having to write your own trigger code;
326    see <a class="xref" href="functions-trigger.html" title="9.29. Trigger Functions">Section 9.29</a>.
327   </p></div><div class="refsect1" id="SQL-CREATETRIGGER-EXAMPLES"><h2>Examples</h2><p>
328    Execute the function <code class="function">check_account_update</code> whenever
329    a row of the table <code class="literal">accounts</code> is about to be updated:
330
331 </p><pre class="programlisting">
332 CREATE TRIGGER check_update
333     BEFORE UPDATE ON accounts
334     FOR EACH ROW
335     EXECUTE FUNCTION check_account_update();
336 </pre><p>
337
338    Modify that trigger definition to only execute the function if
339    column <code class="literal">balance</code> is specified as a target in
340    the <code class="command">UPDATE</code> command:
341
342 </p><pre class="programlisting">
343 CREATE OR REPLACE TRIGGER check_update
344     BEFORE UPDATE OF balance ON accounts
345     FOR EACH ROW
346     EXECUTE FUNCTION check_account_update();
347 </pre><p>
348
349    This form only executes the function if column <code class="literal">balance</code>
350    has in fact changed value:
351
352 </p><pre class="programlisting">
353 CREATE TRIGGER check_update
354     BEFORE UPDATE ON accounts
355     FOR EACH ROW
356     WHEN (OLD.balance IS DISTINCT FROM NEW.balance)
357     EXECUTE FUNCTION check_account_update();
358 </pre><p>
359
360    Call a function to log updates of <code class="literal">accounts</code>, but only if
361    something changed:
362
363 </p><pre class="programlisting">
364 CREATE TRIGGER log_update
365     AFTER UPDATE ON accounts
366     FOR EACH ROW
367     WHEN (OLD.* IS DISTINCT FROM NEW.*)
368     EXECUTE FUNCTION log_account_update();
369 </pre><p>
370
371    Execute the function <code class="function">view_insert_row</code> for each row to insert
372    rows into the tables underlying a view:
373
374 </p><pre class="programlisting">
375 CREATE TRIGGER view_insert
376     INSTEAD OF INSERT ON my_view
377     FOR EACH ROW
378     EXECUTE FUNCTION view_insert_row();
379 </pre><p>
380
381    Execute the function <code class="function">check_transfer_balances_to_zero</code> for each
382    statement to confirm that the <code class="literal">transfer</code> rows offset to a net of
383    zero:
384
385 </p><pre class="programlisting">
386 CREATE TRIGGER transfer_insert
387     AFTER INSERT ON transfer
388     REFERENCING NEW TABLE AS inserted
389     FOR EACH STATEMENT
390     EXECUTE FUNCTION check_transfer_balances_to_zero();
391 </pre><p>
392
393    Execute the function <code class="function">check_matching_pairs</code> for each row to
394    confirm that changes are made to matching pairs at the same time (by the
395    same statement):
396
397 </p><pre class="programlisting">
398 CREATE TRIGGER paired_items_update
399     AFTER UPDATE ON paired_items
400     REFERENCING NEW TABLE AS newtab OLD TABLE AS oldtab
401     FOR EACH ROW
402     EXECUTE FUNCTION check_matching_pairs();
403 </pre><p>
404   </p><p>
405    <a class="xref" href="trigger-example.html" title="37.4. A Complete Trigger Example">Section 37.4</a> contains a complete example of a trigger
406    function written in C.
407   </p></div><div class="refsect1" id="SQL-CREATETRIGGER-COMPATIBILITY"><h2>Compatibility</h2><p>
408    The <code class="command">CREATE TRIGGER</code> statement in
409    <span class="productname">PostgreSQL</span> implements a subset of the
410    <acronym class="acronym">SQL</acronym> standard. The following functionalities are currently
411    missing:
412
413    </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
414       While transition table names for <code class="literal">AFTER</code> triggers are
415       specified using the <code class="literal">REFERENCING</code> clause in the standard way,
416       the row variables used in <code class="literal">FOR EACH ROW</code> triggers may not be
417       specified in a <code class="literal">REFERENCING</code> clause.  They are available in a
418       manner that is dependent on the language in which the trigger function
419       is written, but is fixed for any one language.  Some languages
420       effectively behave as though there is a <code class="literal">REFERENCING</code> clause
421       containing <code class="literal">OLD ROW AS OLD NEW ROW AS NEW</code>.
422      </p></li><li class="listitem"><p>
423       The standard allows transition tables to be used with
424       column-specific <code class="literal">UPDATE</code> triggers, but then the set of rows
425       that should be visible in the transition tables depends on the
426       trigger's column list.  This is not currently implemented by
427       <span class="productname">PostgreSQL</span>.
428      </p></li><li class="listitem"><p>
429       <span class="productname">PostgreSQL</span> only allows the execution
430       of a user-defined function for the triggered action.  The standard
431       allows the execution of a number of other SQL commands, such as
432       <code class="command">CREATE TABLE</code>, as the triggered action.  This
433       limitation is not hard to work around by creating a user-defined
434       function that executes the desired commands.
435      </p></li></ul></div><p>
436   </p><p>
437    SQL specifies that multiple triggers should be fired in
438    time-of-creation order.  <span class="productname">PostgreSQL</span> uses
439    name order, which was judged to be more convenient.
440   </p><p>
441    SQL specifies that <code class="literal">BEFORE DELETE</code> triggers on cascaded
442    deletes fire <span class="emphasis"><em>after</em></span> the cascaded <code class="literal">DELETE</code> completes.
443    The <span class="productname">PostgreSQL</span> behavior is for <code class="literal">BEFORE
444    DELETE</code> to always fire before the delete action, even a cascading
445    one.  This is considered more consistent.  There is also nonstandard
446    behavior if <code class="literal">BEFORE</code> triggers modify rows or prevent
447    updates during an update that is caused by a referential action.  This can
448    lead to constraint violations or stored data that does not honor the
449    referential constraint.
450   </p><p>
451    The ability to specify multiple actions for a single trigger using
452    <code class="literal">OR</code> is a <span class="productname">PostgreSQL</span> extension of
453    the SQL standard.
454   </p><p>
455    The ability to fire triggers for <code class="command">TRUNCATE</code> is a
456    <span class="productname">PostgreSQL</span> extension of the SQL standard, as is the
457    ability to define statement-level triggers on views.
458   </p><p>
459    <code class="command">CREATE CONSTRAINT TRIGGER</code> is a
460    <span class="productname">PostgreSQL</span> extension of the <acronym class="acronym">SQL</acronym>
461    standard.
462    So is the <code class="literal">OR REPLACE</code> option.
463   </p></div><div class="refsect1" id="id-1.9.3.93.11"><h2>See Also</h2><span class="simplelist"><a class="xref" href="sql-altertrigger.html" title="ALTER TRIGGER"><span class="refentrytitle">ALTER TRIGGER</span></a>, <a class="xref" href="sql-droptrigger.html" title="DROP TRIGGER"><span class="refentrytitle">DROP TRIGGER</span></a>, <a class="xref" href="sql-createfunction.html" title="CREATE FUNCTION"><span class="refentrytitle">CREATE FUNCTION</span></a>, <a class="xref" href="sql-set-constraints.html" title="SET CONSTRAINTS"><span class="refentrytitle">SET CONSTRAINTS</span></a></span></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="sql-createtransform.html" title="CREATE TRANSFORM">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="sql-commands.html" title="SQL Commands">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="sql-createtype.html" title="CREATE TYPE">Next</a></td></tr><tr><td width="40%" align="left" valign="top">CREATE TRANSFORM </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 18.0 Documentation">Home</a></td><td width="40%" align="right" valign="top"> CREATE TYPE</td></tr></table></div></body></html>