<!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_trigger.sgml,v 1.9 2000/03/27 17:14:42 thomas Exp $
-Postgres documentation
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/create_trigger.sgml,v 1.37 2003/09/22 00:16:57 petere Exp $
+PostgreSQL documentation
-->
<refentry id="SQL-CREATETRIGGER">
<refmeta>
- <refentrytitle id="SQL-CREATETRIGGER-TITLE">
- CREATE TRIGGER
- </refentrytitle>
+ <refentrytitle id="SQL-CREATETRIGGER-TITLE">CREATE TRIGGER</refentrytitle>
<refmiscinfo>SQL - Language Statements</refmiscinfo>
</refmeta>
+
<refnamediv>
- <refname>
- CREATE TRIGGER
- </refname>
- <refpurpose>
- Creates a new trigger
- </refpurpose>
+ <refname>CREATE TRIGGER</refname>
+ <refpurpose>define a new trigger</refpurpose>
</refnamediv>
+
+ <indexterm zone="sql-createtrigger">
+ <primary>CREATE TRIGGER</primary>
+ </indexterm>
+
<refsynopsisdiv>
- <refsynopsisdivinfo>
- <date>2000-03-25</date>
- </refsynopsisdivinfo>
- <synopsis>
-CREATE TRIGGER <replaceable class="PARAMETER">name</replaceable> { BEFORE | AFTER } { <replaceable class="PARAMETER">event</replaceable> [OR ...] }
- ON <replaceable class="PARAMETER">table</replaceable> FOR EACH { ROW | STATEMENT }
- EXECUTE PROCEDURE <replaceable class="PARAMETER">ER">func</replaceable>BLE> ( <replaceable class="PARAMETER">arguments</replaceable> )
- </synopsis>
-
- <refsect2 id="R2-SQL-CREATETRIGGER-1">
- <refsect2info>
- <date>1998-09-21</date>
- </refsect2info>
- <title>
- Inputs
- </title>
- <para>
-
- <variablelist>
- <varlistentry>
- <term><replaceable class="parameter">name</replaceable></term>
- <listitem>
- <para>
- The name of an existing trigger.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><replaceable class="parameter">table</replaceable></term>
- <listitem>
- <para>
- The name of a table.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><replaceable class="parameter">event</replaceable></term>
- <listitem>
- <para>
- One of INSERT, DELETE or UPDATE.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term><replaceable class="parameter">funcname</replaceable></term>
- <listitem>
- <para>
- A user-supplied function.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- </para>
- </refsect2>
-
- <refsect2 id="R2-SQL-CREATETRIGGER-2">
- <refsect2info>
- <date>1998-09-21</date>
- </refsect2info>
- <title>
- Outputs
- </title>
- <para>
-
- <variablelist>
- <varlistentry>
- <term><computeroutput>
-CREATE
- </computeroutput></term>
- <listitem>
- <para>
- This message is returned if the trigger is successfully created.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- </para>
- </refsect2>
+<synopsis>
+CREATE TRIGGER <replaceable class="PARAMETER">name</replaceable> { BEFORE | AFTER } { <replaceable class="PARAMETER">event</replaceable> [ OR ... ] }
+ ON <replaceable class="PARAMETER">table</replaceable> [ FOR [ EACH ] { ROW | STATEMENT } ]
+ EXECUTE PROCEDURE <replaceable class="PARAMETER">funcname</replaceable> ( <replaceable class="PARAMETER">arguments</replaceable> )
+</synopsis>
</refsynopsisdiv>
- <refsect1 id="R1-SQL-CREATETRIGGER-1">
- <refsect1info>
- <date>1998-09-21</date>
- </refsect1info>
- <title>
- Description
- </title>
+ <refsect1>
+ <title>Description</title>
+
+ <para>
+ <command>CREATE TRIGGER</command> creates a new trigger. The
+ trigger will be associated with the specified table and will
+ execute the specified function <replaceable
+ class="parameter">func</replaceable> when certain events occur.
+ </para>
+
+ <para>
+ The trigger can be specified to fire either before before the
+ operation is attempted on a row (before constraints are checked and
+ the <command>INSERT</command>, <command>UPDATE</command>, or
+ <command>DELETE</command> is attempted) or after the operation has
+ completed (after constraints are checked and the
+ <command>INSERT</command>, <command>UPDATE</command>, or
+ <command>DELETE</command> has completed). If the trigger fires
+ before the event, the trigger may skip the operation for the
+ current row, or change the row being inserted (for
+ <command>INSERT</command> and <command>UPDATE</command> operations
+ only). If the trigger fires after the event, all changes, including
+ the last insertion, update, or deletion, are <quote>visible</quote>
+ to the trigger.
+ </para>
+
+ <para>
+ A trigger that is marked <literal>FOR EACH ROW</literal> is called
+ once for every row that the operation modifies. For example, a
+ <command>DELETE</command> that affects 10 rows will cause any
+ <literal>ON DELETE</literal> triggers on the target relation to be
+ called 10 separate times, once for each deleted row. In contrast, a
+ trigger that is marked <literal>FOR EACH STATEMENT</literal> only
+ executes once for any given operation, regardless of how many rows
+ it modifies (in particular, an operation that modifies zero rows
+ will still result in the execution of any applicable <literal>FOR
+ EACH STATEMENT</literal> triggers).
+ </para>
<para>
- <command>CREATE TRIGGER</command> will enter a new trigger into the current
- data base. The trigger will be associated with the relation
- <replaceable class="parameter">relname</replaceable> and will execute
- the specified function <replaceable class="parameter">funcname</replaceable>.
+ If multiple triggers of the same kind are defined for the same event,
+ they will be fired in alphabetical order by name.
</para>
<para>
- The trigger can be specified to fire either before BEFORE the
- operation is attempted on a tuple (before constraints
- are checked and the <command>INSERT</command>, <command>UPDATE</command> or
- <command>DELETE</command> is attempted) or
- AFTER the operation has been attempted (e.g. after constraints
- are checked and the <command>INSERT</command>,
- <command>UPDATE</command> or <command>DELETE</command> has
- completed). If the
- trigger fires before the event, the trigger may
- skip the operation for the current tuple, or change the tuple
- being inserted (for <command>INSERT</command> and
- <command>UPDATE</command> operations only). If
- the trigger fires after the event, all changes, including the
- last insertion, update, or deletion, are "visible" to the trigger.
+ <command>SELECT</command> does not modify any rows so you can not
+ create <command>SELECT</command> triggers. Rules and views are more
+ appropriate in such cases.
</para>
<para>
- Refer to the chapters on SPI and Triggers in the
- <citetitle>PostgreSQL Programmer's Guide</citetitle> for more
- information.
+ Refer to <xref linkend="triggers"> for more information about triggers.
</para>
+ </refsect1>
+
+ <refsect1>
+ <title>Parameters</title>
+
+ <variablelist>
+ <varlistentry>
+ <term><replaceable class="parameter">name</replaceable></term>
+ <listitem>
+ <para>
+ The name to give the new trigger. This must be distinct from
+ the name of any other trigger for the same table.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>BEFORE</literal></term>
+ <term><literal>AFTER</literal></term>
+ <listitem>
+ <para>
+ Determines whether the function is called before or after the
+ event.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">event</replaceable></term>
+ <listitem>
+ <para>
+ One of <command>INSERT</command>, <command>UPDATE</command>, or
+ <command>DELETE</command>; this specifies the event that will
+ fire the trigger. Multiple events can be specified using
+ <literal>OR</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
- <refsect2 id="R2-SQL-CREATETRIGGER-3">
- <refsect2info>
- <date>1998-09-21</date>
- </refsect2info>
- <title>
- Notes
- </title>
- <para>
- <command>CREATE TRIGGER</command> is a <productname>Postgres</productname>
- language extension.
- </para>
- <para>
- Only the relation owner may create a trigger on this relation.
- </para>
- <para>
- As of the current release (v7.0), STATEMENT triggers are not implemented.
- </para>
- <para>
- Refer to <command>DROP TRIGGER</command> for information on how to
- remove triggers.
- </para>
- </refsect2>
+ <varlistentry>
+ <term><replaceable class="parameter">table</replaceable></term>
+ <listitem>
+ <para>
+ The name (optionally schema-qualified) of the table the trigger
+ is for.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><literal>FOR EACH ROW</literal></term>
+ <term><literal>FOR EACH STATEMENT</literal></term>
+
+ <listitem>
+ <para>
+ This specifies whether the trigger procedure should be fired
+ once for every row affected by the trigger event, or just once
+ per SQL statement. If neither is specified, <literal>FOR EACH
+ STATEMENT</literal> is the default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">func</replaceable></term>
+ <listitem>
+ <para>
+ A user-supplied function that is declared as taking no arguments
+ and returning type <literal>trigger</>, which is executed when
+ the trigger fires.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable class="parameter">arguments</replaceable></term>
+ <listitem>
+ <para>
+ An optional comma-separated list of arguments to be provided to
+ the function when the trigger is executed. The arguments are
+ literal string constants. Simple names and numeric constants
+ may be written here, too, but they will all be converted to
+ strings. Please check the description of the implementation
+ language of the trigger function about how the trigger arguments
+ are accessible within the function; it may be different from
+ normal function arguments.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
</refsect1>
- <refsect1 id="R1-SQL-CREATETRIGGER-2">
- <title>
- Usage
- </title>
+ <refsect1 id="SQL-CREATETRIGGER-notes">
+ <title>Notes</title>
+
<para>
- Check if the specified distributor code exists in the distributors
- table before appending or updating a row in the table films:
-
- <programlisting>
-CREATE TRIGGER if_dist_exists
- BEFORE INSERT OR UPDATE ON films FOR EACH ROW
- EXECUTE PROCEDURE check_primary_key ('did', 'distributors', 'did');
- </programlisting>
+ To create a trigger on a table, the user must have the
+ <literal>TRIGGER</literal> privilege on the table.
</para>
+
+ <para>
+ In <productname>PostgreSQL</productname> versions before 7.3, it was
+ necessary to declare trigger functions as returning the placeholder
+ type <type>opaque</>, rather than <type>trigger</>. To support loading
+ of old dump files, <command>CREATE TRIGGER</> will accept a function
+ declared as returning <type>opaque</>, but it will issue a notice and
+ change the function's declared return type to <type>trigger</>.
+ </para>
+
+ <para>
+ Use <xref linkend="sql-droptrigger"
+ endterm="sql-droptrigger-title"> to remove a trigger.
+ </para>
+ </refsect1>
+
+ <refsect1 id="R1-SQL-CREATETRIGGER-2">
+ <title>Examples</title>
+
<para>
- Before cancelling a distributor or updating its code, remove every
- reference to the table films:
- <programlisting>
-CREATE TRIGGER if_film_exists
- BEFORE DELETE OR UPDATE ON distributors FOR EACH ROW
- EXECUTE PROCEDURE check_foreign_key (1, 'CASCADE', 'did', 'films', 'did');
- </programlisting>
+ <xref linkend="trigger-example"> contains a complete example.
</para>
</refsect1>
- <refsect1 id="R1-SQL-CREATETRIGGER-3">
- <title>
- Compatibility
- </title>
+ <refsect1 id="SQL-CREATETRIGGER-compatibility">
+ <title>Compatibility</title>
- <refsect2 id="R2-SQL-CREATETRIGGER-4">
- <refsect2info>
- <date>1998-09-21</date>
- </refsect2info>
- <title>
- SQL92
- </title>
-
- <para>
- There is no <command>CREATE TRIGGER</command> in <acronym>SQL92</acronym>.
- </para>
-
- <para>
- The second example above may also be done by using a FOREIGN KEY
- constraint as in:
-
- <programlisting>
-CREATE TABLE distributors (
- did DECIMAL(3),
- name VARCHAR(40),
- CONSTRAINT if_film_exists
- FOREIGN KEY(did) REFERENCES films
- ON UPDATE CASCADE ON DELETE CASCADE
-);
- </programlisting>
- </para>
- </refsect2>
+ <para>
+ The <command>CREATE TRIGGER</command> statement in
+ <productname>PostgreSQL</productname> implements a subset of the
+ SQL99 standard. (There are no provisions for triggers in SQL92.)
+ The following functionality is missing:
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ SQL99 allows triggers to fire on updates to specific columns
+ (e.g., <literal>AFTER UPDATE OF col1, col2</literal>).
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ SQL99 allows you to define aliases for the <quote>old</quote>
+ and <quote>new</quote> rows or tables for use in the definition
+ of the triggered action (e.g., <literal>CREATE TRIGGER ... ON
+ tablename REFERENCING OLD ROW AS somename NEW ROW AS othername
+ ...</literal>). Since <productname>PostgreSQL</productname>
+ allows trigger procedures to be written in any number of
+ user-defined languages, access to the data is handled in a
+ language-specific way.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <productname>PostgreSQL</productname> only allows the execution
+ of a user-defined function for the triggered action. SQL99
+ allows the execution of a number of other SQL commands, such as
+ <command>CREATE TABLE</command> as triggered action. This
+ limitation is not hard to work around by creating a user-defined
+ function that executes the desired commands.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+
+ <para>
+ SQL99 specifies that multiple triggers should be fired in
+ time-of-creation order. <productname>PostgreSQL</productname> uses
+ name order, which was judged more convenient to work with.
+ </para>
+
+ <para>
+ The ability to specify multiple actions for a single trigger using
+ <literal>OR</literal> is a <productname>PostgreSQL</> extension of
+ the SQL standard.
+ </para>
+ </refsect1>
+
+ <refsect1>
+ <title>See Also</title>
+
+ <simplelist type="inline">
+ <member><xref linkend="sql-createfunction" endterm="sql-createfunction-title"></member>
+ <member><xref linkend="sql-altertrigger" endterm="sql-altertrigger-title"></member>
+ <member><xref linkend="sql-droptrigger" endterm="sql-droptrigger-title"></member>
+ </simplelist>
</refsect1>
</refentry>