1
1
<!--
2
- $PostgreSQL: pgsql/doc/src/sgml/ref/create_trigger.sgml,v 1.51 2009/10/14 22:14:21 tgl Exp $
2
+ $PostgreSQL: pgsql/doc/src/sgml/ref/create_trigger.sgml,v 1.52 2009/11/20 20:38:09 tgl Exp $
3
3
PostgreSQL documentation
4
4
-->
5
5
@@ -23,6 +23,7 @@ PostgreSQL documentation
23
23
<synopsis>
24
24
CREATE TRIGGER <replaceable class="PARAMETER">name</replaceable> { BEFORE | AFTER } { <replaceable class="PARAMETER">event</replaceable> [ OR ... ] }
25
25
ON <replaceable class="PARAMETER">table</replaceable> [ FOR [ EACH ] { ROW | STATEMENT } ]
26
+ [ WHEN ( <replaceable class="parameter">condition</replaceable> ) ]
26
27
EXECUTE PROCEDURE <replaceable class="PARAMETER">function_name</replaceable> ( <replaceable class="PARAMETER">arguments</replaceable> )
27
28
</synopsis>
28
29
</refsynopsisdiv>
@@ -72,6 +73,16 @@ CREATE TRIGGER <replaceable class="PARAMETER">name</replaceable> { BEFORE | AFTE
72
73
<literal>FOR EACH STATEMENT</literal>.
73
74
</para>
74
75
76
+ <para>
77
+ Also, a trigger definition can specify a boolean <literal>WHEN</>
78
+ condition, which will be tested to see whether the trigger should
79
+ be fired. In row-level triggers the <literal>WHEN</> condition can
80
+ examine the old and/or new values of columns of the row. Statement-level
81
+ triggers can also have <literal>WHEN</> conditions, although the feature
82
+ is not so useful for them since the condition cannot refer to any values
83
+ in the table.
84
+ </para>
85
+
75
86
<para>
76
87
If multiple triggers of the same kind are defined for the same event,
77
88
they will be fired in alphabetical order by name.
@@ -159,6 +170,31 @@ UPDATE OF <replaceable>column_name1</replaceable> [, <replaceable>column_name2</
159
170
</listitem>
160
171
</varlistentry>
161
172
173
+ <varlistentry>
174
+ <term><replaceable class="parameter">condition</replaceable></term>
175
+ <listitem>
176
+ <para>
177
+ A Boolean expression that determines whether the trigger function
178
+ will actually be executed. If <literal>WHEN</> is specified, the
179
+ function will only be called if the <replaceable
180
+ class="parameter">condition</replaceable> returns <literal>true</>.
181
+ In <literal>FOR EACH ROW</literal> triggers, the <literal>WHEN</>
182
+ condition can refer to columns of the old and/or new row values
183
+ by writing <literal>OLD.<replaceable
184
+ class="parameter">column_name</replaceable></literal> or
185
+ <literal>NEW.<replaceable
186
+ class="parameter">column_name</replaceable></literal> respectively.
187
+ Of course, <literal>INSERT</> triggers cannot refer to <literal>OLD</>
188
+ and <literal>DELETE</> triggers cannot refer to <literal>NEW</>.
189
+ </para>
190
+
191
+ <para>
192
+ Currently, <literal>WHEN</literal> expressions cannot contain
193
+ subqueries.
194
+ </para>
195
+ </listitem>
196
+ </varlistentry>
197
+
162
198
<varlistentry>
163
199
<term><replaceable class="parameter">function_name</replaceable></term>
164
200
<listitem>
@@ -213,6 +249,29 @@ UPDATE OF <replaceable>column_name1</replaceable> [, <replaceable>column_name2</
213
249
value did not change.
214
250
</para>
215
251
252
+ <para>
253
+ In a <literal>BEFORE</> trigger, the <literal>WHEN</> condition is
254
+ evaluated just before the function is or would be executed, so using
255
+ <literal>WHEN</> is not materially different from testing the same
256
+ condition at the beginning of the trigger function. Note in particular
257
+ that the <literal>NEW</> row seen by the condition is the current value,
258
+ as possibly modified by earlier triggers. Also, a <literal>BEFORE</>
259
+ trigger's <literal>WHEN</> condition is not allowed to examine the
260
+ system columns of the <literal>NEW</> row (such as <literal>oid</>),
261
+ because those won't have been set yet.
262
+ </para>
263
+
264
+ <para>
265
+ In an <literal>AFTER</> trigger, the <literal>WHEN</> condition is
266
+ evaluated just after the row update occurs, and it determines whether an
267
+ event is queued to fire the trigger at the end of statement. So when an
268
+ <literal>AFTER</> trigger's <literal>WHEN</> condition does not return
269
+ true, it is not necessary to queue an event nor to re-fetch the row at end
270
+ of statement. This can result in significant speedups in statements that
271
+ modify many rows, if the trigger only needs to be fired for a few of the
272
+ rows.
273
+ </para>
274
+
216
275
<para>
217
276
In <productname>PostgreSQL</productname> versions before 7.3, it was
218
277
necessary to declare trigger functions as returning the placeholder
@@ -223,11 +282,56 @@ UPDATE OF <replaceable>column_name1</replaceable> [, <replaceable>column_name2</
223
282
</para>
224
283
</refsect1>
225
284
226
- <refsect1 id="R1- SQL-CREATETRIGGER-2 ">
285
+ <refsect1 id="SQL-CREATETRIGGER-examples ">
227
286
<title>Examples</title>
228
287
229
288
<para>
230
- <xref linkend="trigger-example"> contains a complete example.
289
+ Execute the function <function>check_account_update</> whenever
290
+ a row of the table <literal>accounts</> is about to be updated:
291
+
292
+ <programlisting>
293
+ CREATE TRIGGER check_update
294
+ BEFORE UPDATE ON accounts
295
+ FOR EACH ROW
296
+ EXECUTE PROCEDURE check_account_update();
297
+ </programlisting>
298
+
299
+ The same, but only execute the function if column <literal>balance</>
300
+ is specified as a target in the <command>UPDATE</> command:
301
+
302
+ <programlisting>
303
+ CREATE TRIGGER check_update
304
+ BEFORE UPDATE OF balance ON accounts
305
+ FOR EACH ROW
306
+ EXECUTE PROCEDURE check_account_update();
307
+ </programlisting>
308
+
309
+ This form only executes the function if column <literal>balance</>
310
+ has in fact changed value:
311
+
312
+ <programlisting>
313
+ CREATE TRIGGER check_update
314
+ BEFORE UPDATE ON accounts
315
+ FOR EACH ROW
316
+ WHEN (OLD.balance IS DISTINCT FROM NEW.balance)
317
+ EXECUTE PROCEDURE check_account_update();
318
+ </programlisting>
319
+
320
+ Call a function to log updates of <literal>accounts</>, but only if
321
+ something changed:
322
+
323
+ <programlisting>
324
+ CREATE TRIGGER log_update
325
+ AFTER UPDATE ON accounts
326
+ FOR EACH ROW
327
+ WHEN (OLD.* IS DISTINCT FROM NEW.*)
328
+ EXECUTE PROCEDURE log_account_update();
329
+ </programlisting>
330
+ </para>
331
+
332
+ <para>
333
+ <xref linkend="trigger-example"> contains a complete example of a trigger
334
+ function written in C.
231
335
</para>
232
336
</refsect1>
233
337
@@ -258,7 +362,7 @@ UPDATE OF <replaceable>column_name1</replaceable> [, <replaceable>column_name2</
258
362
<productname>PostgreSQL</productname> only allows the execution
259
363
of a user-defined function for the triggered action. The standard
260
364
allows the execution of a number of other SQL commands, such as
261
- <command>CREATE TABLE</command> as the triggered action. This
365
+ <command>CREATE TABLE</command>, as the triggered action. This
262
366
limitation is not hard to work around by creating a user-defined
263
367
function that executes the desired commands.
264
368
</para>
0 commit comments