1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

doc: Improve description of referential actions

Some of the differences between NO ACTION and RESTRICT were not
explained fully.

Discussion: https://www.postgresql.org/message-id/ea5b2777-266a-46fa-852f-6fca6ec480ad@eisentraut.org
This commit is contained in:
Peter Eisentraut
2024-11-29 08:52:28 +01:00
parent 4a2dbfc6be
commit 1e08905842
2 changed files with 44 additions and 17 deletions

View File

@ -1233,16 +1233,32 @@ CREATE TABLE order_items (
</para> </para>
<para> <para>
Restricting and cascading deletes are the two most common options. The default <literal>ON DELETE</literal> action is <literal>ON DELETE NO
<literal>RESTRICT</literal> prevents deletion of a ACTION</literal>; this does not need to be specified. This means that the
referenced row. <literal>NO ACTION</literal> means that if any deletion in the referenced table is allowed to proceed. But the
referencing rows still exist when the constraint is checked, an error foreign-key constraint is still required to be satisfied, so this
is raised; this is the default behavior if you do not specify anything. operation will usually result in an error. But checking of foreign-key
(The essential difference between these two choices is that constraints can also be deferred to later in the transaction (not covered
<literal>NO ACTION</literal> allows the check to be deferred until in this chapter). In that case, the <literal>NO ACTION</literal> setting
later in the transaction, whereas <literal>RESTRICT</literal> does not.) would allow other commands to <quote>fix</quote> the situation before the
constraint is checked, for example by inserting another suitable row into
the referenced table or by deleting the now-dangling rows from the
referencing table.
</para>
<para>
<literal>RESTRICT</literal> is a stricter setting than <literal>NO
ACTION</literal>. It prevents deletion of a referenced row.
<literal>RESTRICT</literal> does not allow the check to be deferred until
later in the transaction.
</para>
<para>
<literal>CASCADE</literal> specifies that when a referenced row is deleted, <literal>CASCADE</literal> specifies that when a referenced row is deleted,
row(s) referencing it should be automatically deleted as well. row(s) referencing it should be automatically deleted as well.
</para>
<para>
There are two other options: There are two other options:
<literal>SET NULL</literal> and <literal>SET DEFAULT</literal>. <literal>SET NULL</literal> and <literal>SET DEFAULT</literal>.
These cause the referencing column(s) in the referencing row(s) These cause the referencing column(s) in the referencing row(s)
@ -1312,6 +1328,15 @@ CREATE TABLE posts (
NULL</literal> and <literal>SET DEFAULT</literal>. NULL</literal> and <literal>SET DEFAULT</literal>.
In this case, <literal>CASCADE</literal> means that the updated values of the In this case, <literal>CASCADE</literal> means that the updated values of the
referenced column(s) should be copied into the referencing row(s). referenced column(s) should be copied into the referencing row(s).
There is also a noticeable difference between <literal>ON UPDATE NO
ACTION</literal> (the default) and <literal>NO UPDATE RESTRICT</literal>.
The former will allow the update to proceed and the foreign-key constraint
will be checked against the state after the update. The latter will
prevent the update to run even if the state after the update would still
satisfy the constraint. This prevents updating a referenced row to a
value that is distinct but compares as equal (for example, a character
string with a different case variant, if a character string type with a
case-insensitive collation is used).
</para> </para>
<para> <para>

View File

@ -1248,17 +1248,16 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
clause specifies the action to perform when a referenced column clause specifies the action to perform when a referenced column
in the referenced table is being updated to a new value. If the in the referenced table is being updated to a new value. If the
row is updated, but the referenced column is not actually row is updated, but the referenced column is not actually
changed, no action is done. Referential actions other than the changed, no action is done. Referential actions are executed as part of
<literal>NO ACTION</literal> check cannot be deferred, even if the data changing command, even if the constraint is deferred. There
the constraint is declared deferrable. There are the following possible are the following possible actions for each clause:
actions for each clause:
<variablelist> <variablelist>
<varlistentry id="sql-createtable-parms-references-refact-no-action"> <varlistentry id="sql-createtable-parms-references-refact-no-action">
<term><literal>NO ACTION</literal></term> <term><literal>NO ACTION</literal></term>
<listitem> <listitem>
<para> <para>
Produce an error indicating that the deletion or update Produce an error if the deletion or update
would create a foreign key constraint violation. would create a foreign key constraint violation.
If the constraint is deferred, this If the constraint is deferred, this
error will be produced at constraint check time if there still error will be produced at constraint check time if there still
@ -1271,10 +1270,13 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
<term><literal>RESTRICT</literal></term> <term><literal>RESTRICT</literal></term>
<listitem> <listitem>
<para> <para>
Produce an error indicating that the deletion or update Produce an error if a row to be deleted or updated matches a row in
would create a foreign key constraint violation. the referencing table. This prevents the action even if the state
This is the same as <literal>NO ACTION</literal> except that after the action would not violate the foreign key constraint. In
the check is not deferrable. particular, it prevents updates of referenced rows to values that
are distinct but compare as equal. (But it does not prevent
<quote>no-op</quote> updates that update a column to the same
value.)
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>