aboutsummaryrefslogtreecommitdiff
path: root/doc/src
diff options
context:
space:
mode:
Diffstat (limited to 'doc/src')
-rw-r--r--doc/src/sgml/ref/merge.sgml603
1 files changed, 0 insertions, 603 deletions
diff --git a/doc/src/sgml/ref/merge.sgml b/doc/src/sgml/ref/merge.sgml
deleted file mode 100644
index a7d44a39b68..00000000000
--- a/doc/src/sgml/ref/merge.sgml
+++ /dev/null
@@ -1,603 +0,0 @@
-<!--
-doc/src/sgml/ref/merge.sgml
-PostgreSQL documentation
--->
-
-<refentry id="sql-merge">
-
- <refmeta>
- <refentrytitle>MERGE</refentrytitle>
- <manvolnum>7</manvolnum>
- <refmiscinfo>SQL - Language Statements</refmiscinfo>
- </refmeta>
-
- <refnamediv>
- <refname>MERGE</refname>
- <refpurpose>insert, update, or delete rows of a table based upon source data</refpurpose>
- </refnamediv>
-
- <refsynopsisdiv>
-<synopsis>
-MERGE INTO <replaceable class="parameter">target_table_name</replaceable> [ [ AS ] <replaceable class="parameter">target_alias</replaceable> ]
-USING <replaceable class="parameter">data_source</replaceable>
-ON <replaceable class="parameter">join_condition</replaceable>
-<replaceable class="parameter">when_clause</replaceable> [...]
-
-where <replaceable class="parameter">data_source</replaceable> is
-
-{ <replaceable class="parameter">source_table_name</replaceable> |
- ( source_query )
-}
-[ [ AS ] <replaceable class="parameter">source_alias</replaceable> ]
-
-and <replaceable class="parameter">when_clause</replaceable> is
-
-{ WHEN MATCHED [ AND <replaceable class="parameter">condition</replaceable> ] THEN { <replaceable class="parameter">merge_update</replaceable> | <replaceable class="parameter">merge_delete</replaceable> } |
- WHEN NOT MATCHED [ AND <replaceable class="parameter">condition</replaceable> ] THEN { <replaceable class="parameter">merge_insert</replaceable> | DO NOTHING }
-}
-
-and <replaceable class="parameter">merge_insert</replaceable> is
-
-INSERT [( <replaceable class="parameter">column_name</replaceable> [, ...] )]
-[ OVERRIDING { SYSTEM | USER } VALUE ]
-{ VALUES ( { <replaceable class="parameter">expression</replaceable> | DEFAULT } [, ...] ) | DEFAULT VALUES }
-
-and <replaceable class="parameter">merge_update</replaceable> is
-
-UPDATE SET { <replaceable class="parameter">column_name</replaceable> = { <replaceable class="parameter">expression</replaceable> | DEFAULT } |
- ( <replaceable class="parameter">column_name</replaceable> [, ...] ) = ( { <replaceable class="parameter">expression</replaceable> | DEFAULT } [, ...] )
- } [, ...]
-
-and <replaceable class="parameter">merge_delete</replaceable> is
-
-DELETE
-</synopsis>
- </refsynopsisdiv>
-
- <refsect1>
- <title>Description</title>
-
- <para>
- <command>MERGE</command> performs actions that modify rows in the
- <replaceable class="parameter">target_table_name</replaceable>,
- using the <replaceable class="parameter">data_source</replaceable>.
- <command>MERGE</command> provides a single <acronym>SQL</acronym>
- statement that can conditionally <command>INSERT</command>,
- <command>UPDATE</command> or <command>DELETE</command> rows, a task
- that would otherwise require multiple procedural language statements.
- </para>
-
- <para>
- First, the <command>MERGE</command> command performs a join
- from <replaceable class="parameter">data_source</replaceable> to
- <replaceable class="parameter">target_table_name</replaceable>
- producing zero or more candidate change rows. For each candidate change
- row the status of <literal>MATCHED</literal> or <literal>NOT MATCHED</literal> is set
- just once, after which <literal>WHEN</literal> clauses are evaluated
- in the order specified. If one of them is activated, the specified
- action occurs. No more than one <literal>WHEN</literal> clause can be
- activated for any candidate change row.
- </para>
-
- <para>
- <command>MERGE</command> actions have the same effect as
- regular <command>UPDATE</command>, <command>INSERT</command>, or
- <command>DELETE</command> commands of the same names. The syntax of
- those commands is different, notably that there is no <literal>WHERE</literal>
- clause and no tablename is specified. All actions refer to the
- <replaceable class="parameter">target_table_name</replaceable>,
- though modifications to other tables may be made using triggers.
- </para>
-
- <para>
- When <literal>DO NOTHING</literal> action is specified, the source row is
- skipped. Since actions are evaluated in the given order, <literal>DO
- NOTHING</literal> can be handy to skip non-interesting source rows before
- more fine-grained handling.
- </para>
-
- <para>
- There is no MERGE privilege.
- You must have the <literal>UPDATE</literal> privilege on the column(s)
- of the <replaceable class="parameter">target_table_name</replaceable>
- referred to in the <literal>SET</literal> clause
- if you specify an update action, the <literal>INSERT</literal> privilege
- on the <replaceable class="parameter">target_table_name</replaceable>
- if you specify an insert action and/or the <literal>DELETE</literal>
- privilege on the <replaceable class="parameter">target_table_name</replaceable>
- if you specify a delete action on the
- <replaceable class="parameter">target_table_name</replaceable>.
- Privileges are tested once at statement start and are checked
- whether or not particular <literal>WHEN</literal> clauses are activated
- during the subsequent execution.
- You will require the <literal>SELECT</literal> privilege on the
- <replaceable class="parameter">data_source</replaceable> and any column(s)
- of the <replaceable class="parameter">target_table_name</replaceable>
- referred to in a <literal>condition</literal>.
- </para>
-
- <para>
- MERGE is not supported if the <replaceable
- class="parameter">target_table_name</replaceable> has
- <literal>RULES</literal> defined on it.
- See <xref linkend="rules"/> for more information about <literal>RULES</literal>.
- </para>
- </refsect1>
-
- <refsect1>
- <title>Parameters</title>
-
- <variablelist>
- <varlistentry>
- <term><replaceable class="parameter">target_table_name</replaceable></term>
- <listitem>
- <para>
- The name (optionally schema-qualified) of the target table to merge into.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><replaceable class="parameter">target_alias</replaceable></term>
- <listitem>
- <para>
- A substitute name for the target table. When an alias is
- provided, it completely hides the actual name of the table. For
- example, given <literal>MERGE foo AS f</literal>, the remainder of the
- <command>MERGE</command> statement must refer to this table as
- <literal>f</literal> not <literal>foo</literal>.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><replaceable class="parameter">source_table_name</replaceable></term>
- <listitem>
- <para>
- The name (optionally schema-qualified) of the source table, view or
- transition table.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><replaceable class="parameter">source_query</replaceable></term>
- <listitem>
- <para>
- A query (<command>SELECT</command> statement or <command>VALUES</command>
- statement) that supplies the rows to be merged into the
- <replaceable class="parameter">target_table_name</replaceable>.
- Refer to the <xref linkend="sql-select"/>
- statement or <xref linkend="sql-values"/>
- statement for a description of the syntax.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><replaceable class="parameter">source_alias</replaceable></term>
- <listitem>
- <para>
- A substitute name for the data source. When an alias is
- provided, it completely hides whether table or query was specified.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><replaceable class="parameter">join_condition</replaceable></term>
- <listitem>
- <para>
- <replaceable class="parameter">join_condition</replaceable> is
- an expression resulting in a value of type
- <type>boolean</type> (similar to a <literal>WHERE</literal>
- clause) that specifies which rows in the
- <replaceable class="parameter">data_source</replaceable>
- match rows in the
- <replaceable class="parameter">target_table_name</replaceable>.
- </para>
- <warning>
- <para>
- Only columns from <replaceable class="parameter">target_table_name</replaceable>
- that attempt to match <replaceable class="parameter">data_source</replaceable>
- rows should appear in <replaceable class="parameter">join_condition</replaceable>.
- <replaceable class="parameter">join_condition</replaceable> subexpressions that
- only reference <replaceable class="parameter">target_table_name</replaceable>
- columns can only affect which action is taken, often in surprising ways.
- </para>
- </warning>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><replaceable class="parameter">when_clause</replaceable></term>
- <listitem>
- <para>
- At least one <literal>WHEN</literal> clause is required.
- </para>
- <para>
- If the <literal>WHEN</literal> clause specifies <literal>WHEN MATCHED</literal>
- and the candidate change row matches a row in the
- <replaceable class="parameter">target_table_name</replaceable>
- the <literal>WHEN</literal> clause is activated if the
- <replaceable class="parameter">condition</replaceable> is
- absent or is present and evaluates to <literal>true</literal>.
- If the <literal>WHEN</literal> clause specifies <literal>WHEN NOT MATCHED</literal>
- and the candidate change row does not match a row in the
- <replaceable class="parameter">target_table_name</replaceable>
- the <literal>WHEN</literal> clause is activated if the
- <replaceable class="parameter">condition</replaceable> is
- absent or is present and evaluates to <literal>true</literal>.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><replaceable class="parameter">condition</replaceable></term>
- <listitem>
- <para>
- An expression that returns a value of type <type>boolean</type>.
- If this expression returns <literal>true</literal> then the <literal>WHEN</literal>
- clause will be activated and the corresponding action will occur for
- that row. The expression may not contain functions that possibly performs
- writes to the database.
- </para>
- <para>
- A condition on a <literal>WHEN MATCHED</literal> clause can refer to columns
- in both the source and the target relation. A condition on a
- <literal>WHEN NOT MATCHED</literal> clause can only refer to columns from
- the source relation, since by definition there is no matching target row.
- Only the system attributes from the target table are accessible.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><replaceable class="parameter">merge_insert</replaceable></term>
- <listitem>
- <para>
- The specification of an <literal>INSERT</literal> action that inserts
- one row into the target table.
- The target column names can be listed in any order. If no list of
- column names is given at all, the default is all the columns of the
- table in their declared order.
- </para>
- <para>
- Each column not present in the explicit or implicit column list will be
- filled with a default value, either its declared default value
- or null if there is none.
- </para>
- <para>
- If the expression for any column is not of the correct data type,
- automatic type conversion will be attempted.
- </para>
- <para>
- If <replaceable class="parameter">target_table_name</replaceable>
- is a partitioned table, each row is routed to the appropriate partition
- and inserted into it.
- If <replaceable class="parameter">target_table_name</replaceable>
- is a partition, an error will occur if one of the input rows violates
- the partition constraint.
- </para>
- <para>
- Column names may not be specified more than once.
- <command>INSERT</command> actions cannot contain sub-selects.
- </para>
- <para>
- The <literal>VALUES</literal> clause can only refer to columns from
- the source relation, since by definition there is no matching target row.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><replaceable class="parameter">merge_update</replaceable></term>
- <listitem>
- <para>
- The specification of an <literal>UPDATE</literal> action that updates
- the current row of the <replaceable
- class="parameter">target_table_name</replaceable>.
- Column names may not be specified more than once.
- </para>
- <para>
- Do not include the table name, as you would normally do with an
- <xref linkend="sql-update"/> command.
- For example, <literal>UPDATE tab SET col = 1</literal> is invalid. Also,
- do not include a <literal>WHERE</literal> clause, since only the current
- row can be updated. For example,
- <literal>UPDATE SET col = 1 WHERE key = 57</literal> is invalid.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><replaceable class="parameter">merge_delete</replaceable></term>
- <listitem>
- <para>
- Specifies a <literal>DELETE</literal> action that deletes the current row
- of the <replaceable class="parameter">target_table_name</replaceable>.
- Do not include the tablename or any other clauses, as you would normally
- do with an <xref linkend="sql-delete"/> command.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><replaceable class="parameter">column_name</replaceable></term>
- <listitem>
- <para>
- The name of a column in the <replaceable
- class="parameter">target_table_name</replaceable>. The column name
- can be qualified with a subfield name or array subscript, if
- needed. (Inserting into only some fields of a composite
- column leaves the other fields null.) When referencing a
- column, do not include the table's name in the specification
- of a target column.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><literal>OVERRIDING SYSTEM VALUE</literal></term>
- <listitem>
- <para>
- Without this clause, it is an error to specify an explicit value
- (other than <literal>DEFAULT</literal>) for an identity column defined
- as <literal>GENERATED ALWAYS</literal>. This clause overrides that
- restriction.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><literal>OVERRIDING USER VALUE</literal></term>
- <listitem>
- <para>
- If this clause is specified, then any values supplied for identity
- columns defined as <literal>GENERATED BY DEFAULT</literal> are ignored
- and the default sequence-generated values are applied.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><literal>DEFAULT VALUES</literal></term>
- <listitem>
- <para>
- All columns will be filled with their default values.
- (An <literal>OVERRIDING</literal> clause is not permitted in this
- form.)
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><replaceable class="parameter">expression</replaceable></term>
- <listitem>
- <para>
- An expression to assign to the column. The expression can use the
- old values of this and other columns in the table.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><literal>DEFAULT</literal></term>
- <listitem>
- <para>
- Set the column to its default value (which will be NULL if no
- specific default expression has been assigned to it).
- </para>
- </listitem>
- </varlistentry>
-
- </variablelist>
- </refsect1>
-
- <refsect1>
- <title>Outputs</title>
-
- <para>
- On successful completion, a <command>MERGE</command> command returns a command
- tag of the form
-<screen>
-MERGE <replaceable class="parameter">total-count</replaceable>
-</screen>
- The <replaceable class="parameter">total-count</replaceable> is the total
- number of rows changed (whether inserted, updated, or deleted).
- If <replaceable class="parameter">total-count</replaceable> is 0, no rows
- were changed in any way.
- </para>
-
- </refsect1>
-
- <refsect1>
- <title>Execution</title>
-
- <para>
- The following steps take place during the execution of
- <command>MERGE</command>.
- <orderedlist>
- <listitem>
- <para>
- Perform any BEFORE STATEMENT triggers for all actions specified, whether or
- not their <literal>WHEN</literal> clauses are activated during execution.
- </para>
- </listitem>
- <listitem>
- <para>
- Perform a join from source to target table.
- The resulting query will be optimized normally and will produce
- a set of candidate change row. For each candidate change row
- <orderedlist>
- <listitem>
- <para>
- Evaluate whether each row is MATCHED or NOT MATCHED.
- </para>
- </listitem>
- <listitem>
- <para>
- Test each WHEN condition in the order specified until one activates.
- </para>
- </listitem>
- <listitem>
- <para>
- When activated, perform the following actions
- <orderedlist>
- <listitem>
- <para>
- Perform any BEFORE ROW triggers that fire for the action's event type.
- </para>
- </listitem>
- <listitem>
- <para>
- Apply the action specified, invoking any check constraints on the
- target table.
- However, it will not invoke rules.
- </para>
- </listitem>
- <listitem>
- <para>
- Perform any AFTER ROW triggers that fire for the action's event type.
- </para>
- </listitem>
- </orderedlist>
- </para>
- </listitem>
- </orderedlist>
- </para>
- </listitem>
- <listitem>
- <para>
- Perform any AFTER STATEMENT triggers for actions specified, whether or
- not they actually occur. This is similar to the behavior of an
- <command>UPDATE</command> statement that modifies no rows.
- </para>
- </listitem>
- </orderedlist>
- In summary, statement triggers for an event type (say, INSERT) will
- be fired whenever we <emphasis>specify</emphasis> an action of that kind. Row-level
- triggers will fire only for the one event type <emphasis>activated</emphasis>.
- So a <command>MERGE</command> might fire statement triggers for both
- <command>UPDATE</command> and <command>INSERT</command>, even though only
- <command>UPDATE</command> row triggers were fired.
- </para>
-
- <para>
- You should ensure that the join produces at most one candidate change row
- for each target row. In other words, a target row shouldn't join to more
- than one data source row. If it does, then only one of the candidate change
- rows will be used to modify the target row, later attempts to modify will
- cause an error. This can also occur if row triggers make changes to the
- target table which are then subsequently modified by <command>MERGE</command>.
- If the repeated action is an <command>INSERT</command> this will
- cause a uniqueness violation while a repeated <command>UPDATE</command> or
- <command>DELETE</command> will cause a cardinality violation; the latter behavior
- is required by the <acronym>SQL</acronym> Standard. This differs from
- historical <productname>PostgreSQL</productname> behavior of joins in
- <command>UPDATE</command> and <command>DELETE</command> statements where second and
- subsequent attempts to modify are simply ignored.
- </para>
-
- <para>
- If a <literal>WHEN</literal> clause omits an <literal>AND</literal> clause it becomes
- the final reachable clause of that kind (<literal>MATCHED</literal> or
- <literal>NOT MATCHED</literal>). If a later <literal>WHEN</literal> clause of that kind
- is specified it would be provably unreachable and an error is raised.
- If a final reachable clause is omitted it is possible that no action
- will be taken for a candidate change row.
- </para>
-
- </refsect1>
- <refsect1>
- <title>Notes</title>
-
- <para>
- The order in which rows are generated from the data source is indeterminate
- by default. A <replaceable class="parameter">source_query</replaceable>
- can be used to specify a consistent ordering, if required, which might be
- needed to avoid deadlocks between concurrent transactions.
- </para>
-
- <para>
- There is no <literal>RETURNING</literal> clause with <command>MERGE</command>.
- Actions of <command>INSERT</command>, <command>UPDATE</command> and <command>DELETE</command>
- cannot contain <literal>RETURNING</literal> or <literal>WITH</literal> clauses.
- </para>
-
- <tip>
- <para>
- You may also wish to consider using <command>INSERT ... ON CONFLICT</command> as an
- alternative statement which offers the ability to run an <command>UPDATE</command>
- if a concurrent <command>INSERT</command> occurs. There are a variety of
- differences and restrictions between the two statement types and they are not
- interchangeable.
- </para>
- </tip>
- </refsect1>
-
- <refsect1>
- <title>Examples</title>
-
- <para>
- Perform maintenance on CustomerAccounts based upon new Transactions.
-
-<programlisting>
-MERGE CustomerAccount CA
-USING RecentTransactions T
-ON T.CustomerId = CA.CustomerId
-WHEN MATCHED THEN
- UPDATE SET Balance = Balance + TransactionValue
-WHEN NOT MATCHED THEN
- INSERT (CustomerId, Balance)
- VALUES (T.CustomerId, T.TransactionValue);
-</programlisting>
-
- notice that this would be exactly equivalent to the following
- statement because the <literal>MATCHED</literal> result does not change
- during execution
-
-<programlisting>
-MERGE CustomerAccount CA
-USING (Select CustomerId, TransactionValue From RecentTransactions) AS T
-ON CA.CustomerId = T.CustomerId
-WHEN NOT MATCHED THEN
- INSERT (CustomerId, Balance)
- VALUES (T.CustomerId, T.TransactionValue)
-WHEN MATCHED THEN
- UPDATE SET Balance = Balance + TransactionValue;
-</programlisting>
- </para>
-
- <para>
- Attempt to insert a new stock item along with the quantity of stock. If
- the item already exists, instead update the stock count of the existing
- item. Don't allow entries that have zero stock.
-<programlisting>
-MERGE INTO wines w
-USING wine_stock_changes s
-ON s.winename = w.winename
-WHEN NOT MATCHED AND s.stock_delta > 0 THEN
- INSERT VALUES(s.winename, s.stock_delta)
-WHEN MATCHED AND w.stock + s.stock_delta > 0 THEN
- UPDATE SET stock = w.stock + s.stock_delta;
-WHEN MATCHED THEN
- DELETE;
-</programlisting>
-
- The wine_stock_changes table might be, for example, a temporary table
- recently loaded into the database.
- </para>
-
- </refsect1>
-
- <refsect1>
- <title>Compatibility</title>
- <para>
- This command conforms to the <acronym>SQL</acronym> standard.
- </para>
- <para>
- The DO NOTHING action is an extension to the <acronym>SQL</acronym> standard.
- </para>
- </refsect1>
-</refentry>