mirror of
https://github.com/postgres/postgres.git
synced 2025-06-20 15:22:23 +03:00
Revert "MERGE SQL Command following SQL:2016"
This reverts commit e6597dc353
.
This commit is contained in:
@ -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>
|
Reference in New Issue
Block a user