{"Entry":{"collection":"sql","key":"merge","name":"MERGE","aliases":["merge"],"metadata":{"aliases":["merge"],"changed_in":["17","18"],"changes":[{"from":"14","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":[],"removed":[]},"status":"added","synopsis":null,"to":"15"},{"from":"16","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["description","parameters","outputs","notes","examples","compatibility"],"removed":[]},"status":"changed","synopsis":{"added":["when_clause [...]","[ RETURNING { * | output_expression [ [ AS ] output_name ] } [, ...] ]","WHEN NOT MATCHED BY SOURCE [ AND condition ] THEN { merge_update | merge_delete | DO NOTHING } |","WHEN NOT MATCHED [ BY TARGET ] [ AND condition ] THEN { merge_insert | DO NOTHING } }"],"removed":[]},"to":"17"},{"from":"17","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["description","parameters","examples"],"removed":[]},"status":"changed","synopsis":{"added":["[ RETURNING [ WITH ( { OLD | NEW } AS output_alias [, ...] ) ]"],"removed":[]},"to":"18"},{"from":"18","purpose_changed":false,"renamed":null,"sections":{"added":[],"changed":["notes"],"removed":[]},"status":"changed","synopsis":null,"to":"19"}],"content_hash":"564f45186789eedd06b7a8ab5b2f4c80a6fa63dd8f5fd71176726b89ed7c32c4","editorial":{},"first_version":"15","group":"query","imported_at":"2026-09-27T17:57:27.074131+08:00","last_version":"20","name":"MERGE","object":"","position":11005,"present_in":["15","16","17","18","19","20"],"purpose":"conditionally insert, update, or delete rows of a table","purpose_zh":"","related":[],"slug":"merge","source_rev":"b7bd9cda","synopsis":"[ WITH with_query [, ...] ]\nMERGE INTO [ ONLY ] target_table_name [ * ] [ [ AS ] target_alias ]\nUSING data_source ON join_condition\nwhen_clause [...]\n[ RETURNING [ WITH ( { OLD | NEW } AS output_alias [, ...] ) ]\n{ * | output_expression [ [ AS ] output_name ] } [, ...] ]\n\nwhere data_source is:\n\n{ [ ONLY ] source_table_name [ * ] | ( source_query ) } [ [ AS ] source_alias ]\n\nand when_clause is:\n\n{ WHEN MATCHED [ AND condition ] THEN { merge_update | merge_delete | DO NOTHING } |\nWHEN NOT MATCHED BY SOURCE [ AND condition ] THEN { merge_update | merge_delete | DO NOTHING } |\nWHEN NOT MATCHED [ BY TARGET ] [ AND condition ] THEN { merge_insert | DO NOTHING } }\n\nand merge_insert is:\n\nINSERT [( column_name [, ...] )]\n[ OVERRIDING { SYSTEM | USER } VALUE ]\n{ VALUES ( { expression | DEFAULT } [, ...] ) | DEFAULT VALUES }\n\nand merge_update is:\n\nUPDATE SET { column_name = { expression | DEFAULT } |\n( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT } [, ...] ) |\n( column_name [, ...] ) = ( sub-SELECT )\n} [, ...]\n\nand merge_delete is:\n\nDELETE","verb":"MERGE"}},"Definition":{"Collection":"sql","Key":"merge","SourceDatabase":"center","Version":"18","SourceTable":"sqlcmd","SourceKey":"merge","SourceRevision":"b7bd9cda","Facts":{"anchor":"SQL-MERGE","file":"sql-merge.html","lang":"en","name":"MERGE","purpose":"conditionally insert, update, or delete rows of a table","purpose_zh":"","related":[],"sections":[{"html":"\u003cp\u003e\u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e performs actions that modify rows in the target table identified as \u003cem class=\"replaceable\"\u003e\u003ccode\u003etarget_table_name\u003c/code\u003e\u003c/em\u003e, using the \u003cem class=\"replaceable\"\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e. \u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e provides a single \u003cacronym\u003eSQL\u003c/acronym\u003e statement that can conditionally \u003ccode class=\"command\"\u003eINSERT\u003c/code\u003e, \u003ccode class=\"command\"\u003eUPDATE\u003c/code\u003e or \u003ccode class=\"command\"\u003eDELETE\u003c/code\u003e rows, a task that would otherwise require multiple procedural language statements.\u003c/p\u003e\u003cp\u003eFirst, the \u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e command performs a join from \u003cem class=\"replaceable\"\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e to the target table producing zero or more candidate change rows. For each candidate change row, the status of \u003ccode class=\"literal\"\u003eMATCHED\u003c/code\u003e, \u003ccode class=\"literal\"\u003eNOT MATCHED BY SOURCE\u003c/code\u003e, or \u003ccode class=\"literal\"\u003eNOT MATCHED [BY TARGET]\u003c/code\u003e is set just once, after which \u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e clauses are evaluated in the order specified. For each candidate change row, the first clause to evaluate as true is executed. No more than one \u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e clause is executed for any candidate change row.\u003c/p\u003e\u003cp\u003e\u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e actions have the same effect as regular \u003ccode class=\"command\"\u003eUPDATE\u003c/code\u003e, \u003ccode class=\"command\"\u003eINSERT\u003c/code\u003e, or \u003ccode class=\"command\"\u003eDELETE\u003c/code\u003e commands of the same names. The syntax of those commands is different, notably that there is no \u003ccode class=\"literal\"\u003eWHERE\u003c/code\u003e clause and no table name is specified. All actions refer to the target table, though modifications to other tables may be made using triggers.\u003c/p\u003e\u003cp\u003eWhen \u003ccode class=\"literal\"\u003eDO NOTHING\u003c/code\u003e is specified, the source row is skipped. Since actions are evaluated in their specified order, \u003ccode class=\"literal\"\u003eDO NOTHING\u003c/code\u003e can be handy to skip non-interesting source rows before more fine-grained handling.\u003c/p\u003e\u003cp\u003eThe optional \u003ccode class=\"literal\"\u003eRETURNING\u003c/code\u003e clause causes \u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e to compute and return value(s) based on each row inserted, updated, or deleted. Any expression using the source or target table's columns, or the \u003ca href=\"/docs/18/functions-merge-support.html#MERGE-ACTION\"\u003e\u003ccode class=\"function\"\u003emerge_action()\u003c/code\u003e\u003c/a\u003e function can be computed. By default, when an \u003ccode class=\"command\"\u003eINSERT\u003c/code\u003e or \u003ccode class=\"command\"\u003eUPDATE\u003c/code\u003e action is performed, the new values of the target table's columns are used, and when a \u003ccode class=\"command\"\u003eDELETE\u003c/code\u003e is performed, the old values of the target table's columns are used, but it is also possible to explicitly request old and new values. The syntax of the \u003ccode class=\"literal\"\u003eRETURNING\u003c/code\u003e list is identical to that of the output list of \u003ccode class=\"command\"\u003eSELECT\u003c/code\u003e.\u003c/p\u003e\u003cp\u003eThere is no separate \u003ccode class=\"literal\"\u003eMERGE\u003c/code\u003e privilege. If you specify an update action, you must have the \u003ccode class=\"literal\"\u003eUPDATE\u003c/code\u003e privilege on the column(s) of the target table that are referred to in the \u003ccode class=\"literal\"\u003eSET\u003c/code\u003e clause. If you specify an insert action, you must have the \u003ccode class=\"literal\"\u003eINSERT\u003c/code\u003e privilege on the target table. If you specify a delete action, you must have the \u003ccode class=\"literal\"\u003eDELETE\u003c/code\u003e privilege on the target table. If you specify a \u003ccode class=\"literal\"\u003eDO NOTHING\u003c/code\u003e action, you must have the \u003ccode class=\"literal\"\u003eSELECT\u003c/code\u003e privilege on at least one column of the target table. You will also need \u003ccode class=\"literal\"\u003eSELECT\u003c/code\u003e privilege on any column(s) of the \u003cem class=\"replaceable\"\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e and of the target table referred to in any \u003ccode class=\"literal\"\u003econdition\u003c/code\u003e (including \u003ccode class=\"literal\"\u003ejoin_condition\u003c/code\u003e) or \u003ccode class=\"literal\"\u003eexpression\u003c/code\u003e. Privileges are tested once at statement start and are checked whether or not particular \u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e clauses are executed.\u003c/p\u003e\u003cp\u003e\u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e is not supported if the target table is a materialized view, foreign table, or if it has any rules defined on it.\u003c/p\u003e","key":"description","title":"Description"},{"html":"\u003cdiv class=\"variablelist\"\u003e\u003cdl class=\"variablelist\"\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003ewith_query\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eThe \u003ccode class=\"literal\"\u003eWITH\u003c/code\u003e clause allows you to specify one or more subqueries that can be referenced by name in the \u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e query. See \u003ca href=\"/docs/18/queries-with.html\" title=\"7.8. WITH Queries (Common Table Expressions)\"\u003eSection 7.8\u003c/a\u003e and \u003ca href=\"/docs/18/sql-select.html\" title=\"SELECT\"\u003e\u003cspan class=\"refentrytitle\"\u003eSELECT\u003c/span\u003e\u003c/a\u003e for details. Note that \u003ccode class=\"literal\"\u003eWITH RECURSIVE\u003c/code\u003e is not supported by \u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e.\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003etarget_table_name\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eThe name (optionally schema-qualified) of the target table or view to merge into. If \u003ccode class=\"literal\"\u003eONLY\u003c/code\u003e is specified before a table name, matching rows are updated or deleted in the named table only. If \u003ccode class=\"literal\"\u003eONLY\u003c/code\u003e is not specified, matching rows are also updated or deleted in any tables inheriting from the named table. Optionally, \u003ccode class=\"literal\"\u003e*\u003c/code\u003e can be specified after the table name to explicitly indicate that descendant tables are included. The \u003ccode class=\"literal\"\u003eONLY\u003c/code\u003e keyword and \u003ccode class=\"literal\"\u003e*\u003c/code\u003e option do not affect insert actions, which always insert into the named table only.\u003c/p\u003e\u003cp\u003eIf \u003cem class=\"replaceable\"\u003e\u003ccode\u003etarget_table_name\u003c/code\u003e\u003c/em\u003e is a view, it must either be automatically updatable with no \u003ccode class=\"literal\"\u003eINSTEAD OF\u003c/code\u003e triggers, or it must have \u003ccode class=\"literal\"\u003eINSTEAD OF\u003c/code\u003e triggers for every type of action (\u003ccode class=\"literal\"\u003eINSERT\u003c/code\u003e, \u003ccode class=\"literal\"\u003eUPDATE\u003c/code\u003e, and \u003ccode class=\"literal\"\u003eDELETE\u003c/code\u003e) specified in the \u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e clauses. Views with rules are not supported.\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003etarget_alias\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eA substitute name for the target table. When an alias is provided, it completely hides the actual name of the table. For example, given \u003ccode class=\"literal\"\u003eMERGE INTO foo AS f\u003c/code\u003e, the remainder of the \u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e statement must refer to this table as \u003ccode class=\"literal\"\u003ef\u003c/code\u003e not \u003ccode class=\"literal\"\u003efoo\u003c/code\u003e.\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003esource_table_name\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eThe name (optionally schema-qualified) of the source table, view, or transition table. If \u003ccode class=\"literal\"\u003eONLY\u003c/code\u003e is specified before the table name, matching rows are included from the named table only. If \u003ccode class=\"literal\"\u003eONLY\u003c/code\u003e is not specified, matching rows are also included from any tables inheriting from the named table. Optionally, \u003ccode class=\"literal\"\u003e*\u003c/code\u003e can be specified after the table name to explicitly indicate that descendant tables are included.\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003esource_query\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eA query (\u003ccode class=\"command\"\u003eSELECT\u003c/code\u003e statement or \u003ccode class=\"command\"\u003eVALUES\u003c/code\u003e statement) that supplies the rows to be merged into the target table. Refer to the \u003ca href=\"/docs/18/sql-select.html\" title=\"SELECT\"\u003e\u003cspan class=\"refentrytitle\"\u003eSELECT\u003c/span\u003e\u003c/a\u003e statement or \u003ca href=\"/docs/18/sql-values.html\" title=\"VALUES\"\u003e\u003cspan class=\"refentrytitle\"\u003eVALUES\u003c/span\u003e\u003c/a\u003e statement for a description of the syntax.\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003esource_alias\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eA substitute name for the data source. When an alias is provided, it completely hides the actual name of the table or the fact that a query was issued.\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003ejoin_condition\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003ejoin_condition\u003c/code\u003e\u003c/em\u003e is an expression resulting in a value of type \u003ccode class=\"type\"\u003eboolean\u003c/code\u003e (similar to a \u003ccode class=\"literal\"\u003eWHERE\u003c/code\u003e clause) that specifies which rows in the \u003cem class=\"replaceable\"\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e match rows in the target table.\u003c/p\u003e\u003cdiv class=\"warning\"\u003e\u003ch3\u003eWarning\u003c/h3\u003e\u003cp\u003eOnly columns from the target table that attempt to match \u003cem class=\"replaceable\"\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e rows should appear in \u003cem class=\"replaceable\"\u003e\u003ccode\u003ejoin_condition\u003c/code\u003e\u003c/em\u003e. \u003cem class=\"replaceable\"\u003e\u003ccode\u003ejoin_condition\u003c/code\u003e\u003c/em\u003e subexpressions that only reference the target table's columns can affect which action is taken, often in surprising ways.\u003c/p\u003e\u003cp\u003eIf both \u003ccode class=\"literal\"\u003eWHEN NOT MATCHED BY SOURCE\u003c/code\u003e and \u003ccode class=\"literal\"\u003eWHEN NOT MATCHED [BY TARGET]\u003c/code\u003e clauses are specified, the \u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e command will perform a \u003ccode class=\"literal\"\u003eFULL\u003c/code\u003e join between \u003cem class=\"replaceable\"\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e and the target table. For this to work, at least one \u003cem class=\"replaceable\"\u003e\u003ccode\u003ejoin_condition\u003c/code\u003e\u003c/em\u003e subexpression must use an operator that can support a hash join, or all of the subexpressions must use operators that can support a merge join.\u003c/p\u003e\u003c/div\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003ewhen_clause\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eAt least one \u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e clause is required.\u003c/p\u003e\u003cp\u003eThe \u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e clause may specify \u003ccode class=\"literal\"\u003eWHEN MATCHED\u003c/code\u003e, \u003ccode class=\"literal\"\u003eWHEN NOT MATCHED BY SOURCE\u003c/code\u003e, or \u003ccode class=\"literal\"\u003eWHEN NOT MATCHED [BY TARGET]\u003c/code\u003e. Note that the \u003cacronym\u003eSQL\u003c/acronym\u003e standard only defines \u003ccode class=\"literal\"\u003eWHEN MATCHED\u003c/code\u003e and \u003ccode class=\"literal\"\u003eWHEN NOT MATCHED\u003c/code\u003e (which is defined to mean no matching target row). \u003ccode class=\"literal\"\u003eWHEN NOT MATCHED BY SOURCE\u003c/code\u003e is an extension to the \u003cacronym\u003eSQL\u003c/acronym\u003e standard, as is the option to append \u003ccode class=\"literal\"\u003eBY TARGET\u003c/code\u003e to \u003ccode class=\"literal\"\u003eWHEN NOT MATCHED\u003c/code\u003e, to make its meaning more explicit.\u003c/p\u003e\u003cp\u003eIf the \u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e clause specifies \u003ccode class=\"literal\"\u003eWHEN MATCHED\u003c/code\u003e and the candidate change row matches a row in the \u003cem class=\"replaceable\"\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e to a row in the target table, the \u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e clause is executed if the \u003cem class=\"replaceable\"\u003e\u003ccode\u003econdition\u003c/code\u003e\u003c/em\u003e is absent or it evaluates to \u003ccode class=\"literal\"\u003etrue\u003c/code\u003e.\u003c/p\u003e\u003cp\u003eIf the \u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e clause specifies \u003ccode class=\"literal\"\u003eWHEN NOT MATCHED BY SOURCE\u003c/code\u003e and the candidate change row represents a row in the target table that does not match a row in the \u003cem class=\"replaceable\"\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e, the \u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e clause is executed if the \u003cem class=\"replaceable\"\u003e\u003ccode\u003econdition\u003c/code\u003e\u003c/em\u003e is absent or it evaluates to \u003ccode class=\"literal\"\u003etrue\u003c/code\u003e.\u003c/p\u003e\u003cp\u003eIf the \u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e clause specifies \u003ccode class=\"literal\"\u003eWHEN NOT MATCHED [BY TARGET]\u003c/code\u003e and the candidate change row represents a row in the \u003cem class=\"replaceable\"\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e that does not match a row in the target table, the \u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e clause is executed if the \u003cem class=\"replaceable\"\u003e\u003ccode\u003econdition\u003c/code\u003e\u003c/em\u003e is absent or it evaluates to \u003ccode class=\"literal\"\u003etrue\u003c/code\u003e.\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003econdition\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eAn expression that returns a value of type \u003ccode class=\"type\"\u003eboolean\u003c/code\u003e. If this expression for a \u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e clause returns \u003ccode class=\"literal\"\u003etrue\u003c/code\u003e, then the action for that clause is executed for that row.\u003c/p\u003e\u003cp\u003eA condition on a \u003ccode class=\"literal\"\u003eWHEN MATCHED\u003c/code\u003e clause can refer to columns in both the source and the target relations. A condition on a \u003ccode class=\"literal\"\u003eWHEN NOT MATCHED BY SOURCE\u003c/code\u003e clause can only refer to columns from the target relation, since by definition there is no matching source row. A condition on a \u003ccode class=\"literal\"\u003eWHEN NOT MATCHED [BY TARGET]\u003c/code\u003e 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.\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003emerge_insert\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eThe specification of an \u003ccode class=\"literal\"\u003eINSERT\u003c/code\u003e 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.\u003c/p\u003e\u003cp\u003eEach 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.\u003c/p\u003e\u003cp\u003eIf the target table is a partitioned table, each row is routed to the appropriate partition and inserted into it. If the target table is a partition, an error will occur if any input row violates the partition constraint.\u003c/p\u003e\u003cp\u003eColumn names may not be specified more than once. \u003ccode class=\"command\"\u003eINSERT\u003c/code\u003e actions cannot contain sub-selects.\u003c/p\u003e\u003cp\u003eOnly one \u003ccode class=\"literal\"\u003eVALUES\u003c/code\u003e clause can be specified. The \u003ccode class=\"literal\"\u003eVALUES\u003c/code\u003e clause can only refer to columns from the source relation, since by definition there is no matching target row.\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003emerge_update\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eThe specification of an \u003ccode class=\"literal\"\u003eUPDATE\u003c/code\u003e action that updates the current row of the target table. Column names may not be specified more than once.\u003c/p\u003e\u003cp\u003eNeither a table name nor a \u003ccode class=\"literal\"\u003eWHERE\u003c/code\u003e clause are allowed.\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003emerge_delete\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eSpecifies a \u003ccode class=\"literal\"\u003eDELETE\u003c/code\u003e action that deletes the current row of the target table. Do not include the table name or any other clauses, as you would normally do with a \u003ca href=\"/docs/18/sql-delete.html\" title=\"DELETE\"\u003e\u003cspan class=\"refentrytitle\"\u003eDELETE\u003c/span\u003e\u003c/a\u003e command.\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003ecolumn_name\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eThe name of a column in the target table. 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.) Do not include the table's name in the specification of a target column.\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003ccode class=\"literal\"\u003eOVERRIDING SYSTEM VALUE\u003c/code\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eWithout this clause, it is an error to specify an explicit value (other than \u003ccode class=\"literal\"\u003eDEFAULT\u003c/code\u003e) for an identity column defined as \u003ccode class=\"literal\"\u003eGENERATED ALWAYS\u003c/code\u003e. This clause overrides that restriction.\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003ccode class=\"literal\"\u003eOVERRIDING USER VALUE\u003c/code\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eIf this clause is specified, then any values supplied for identity columns defined as \u003ccode class=\"literal\"\u003eGENERATED BY DEFAULT\u003c/code\u003e are ignored and the default sequence-generated values are applied.\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003ccode class=\"literal\"\u003eDEFAULT VALUES\u003c/code\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eAll columns will be filled with their default values. (An \u003ccode class=\"literal\"\u003eOVERRIDING\u003c/code\u003e clause is not permitted in this form.)\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003eexpression\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eAn expression to assign to the column. If used in a \u003ccode class=\"literal\"\u003eWHEN MATCHED\u003c/code\u003e clause, the expression can use values from the original row in the target table, and values from the \u003cem class=\"replaceable\"\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e row. If used in a \u003ccode class=\"literal\"\u003eWHEN NOT MATCHED BY SOURCE\u003c/code\u003e clause, the expression can only use values from the original row in the target table. If used in a \u003ccode class=\"literal\"\u003eWHEN NOT MATCHED [BY TARGET]\u003c/code\u003e clause, the expression can only use values from the \u003cem class=\"replaceable\"\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e row.\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003ccode class=\"literal\"\u003eDEFAULT\u003c/code\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eSet the column to its default value (which will be \u003ccode class=\"literal\"\u003eNULL\u003c/code\u003e if no specific default expression has been assigned to it).\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003esub-SELECT\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eA \u003ccode class=\"literal\"\u003eSELECT\u003c/code\u003e sub-query that produces as many output columns as are listed in the parenthesized column list preceding it. The sub-query must yield no more than one row when executed. If it yields one row, its column values are assigned to the target columns; if it yields no rows, NULL values are assigned to the target columns. If used in a \u003ccode class=\"literal\"\u003eWHEN MATCHED\u003c/code\u003e clause, the sub-query can refer to values from the original row in the target table, and values from the \u003cem class=\"replaceable\"\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e row. If used in a \u003ccode class=\"literal\"\u003eWHEN NOT MATCHED BY SOURCE\u003c/code\u003e clause, the sub-query can only refer to values from the original row in the target table.\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003eoutput_alias\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eAn optional substitute name for \u003ccode class=\"literal\"\u003eOLD\u003c/code\u003e or \u003ccode class=\"literal\"\u003eNEW\u003c/code\u003e rows in the \u003ccode class=\"literal\"\u003eRETURNING\u003c/code\u003e list.\u003c/p\u003e\u003cp\u003eBy default, old values from the target table can be returned by writing \u003ccode class=\"literal\"\u003eOLD.\u003cem class=\"replaceable\"\u003e\u003ccode\u003ecolumn_name\u003c/code\u003e\u003c/em\u003e\u003c/code\u003e or \u003ccode class=\"literal\"\u003eOLD.*\u003c/code\u003e, and new values can be returned by writing \u003ccode class=\"literal\"\u003eNEW.\u003cem class=\"replaceable\"\u003e\u003ccode\u003ecolumn_name\u003c/code\u003e\u003c/em\u003e\u003c/code\u003e or \u003ccode class=\"literal\"\u003eNEW.*\u003c/code\u003e. When an alias is provided, these names are hidden and the old or new rows must be referred to using the alias. For example \u003ccode class=\"literal\"\u003eRETURNING WITH (OLD AS o, NEW AS n) o.*, n.*\u003c/code\u003e.\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003eoutput_expression\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eAn expression to be computed and returned by the \u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e command after each row is changed (whether inserted, updated, or deleted). The expression can use any columns of the source or target tables, or the \u003ca href=\"/docs/18/functions-merge-support.html#MERGE-ACTION\"\u003e\u003ccode class=\"function\"\u003emerge_action()\u003c/code\u003e\u003c/a\u003e function to return additional information about the action executed.\u003c/p\u003e\u003cp\u003eWriting \u003ccode class=\"literal\"\u003e*\u003c/code\u003e will return all columns from the source table, followed by all columns from the target table. Often this will lead to a lot of duplication, since it is common for the source and target tables to have a lot of the same columns. This can be avoided by qualifying the \u003ccode class=\"literal\"\u003e*\u003c/code\u003e with the name or alias of the source or target table.\u003c/p\u003e\u003cp\u003eA column name or \u003ccode class=\"literal\"\u003e*\u003c/code\u003e may also be qualified using \u003ccode class=\"literal\"\u003eOLD\u003c/code\u003e or \u003ccode class=\"literal\"\u003eNEW\u003c/code\u003e, or the corresponding \u003cem class=\"replaceable\"\u003e\u003ccode\u003eoutput_alias\u003c/code\u003e\u003c/em\u003e for \u003ccode class=\"literal\"\u003eOLD\u003c/code\u003e or \u003ccode class=\"literal\"\u003eNEW\u003c/code\u003e, to cause old or new values from the target table to be returned. An unqualified column name from the target table, or a column name or \u003ccode class=\"literal\"\u003e*\u003c/code\u003e qualified using the target table name or alias will return new values for \u003ccode class=\"literal\"\u003eINSERT\u003c/code\u003e and \u003ccode class=\"literal\"\u003eUPDATE\u003c/code\u003e actions, and old values for \u003ccode class=\"literal\"\u003eDELETE\u003c/code\u003e actions.\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003eoutput_name\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003eA name to use for a returned column.\u003c/p\u003e\u003c/dd\u003e\u003c/dl\u003e\u003c/div\u003e","key":"parameters","title":"Parameters"},{"html":"\u003cp\u003eOn successful completion, a \u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e command returns a command tag of the form\u003c/p\u003e\u003cpre class=\"screen\"\u003eMERGE \u003cem class=\"replaceable\"\u003e\u003ccode\u003etotal_count\u003c/code\u003e\u003c/em\u003e\n\u003c/pre\u003e\u003cp\u003eThe \u003cem class=\"replaceable\"\u003e\u003ccode\u003etotal_count\u003c/code\u003e\u003c/em\u003e is the total number of rows changed (whether inserted, updated, or deleted). If \u003cem class=\"replaceable\"\u003e\u003ccode\u003etotal_count\u003c/code\u003e\u003c/em\u003e is 0, no rows were changed in any way.\u003c/p\u003e\u003cp\u003eIf the \u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e command contains a \u003ccode class=\"literal\"\u003eRETURNING\u003c/code\u003e clause, the result will be similar to that of a \u003ccode class=\"command\"\u003eSELECT\u003c/code\u003e statement containing the columns and values defined in the \u003ccode class=\"literal\"\u003eRETURNING\u003c/code\u003e list, computed over the row(s) inserted, updated, or deleted by the command.\u003c/p\u003e","key":"outputs","title":"Outputs"},{"html":"\u003cp\u003eThe following steps take place during the execution of \u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e.\u003c/p\u003e\u003cdiv class=\"orderedlist\"\u003e\u003col class=\"orderedlist\"\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003ePerform any \u003ccode class=\"literal\"\u003eBEFORE STATEMENT\u003c/code\u003e triggers for all actions specified, whether or not their \u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e clauses match.\u003c/p\u003e\u003c/li\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003ePerform a join from source to target table. The resulting query will be optimized normally and will produce a set of candidate change rows. For each candidate change row,\u003c/p\u003e\u003cdiv class=\"orderedlist\"\u003e\u003col class=\"orderedlist\"\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003eEvaluate whether each row is \u003ccode class=\"literal\"\u003eMATCHED\u003c/code\u003e, \u003ccode class=\"literal\"\u003eNOT MATCHED BY SOURCE\u003c/code\u003e, or \u003ccode class=\"literal\"\u003eNOT MATCHED [BY TARGET]\u003c/code\u003e.\u003c/p\u003e\u003c/li\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003eTest each \u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e condition in the order specified until one returns true.\u003c/p\u003e\u003c/li\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003eWhen a condition returns true, perform the following actions:\u003c/p\u003e\u003cdiv class=\"orderedlist\"\u003e\u003col class=\"orderedlist\"\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003ePerform any \u003ccode class=\"literal\"\u003eBEFORE ROW\u003c/code\u003e triggers that fire for the action's event type.\u003c/p\u003e\u003c/li\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003ePerform the specified action, invoking any check constraints on the target table.\u003c/p\u003e\u003c/li\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003ePerform any \u003ccode class=\"literal\"\u003eAFTER ROW\u003c/code\u003e triggers that fire for the action's event type.\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003c/div\u003e\u003cp\u003eIf the target relation is a view with \u003ccode class=\"literal\"\u003eINSTEAD OF ROW\u003c/code\u003e triggers for the action's event type, they are used to perform the action instead.\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003c/div\u003e\u003c/li\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003ePerform any \u003ccode class=\"literal\"\u003eAFTER STATEMENT\u003c/code\u003e triggers for actions specified, whether or not they actually occur. This is similar to the behavior of an \u003ccode class=\"command\"\u003eUPDATE\u003c/code\u003e statement that modifies no rows.\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003c/div\u003e\u003cp\u003eIn summary, statement triggers for an event type (say, \u003ccode class=\"command\"\u003eINSERT\u003c/code\u003e) will be fired whenever we \u003cspan class=\"emphasis\"\u003e\u003cem\u003especify\u003c/em\u003e\u003c/span\u003e an action of that kind. In contrast, row-level triggers will fire only for the specific event type being \u003cspan class=\"emphasis\"\u003e\u003cem\u003eexecuted\u003c/em\u003e\u003c/span\u003e. So a \u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e command might fire statement triggers for both \u003ccode class=\"command\"\u003eUPDATE\u003c/code\u003e and \u003ccode class=\"command\"\u003eINSERT\u003c/code\u003e, even though only \u003ccode class=\"command\"\u003eUPDATE\u003c/code\u003e row triggers were fired.\u003c/p\u003e\u003cp\u003eYou 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 the row will cause an error. This can also occur if row triggers make changes to the target table and the rows so modified are then subsequently also modified by \u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e. If the repeated action is an \u003ccode class=\"command\"\u003eINSERT\u003c/code\u003e, this will cause a uniqueness violation, while a repeated \u003ccode class=\"command\"\u003eUPDATE\u003c/code\u003e or \u003ccode class=\"command\"\u003eDELETE\u003c/code\u003e will cause a cardinality violation; the latter behavior is required by the \u003cacronym\u003eSQL\u003c/acronym\u003e standard. This differs from historical \u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e behavior of joins in \u003ccode class=\"command\"\u003eUPDATE\u003c/code\u003e and \u003ccode class=\"command\"\u003eDELETE\u003c/code\u003e statements where second and subsequent attempts to modify the same row are simply ignored.\u003c/p\u003e\u003cp\u003eIf a \u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e clause omits an \u003ccode class=\"literal\"\u003eAND\u003c/code\u003e sub-clause, it becomes the final reachable clause of that kind (\u003ccode class=\"literal\"\u003eMATCHED\u003c/code\u003e, \u003ccode class=\"literal\"\u003eNOT MATCHED BY SOURCE\u003c/code\u003e, or \u003ccode class=\"literal\"\u003eNOT MATCHED [BY TARGET]\u003c/code\u003e). If a later \u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e clause of that kind is specified it would be provably unreachable and an error is raised. If no final reachable clause is specified of either kind, it is possible that no action will be taken for a candidate change row.\u003c/p\u003e\u003cp\u003eThe order in which rows are generated from the data source is indeterminate by default. A \u003cem class=\"replaceable\"\u003e\u003ccode\u003esource_query\u003c/code\u003e\u003c/em\u003e can be used to specify a consistent ordering, if required, which might be needed to avoid deadlocks between concurrent transactions.\u003c/p\u003e\u003cp\u003eWhen \u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e is run concurrently with other commands that modify the target table, the usual transaction isolation rules apply; see \u003ca href=\"/docs/18/transaction-iso.html\" title=\"13.2. Transaction Isolation\"\u003eSection 13.2\u003c/a\u003e for an explanation on the behavior at each isolation level. You may also wish to consider using \u003ccode class=\"command\"\u003eINSERT ... ON CONFLICT\u003c/code\u003e as an alternative statement which offers the ability to run an \u003ccode class=\"command\"\u003eUPDATE\u003c/code\u003e if a concurrent \u003ccode class=\"command\"\u003eINSERT\u003c/code\u003e occurs. There are a variety of differences and restrictions between the two statement types and they are not interchangeable.\u003c/p\u003e","key":"notes","title":"Notes"},{"html":"\u003cp\u003ePerform maintenance on \u003ccode class=\"literal\"\u003ecustomer_accounts\u003c/code\u003e based upon new \u003ccode class=\"literal\"\u003erecent_transactions\u003c/code\u003e.\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eMERGE INTO customer_account ca\nUSING recent_transactions t\nON t.customer_id = ca.customer_id\nWHEN MATCHED THEN\n  UPDATE SET balance = balance + transaction_value\nWHEN NOT MATCHED THEN\n  INSERT (customer_id, balance)\n  VALUES (t.customer_id, t.transaction_value);\n\u003c/pre\u003e\u003cp\u003eAttempt 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. Return details of all changes made.\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eMERGE INTO wines w\nUSING wine_stock_changes s\nON s.winename = w.winename\nWHEN NOT MATCHED AND s.stock_delta \u0026gt; 0 THEN\n  INSERT VALUES(s.winename, s.stock_delta)\nWHEN MATCHED AND w.stock + s.stock_delta \u0026gt; 0 THEN\n  UPDATE SET stock = w.stock + s.stock_delta\nWHEN MATCHED THEN\n  DELETE\nRETURNING merge_action(), w.winename, old.stock AS old_stock, new.stock AS new_stock;\n\u003c/pre\u003e\u003cp\u003eThe \u003ccode class=\"literal\"\u003ewine_stock_changes\u003c/code\u003e table might be, for example, a temporary table recently loaded into the database.\u003c/p\u003e\u003cp\u003eUpdate \u003ccode class=\"literal\"\u003ewines\u003c/code\u003e based on a replacement wine list, inserting rows for any new stock, updating modified stock entries, and deleting any wines not present in the new list.\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eMERGE INTO wines w\nUSING new_wine_list s\nON s.winename = w.winename\nWHEN NOT MATCHED BY TARGET THEN\n  INSERT VALUES(s.winename, s.stock)\nWHEN MATCHED AND w.stock != s.stock THEN\n  UPDATE SET stock = s.stock\nWHEN NOT MATCHED BY SOURCE THEN\n  DELETE;\n\u003c/pre\u003e","key":"examples","title":"Examples"},{"html":"\u003cp\u003eThis command conforms to the \u003cacronym\u003eSQL\u003c/acronym\u003e standard.\u003c/p\u003e\u003cp\u003eThe \u003ccode class=\"literal\"\u003eWITH\u003c/code\u003e clause, \u003ccode class=\"literal\"\u003eBY SOURCE\u003c/code\u003e and \u003ccode class=\"literal\"\u003eBY TARGET\u003c/code\u003e qualifiers to \u003ccode class=\"literal\"\u003eWHEN NOT MATCHED\u003c/code\u003e, \u003ccode class=\"literal\"\u003eDO NOTHING\u003c/code\u003e action, and \u003ccode class=\"literal\"\u003eRETURNING\u003c/code\u003e clause are extensions to the \u003cacronym\u003eSQL\u003c/acronym\u003e standard.\u003c/p\u003e","key":"compatibility","title":"Compatibility"}],"sections_same_as":"","slug":"18","synopsis_html":"[ WITH \u003cem class=\"replaceable\"\u003e\u003ccode\u003ewith_query\u003c/code\u003e\u003c/em\u003e [, ...] ]\nMERGE INTO [ ONLY ] \u003cem class=\"replaceable\"\u003e\u003ccode\u003etarget_table_name\u003c/code\u003e\u003c/em\u003e [ * ] [ [ AS ] \u003cem class=\"replaceable\"\u003e\u003ccode\u003etarget_alias\u003c/code\u003e\u003c/em\u003e ]\n    USING \u003cem class=\"replaceable\"\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e ON \u003cem class=\"replaceable\"\u003e\u003ccode\u003ejoin_condition\u003c/code\u003e\u003c/em\u003e\n    \u003cem class=\"replaceable\"\u003e\u003ccode\u003ewhen_clause\u003c/code\u003e\u003c/em\u003e [...]\n    [ RETURNING [ WITH ( { OLD | NEW } AS \u003cem class=\"replaceable\"\u003e\u003ccode\u003eoutput_alias\u003c/code\u003e\u003c/em\u003e [, ...] ) ]\n                { * | \u003cem class=\"replaceable\"\u003e\u003ccode\u003eoutput_expression\u003c/code\u003e\u003c/em\u003e [ [ AS ] \u003cem class=\"replaceable\"\u003e\u003ccode\u003eoutput_name\u003c/code\u003e\u003c/em\u003e ] } [, ...] ]\n\n\u003cspan class=\"phrase\"\u003ewhere \u003cem class=\"replaceable\"\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e is:\u003c/span\u003e\n\n    { [ ONLY ] \u003cem class=\"replaceable\"\u003e\u003ccode\u003esource_table_name\u003c/code\u003e\u003c/em\u003e [ * ] | ( \u003cem class=\"replaceable\"\u003e\u003ccode\u003esource_query\u003c/code\u003e\u003c/em\u003e ) } [ [ AS ] \u003cem class=\"replaceable\"\u003e\u003ccode\u003esource_alias\u003c/code\u003e\u003c/em\u003e ]\n\n\u003cspan class=\"phrase\"\u003eand \u003cem class=\"replaceable\"\u003e\u003ccode\u003ewhen_clause\u003c/code\u003e\u003c/em\u003e is:\u003c/span\u003e\n\n    { WHEN MATCHED [ AND \u003cem class=\"replaceable\"\u003e\u003ccode\u003econdition\u003c/code\u003e\u003c/em\u003e ] THEN { \u003cem class=\"replaceable\"\u003e\u003ccode\u003emerge_update\u003c/code\u003e\u003c/em\u003e | \u003cem class=\"replaceable\"\u003e\u003ccode\u003emerge_delete\u003c/code\u003e\u003c/em\u003e | DO NOTHING } |\n      WHEN NOT MATCHED BY SOURCE [ AND \u003cem class=\"replaceable\"\u003e\u003ccode\u003econdition\u003c/code\u003e\u003c/em\u003e ] THEN { \u003cem class=\"replaceable\"\u003e\u003ccode\u003emerge_update\u003c/code\u003e\u003c/em\u003e | \u003cem class=\"replaceable\"\u003e\u003ccode\u003emerge_delete\u003c/code\u003e\u003c/em\u003e | DO NOTHING } |\n      WHEN NOT MATCHED [ BY TARGET ] [ AND \u003cem class=\"replaceable\"\u003e\u003ccode\u003econdition\u003c/code\u003e\u003c/em\u003e ] THEN { \u003cem class=\"replaceable\"\u003e\u003ccode\u003emerge_insert\u003c/code\u003e\u003c/em\u003e | DO NOTHING } }\n\n\u003cspan class=\"phrase\"\u003eand \u003cem class=\"replaceable\"\u003e\u003ccode\u003emerge_insert\u003c/code\u003e\u003c/em\u003e is:\u003c/span\u003e\n\n    INSERT [( \u003cem class=\"replaceable\"\u003e\u003ccode\u003ecolumn_name\u003c/code\u003e\u003c/em\u003e [, ...] )]\n        [ OVERRIDING { SYSTEM | USER } VALUE ]\n        { VALUES ( { \u003cem class=\"replaceable\"\u003e\u003ccode\u003eexpression\u003c/code\u003e\u003c/em\u003e | DEFAULT } [, ...] ) | DEFAULT VALUES }\n\n\u003cspan class=\"phrase\"\u003eand \u003cem class=\"replaceable\"\u003e\u003ccode\u003emerge_update\u003c/code\u003e\u003c/em\u003e is:\u003c/span\u003e\n\n    UPDATE SET { \u003cem class=\"replaceable\"\u003e\u003ccode\u003ecolumn_name\u003c/code\u003e\u003c/em\u003e = { \u003cem class=\"replaceable\"\u003e\u003ccode\u003eexpression\u003c/code\u003e\u003c/em\u003e | DEFAULT } |\n                 ( \u003cem class=\"replaceable\"\u003e\u003ccode\u003ecolumn_name\u003c/code\u003e\u003c/em\u003e [, ...] ) = [ ROW ] ( { \u003cem class=\"replaceable\"\u003e\u003ccode\u003eexpression\u003c/code\u003e\u003c/em\u003e | DEFAULT } [, ...] ) |\n                 ( \u003cem class=\"replaceable\"\u003e\u003ccode\u003ecolumn_name\u003c/code\u003e\u003c/em\u003e [, ...] ) = ( \u003cem class=\"replaceable\"\u003e\u003ccode\u003esub-SELECT\u003c/code\u003e\u003c/em\u003e )\n               } [, ...]\n\n\u003cspan class=\"phrase\"\u003eand \u003cem class=\"replaceable\"\u003e\u003ccode\u003emerge_delete\u003c/code\u003e\u003c/em\u003e is:\u003c/span\u003e\n\n    DELETE","synopsis_text":"[ WITH with_query [, ...] ]\nMERGE INTO [ ONLY ] target_table_name [ * ] [ [ AS ] target_alias ]\nUSING data_source ON join_condition\nwhen_clause [...]\n[ RETURNING [ WITH ( { OLD | NEW } AS output_alias [, ...] ) ]\n{ * | output_expression [ [ AS ] output_name ] } [, ...] ]\n\nwhere data_source is:\n\n{ [ ONLY ] source_table_name [ * ] | ( source_query ) } [ [ AS ] source_alias ]\n\nand when_clause is:\n\n{ WHEN MATCHED [ AND condition ] THEN { merge_update | merge_delete | DO NOTHING } |\nWHEN NOT MATCHED BY SOURCE [ AND condition ] THEN { merge_update | merge_delete | DO NOTHING } |\nWHEN NOT MATCHED [ BY TARGET ] [ AND condition ] THEN { merge_insert | DO NOTHING } }\n\nand merge_insert is:\n\nINSERT [( column_name [, ...] )]\n[ OVERRIDING { SYSTEM | USER } VALUE ]\n{ VALUES ( { expression | DEFAULT } [, ...] ) | DEFAULT VALUES }\n\nand merge_update is:\n\nUPDATE SET { column_name = { expression | DEFAULT } |\n( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT } [, ...] ) |\n( column_name [, ...] ) = ( sub-SELECT )\n} [, ...]\n\nand merge_delete is:\n\nDELETE"},"ManualEvidence":{},"MeasuredEvidence":{}},"Text":{"Collection":"sql","Key":"merge","SourceDatabase":"pgweb","Version":"18","Locale":"zh-Hans","Title":"MERGE","Summary":"有条件地插入、更新或删除表中的行","BodyHTML":"\u003cpre\u003e[ WITH with_query [, ...] ]\nMERGE INTO [ ONLY ] target_table_name [ * ] [ [ AS ] target_alias ]\nUSING data_source ON join_condition\nwhen_clause [...]\n[ RETURNING [ WITH ( { OLD | NEW } AS output_alias [, ...] ) ]\n{ * | output_expression [ [ AS ] output_name ] } [, ...] ]\n\n其中 data_source 为：\n\n{ [ ONLY ] source_table_name [ * ] | ( source_query ) } [ [ AS ] source_alias ]\n\n而 when_clause 为：\n\n{ WHEN MATCHED [ AND condition ] THEN { merge_update | merge_delete | DO NOTHING } |\nWHEN NOT MATCHED BY SOURCE [ AND condition ] THEN { merge_update | merge_delete | DO NOTHING } |\nWHEN NOT MATCHED [ BY TARGET ] [ AND condition ] THEN { merge_insert | DO NOTHING } }\n\n而 merge_insert 为：\n\nINSERT [( column_name [, ...] )]\n[ OVERRIDING { SYSTEM | USER } VALUE ]\n{ VALUES ( { expression | DEFAULT } [, ...] ) | DEFAULT VALUES }\n\n而 merge_update 为：\n\nUPDATE SET { column_name = { expression | DEFAULT } |\n( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT } [, ...] ) |\n( column_name [, ...] ) = ( sub-SELECT )\n} [, ...]\n\n而 merge_delete 为：\n\nDELETE\u003c/pre\u003e\u003csection\u003e\u003ch2\u003e描述\u003c/h2\u003e\u003cp\u003e\u003ccode\u003eMERGE\u003c/code\u003e使用\u003cem\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e 对由\u003cem\u003e\u003ccode\u003etarget_table_name\u003c/code\u003e\u003c/em\u003e标识的目标表中的行执行修改动作。\u003ccode\u003eMERGE\u003c/code\u003e提供了一条单独的\u003cacronym\u003eSQL\u003c/acronym\u003e语句，可按条件对行执行\u003ccode\u003eINSERT\u003c/code\u003e、\u003ccode\u003eUPDATE\u003c/code\u003e或\u003ccode\u003eDELETE\u003c/code\u003e；否则，这项工作需要多条过程语言语句。\u003c/p\u003e\u003cp\u003e首先，\u003ccode\u003eMERGE\u003c/code\u003e命令会将\u003cem\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e 与目标表执行连接，生成零个或多个候选变更行。对于每个候选变更行，系统只会确定一次其状态是\u003ccode\u003eMATCHED\u003c/code\u003e、\u003ccode\u003eNOT MATCHED BY SOURCE\u003c/code\u003e还是 \u003ccode\u003eNOT MATCHED [BY TARGET]\u003c/code\u003e，然后按指定顺序对 \u003ccode\u003eWHEN\u003c/code\u003e子句求值。对于每个候选变更行，只执行第一个求值为真的子句。任何候选变更行都不会执行多个 \u003ccode\u003eWHEN\u003c/code\u003e子句。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eMERGE\u003c/code\u003e中的各个动作，与常规的 \u003ccode\u003eUPDATE\u003c/code\u003e、\u003ccode\u003eINSERT\u003c/code\u003e或 \u003ccode\u003eDELETE\u003c/code\u003e同名命令具有相同效果。不过这些动作的语法有所不同，尤其是没有\u003ccode\u003eWHERE\u003c/code\u003e子句，也不指定表名。所有动作都针对目标表，不过也可以借助触发器修改其他表。\u003c/p\u003e\u003cp\u003e当指定\u003ccode\u003eDO NOTHING\u003c/code\u003e时，源行会被跳过。由于动作会按其指定顺序求值，\u003ccode\u003eDO NOTHING\u003c/code\u003e有助于在进行更细粒度处理之前跳过不需要关注的源行。\u003c/p\u003e\u003cp\u003e可选的\u003ccode\u003eRETURNING\u003c/code\u003e子句会让\u003ccode\u003eMERGE\u003c/code\u003e 针对每个被插入、更新或删除的行计算并返回值。可以计算任何使用源表或目标表列的表达式，也可以调用\u003ca href=\"/docs/18/functions-merge-support.html#MERGE-ACTION\" rel=\"nofollow\"\u003e\u003ccode\u003emerge_action()\u003c/code\u003e\u003c/a\u003e函数。默认情况下，执行\u003ccode\u003eINSERT\u003c/code\u003e或\u003ccode\u003eUPDATE\u003c/code\u003e动作时，使用目标表各列的新值；执行\u003ccode\u003eDELETE\u003c/code\u003e动作时，使用目标表各列的旧值，但也可以显式请求旧值和新值。\u003ccode\u003eRETURNING\u003c/code\u003e列表的语法与 \u003ccode\u003eSELECT\u003c/code\u003e的输出列表完全相同。\u003c/p\u003e\u003cp\u003e没有单独的\u003ccode\u003eMERGE\u003c/code\u003e权限。如果指定更新动作，则必须对目标表中\u003ccode\u003eSET\u003c/code\u003e子句所引用的列具有\u003ccode\u003eUPDATE\u003c/code\u003e权限。如果指定插入动作，则必须对目标表具有\u003ccode\u003eINSERT\u003c/code\u003e权限。如果指定删除动作，则必须对目标表具有\u003ccode\u003eDELETE\u003c/code\u003e权限。如果指定\u003ccode\u003eDO NOTHING\u003c/code\u003e动作，则必须对目标表中至少一列具有\u003ccode\u003eSELECT\u003c/code\u003e权限。对于\u003cem\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e以及目标表中在任何 \u003ccode\u003econdition\u003c/code\u003e（包括\u003ccode\u003ejoin_condition\u003c/code\u003e）或 \u003ccode\u003eexpression\u003c/code\u003e中引用的列，你还必须具有\u003ccode\u003eSELECT\u003c/code\u003e权限。权限只会在语句开始时测试一次，而且无论特定的\u003ccode\u003eWHEN\u003c/code\u003e子句是否执行，都会进行检查。\u003c/p\u003e\u003cp\u003e如果目标表是物化视图、外部表，或者其上定义了任何规则，则不支持\u003ccode\u003eMERGE\u003c/code\u003e。\u003c/p\u003e\u003c/section\u003e\u003csection\u003e\u003ch2\u003e参数\u003c/h2\u003e\u003cdiv\u003e\u003cdl\u003e\u003cdt\u003e\u003cspan\u003e\u003cem\u003e\u003ccode\u003ewith_query\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e\u003ccode\u003eWITH\u003c/code\u003e子句允许你指定一个或多个子查询，以便在\u003ccode\u003eMERGE\u003c/code\u003e查询中按名称引用它们。有关细节请参见\u003ca href=\"/docs/18/queries-with.html\" rel=\"nofollow\"\u003e第 7.8 节\u003c/a\u003e和\u003ca href=\"/docs/18/sql-select.html\" title=\"SELECT\" rel=\"nofollow\"\u003e\u003cspan\u003eSELECT\u003c/span\u003e\u003c/a\u003e。请注意，\u003ccode\u003eMERGE\u003c/code\u003e不支持\u003ccode\u003eWITH RECURSIVE\u003c/code\u003e。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003cem\u003e\u003ccode\u003etarget_table_name\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e要合并到其中的目标表或视图名称（可选模式限定）。如果在表名前指定\u003ccode\u003eONLY\u003c/code\u003e，则匹配行只会在该命名表中被更新或删除。如果未指定\u003ccode\u003eONLY\u003c/code\u003e，则匹配行还会在继承自该命名表的任何表中被更新或删除。也可以在表名后指定\u003ccode\u003e*\u003c/code\u003e，以显式表明包含后代表。\u003ccode\u003eONLY\u003c/code\u003e关键字和\u003ccode\u003e*\u003c/code\u003e选项不会影响插入动作，因为插入动作始终只会插入到该命名表中。\u003c/p\u003e\u003cp\u003e如果\u003cem\u003e\u003ccode\u003etarget_table_name\u003c/code\u003e\u003c/em\u003e是一个视图，它必须要么是没有\u003ccode\u003eINSTEAD OF\u003c/code\u003e触发器的自动可更新视图，要么为\u003ccode\u003eWHEN\u003c/code\u003e子句中指定的每一种动作类型（\u003ccode\u003eINSERT\u003c/code\u003e、\u003ccode\u003eUPDATE\u003c/code\u003e和\u003ccode\u003eDELETE\u003c/code\u003e）都定义了\u003ccode\u003eINSTEAD OF\u003c/code\u003e触发器。不支持带有规则的视图。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003cem\u003e\u003ccode\u003etarget_alias\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e目标表的替代名称。提供别名后，它会完全隐藏表的实际名称。例如，给定\u003ccode\u003eMERGE INTO foo AS f\u003c/code\u003e，则\u003ccode\u003eMERGE\u003c/code\u003e语句的其余部分必须将该表称为\u003ccode\u003ef\u003c/code\u003e，而不是\u003ccode\u003efoo\u003c/code\u003e。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003cem\u003e\u003ccode\u003esource_table_name\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e源表、视图或过渡表的名称（可选模式限定）。如果在表名前指定\u003ccode\u003eONLY\u003c/code\u003e，则只包含来自该命名表的匹配行。如果未指定\u003ccode\u003eONLY\u003c/code\u003e，则还会包含来自继承自该命名表的任何表的匹配行。也可以在表名后指定\u003ccode\u003e*\u003c/code\u003e，以显式表明包含后代表。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003cem\u003e\u003ccode\u003esource_query\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e一个查询（\u003ccode\u003eSELECT\u003c/code\u003e语句或\u003ccode\u003eVALUES\u003c/code\u003e语句），用于提供要合并到目标表中的行。其语法说明请参见\u003ca href=\"/docs/18/sql-select.html\" title=\"SELECT\" rel=\"nofollow\"\u003e\u003cspan\u003eSELECT\u003c/span\u003e\u003c/a\u003e语句或\u003ca href=\"/docs/18/sql-values.html\" title=\"VALUES\" rel=\"nofollow\"\u003e\u003cspan\u003eVALUES\u003c/span\u003e\u003c/a\u003e语句。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003cem\u003e\u003ccode\u003esource_alias\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e数据源的替代名称。提供别名后，它会完全隐藏表的实际名称，或者隐藏此处实际使用的是一个查询这一事实。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003cem\u003e\u003ccode\u003ejoin_condition\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e\u003cem\u003e\u003ccode\u003ejoin_condition\u003c/code\u003e\u003c/em\u003e是一个返回 \u003ccode\u003eboolean\u003c/code\u003e类型值的表达式（类似于\u003ccode\u003eWHERE\u003c/code\u003e子句），用于指定\u003cem\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e中的哪些行与目标表中的行匹配。\u003c/p\u003e\u003cdiv\u003e\u003ch3\u003e警告\u003c/h3\u003e\u003cp\u003e只有那些用于尝试将\u003cem\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e行与目标表行匹配的目标表列，才应出现在\u003cem\u003e\u003ccode\u003ejoin_condition\u003c/code\u003e\u003c/em\u003e中。只引用目标表列的\u003cem\u003e\u003ccode\u003ejoin_condition\u003c/code\u003e\u003c/em\u003e子表达式可能影响所采取的动作，而且常常会令人意外。\u003c/p\u003e\u003cp\u003e如果同时指定了\u003ccode\u003eWHEN NOT MATCHED BY SOURCE\u003c/code\u003e和 \u003ccode\u003eWHEN NOT MATCHED [BY TARGET]\u003c/code\u003e子句，\u003ccode\u003eMERGE\u003c/code\u003e命令将对\u003cem\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e 与目标表执行\u003ccode\u003eFULL\u003c/code\u003e连接。要做到这一点，至少有一个\u003cem\u003e\u003ccode\u003ejoin_condition\u003c/code\u003e\u003c/em\u003e子表达式必须使用可支持哈希连接的操作符，或者所有子表达式都必须使用可支持归并连接的操作符。\u003c/p\u003e\u003c/div\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003cem\u003e\u003ccode\u003ewhen_clause\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e至少需要一个\u003ccode\u003eWHEN\u003c/code\u003e子句。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eWHEN\u003c/code\u003e子句可以指定\u003ccode\u003eWHEN MATCHED\u003c/code\u003e、\u003ccode\u003eWHEN NOT MATCHED BY SOURCE\u003c/code\u003e或 \u003ccode\u003eWHEN NOT MATCHED [BY TARGET]\u003c/code\u003e。请注意，\u003cacronym\u003eSQL\u003c/acronym\u003e标准只定义了\u003ccode\u003eWHEN MATCHED\u003c/code\u003e和 \u003ccode\u003eWHEN NOT MATCHED\u003c/code\u003e（后者定义为没有匹配的目标行）。\u003ccode\u003eWHEN NOT MATCHED BY SOURCE\u003c/code\u003e是对\u003cacronym\u003eSQL\u003c/acronym\u003e标准的扩展，而给\u003ccode\u003eWHEN NOT MATCHED\u003c/code\u003e追加\u003ccode\u003eBY TARGET\u003c/code\u003e选项也是扩展，用以使其含义更加明确。\u003c/p\u003e\u003cp\u003e如果\u003ccode\u003eWHEN\u003c/code\u003e子句指定了\u003ccode\u003eWHEN MATCHED\u003c/code\u003e，并且候选变更行表示\u003cem\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e中的一行与目标表中的一行相匹配，那么如果 \u003cem\u003e\u003ccode\u003econdition\u003c/code\u003e\u003c/em\u003e未指定，或其求值结果为\u003ccode\u003etrue\u003c/code\u003e，就会执行该\u003ccode\u003eWHEN\u003c/code\u003e子句。\u003c/p\u003e\u003cp\u003e如果\u003ccode\u003eWHEN\u003c/code\u003e子句指定了\u003ccode\u003eWHEN NOT MATCHED BY SOURCE\u003c/code\u003e，并且候选变更行表示目标表中的某一行与 \u003cem\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e中的任何行都不匹配，那么如果\u003cem\u003e\u003ccode\u003econdition\u003c/code\u003e\u003c/em\u003e未指定，或其求值结果为\u003ccode\u003etrue\u003c/code\u003e，就会执行该\u003ccode\u003eWHEN\u003c/code\u003e子句。\u003c/p\u003e\u003cp\u003e如果\u003ccode\u003eWHEN\u003c/code\u003e子句指定了\u003ccode\u003eWHEN NOT MATCHED [BY TARGET]\u003c/code\u003e，并且候选变更行表示\u003cem\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e中的某一行与目标表中的任何行都不匹配，那么如果 \u003cem\u003e\u003ccode\u003econdition\u003c/code\u003e\u003c/em\u003e未指定，或其求值结果为\u003ccode\u003etrue\u003c/code\u003e，就会执行该\u003ccode\u003eWHEN\u003c/code\u003e子句。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003cem\u003e\u003ccode\u003econdition\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e一个返回\u003ccode\u003eboolean\u003c/code\u003e类型值的表达式。如果某个\u003ccode\u003eWHEN\u003c/code\u003e子句中的这个表达式返回\u003ccode\u003etrue\u003c/code\u003e，则会对该行执行该子句对应的动作。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eWHEN MATCHED\u003c/code\u003e子句上的条件可以引用源关系和目标关系中的列。\u003ccode\u003eWHEN NOT MATCHED BY SOURCE\u003c/code\u003e子句上的条件只能引用目标关系中的列，因为按定义不存在匹配的源行。\u003ccode\u003eWHEN NOT MATCHED [BY TARGET]\u003c/code\u003e子句上的条件只能引用源关系中的列，因为按定义不存在匹配的目标行。只能访问目标表的系统属性。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003cem\u003e\u003ccode\u003emerge_insert\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e用于向目标表插入一行的\u003ccode\u003eINSERT\u003c/code\u003e动作规范。目标列名可以按任意顺序列出。如果根本没有给出列名列表，则默认为按声明顺序使用该表的所有列。\u003c/p\u003e\u003cp\u003e任何未出现在显式或隐式列列表中的列都会填入默认值；如果没有声明默认值，则填入空值。\u003c/p\u003e\u003cp\u003e如果目标表是分区表，则每一行都会被路由到适当的分区并插入其中。如果目标表本身是一个分区，而任何输入行违反了分区约束，就会报错。\u003c/p\u003e\u003cp\u003e列名不得指定多次。\u003ccode\u003eINSERT\u003c/code\u003e动作不能包含子查询。\u003c/p\u003e\u003cp\u003e只能指定一个\u003ccode\u003eVALUES\u003c/code\u003e子句。\u003ccode\u003eVALUES\u003c/code\u003e子句只能引用源关系中的列，因为按定义不存在匹配的目标行。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003cem\u003e\u003ccode\u003emerge_update\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e用于更新目标表当前行的\u003ccode\u003eUPDATE\u003c/code\u003e动作规范。列名不得指定多次。\u003c/p\u003e\u003cp\u003e既不允许表名，也不允许\u003ccode\u003eWHERE\u003c/code\u003e子句。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003cem\u003e\u003ccode\u003emerge_delete\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e指定一个\u003ccode\u003eDELETE\u003c/code\u003e动作，用于删除目标表的当前行。不要像通常编写\u003ca href=\"/docs/18/sql-delete.html\" title=\"DELETE\" rel=\"nofollow\"\u003e\u003cspan\u003eDELETE\u003c/span\u003e\u003c/a\u003e命令那样包含表名或其他子句。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003cem\u003e\u003ccode\u003ecolumn_name\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e目标表中某一列的名称。如有需要，列名可以使用子字段名或数组下标进行限定。（只向复合列的部分字段插入值会使其余字段为\u003ccode\u003eNULL\u003c/code\u003e。）在指定目标列时不要包含表名。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003ccode\u003eOVERRIDING SYSTEM VALUE\u003c/code\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e如果没有这个子句，那么为定义为\u003ccode\u003eGENERATED ALWAYS\u003c/code\u003e的标识列指定显式值（除\u003ccode\u003eDEFAULT\u003c/code\u003e外）会报错。这个子句会覆盖该限制。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003ccode\u003eOVERRIDING USER VALUE\u003c/code\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e如果指定了此子句，则会忽略为定义为\u003ccode\u003eGENERATED BY DEFAULT\u003c/code\u003e的标识列提供的任何值，并应用默认的序列生成值。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003ccode\u003eDEFAULT VALUES\u003c/code\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e所有列都会填入各自的默认值。（这种形式不允许出现\u003ccode\u003eOVERRIDING\u003c/code\u003e子句。）\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003cem\u003e\u003ccode\u003eexpression\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e赋给该列的表达式。如果用于\u003ccode\u003eWHEN MATCHED\u003c/code\u003e子句，该表达式可以使用目标表中原始行的值以及 \u003cem\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e行的值。如果用于\u003ccode\u003eWHEN NOT MATCHED BY SOURCE\u003c/code\u003e子句，该表达式只能使用目标表中原始行的值。如果用于\u003ccode\u003eWHEN NOT MATCHED [BY TARGET]\u003c/code\u003e子句，该表达式只能使用\u003cem\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e行的值。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003ccode\u003eDEFAULT\u003c/code\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e将该列设为其默认值（如果没有为其指定特定的默认表达式，则为\u003ccode\u003eNULL\u003c/code\u003e）。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003cem\u003e\u003ccode\u003esub-SELECT\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e一个\u003ccode\u003eSELECT\u003c/code\u003e子查询，其输出列数必须与它前面的括号列列表中列出的数量相同。执行时，该子查询最多只能产生一行。如果产生一行，其列值会赋给目标列；如果不产生任何行，则向目标列赋\u003ccode\u003eNULL\u003c/code\u003e值。如果用于\u003ccode\u003eWHEN MATCHED\u003c/code\u003e子句，子查询可以引用目标表中原始行的值，以及\u003cem\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e行的值。如果用于\u003ccode\u003eWHEN NOT MATCHED BY SOURCE\u003c/code\u003e子句，子查询只能引用目标表中原始行的值。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003cem\u003e\u003ccode\u003eoutput_alias\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e在\u003ccode\u003eRETURNING\u003c/code\u003e列表中为\u003ccode\u003eOLD\u003c/code\u003e或 \u003ccode\u003eNEW\u003c/code\u003e行指定的可选替代名称。\u003c/p\u003e\u003cp\u003e默认情况下，可通过 \u003ccode\u003eOLD.\u003cem\u003e\u003ccode\u003ecolumn_name\u003c/code\u003e\u003c/em\u003e\u003c/code\u003e 或\u003ccode\u003eOLD.*\u003c/code\u003e返回目标表旧值，通过 \u003ccode\u003eNEW.\u003cem\u003e\u003ccode\u003ecolumn_name\u003c/code\u003e\u003c/em\u003e\u003c/code\u003e 或\u003ccode\u003eNEW.*\u003c/code\u003e返回新值。提供别名后，这些名称会被隐藏，必须使用别名来引用旧行或新行。例如 \u003ccode\u003eRETURNING WITH (OLD AS o, NEW AS n) o.*, n.*\u003c/code\u003e。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003cem\u003e\u003ccode\u003eoutput_expression\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e由\u003ccode\u003eMERGE\u003c/code\u003e命令在每一行发生变化后（无论是插入、更新还是删除）计算并返回的表达式。该表达式可以使用源表或目标表的任意列，也可以使用 \u003ca href=\"/docs/18/functions-merge-support.html#MERGE-ACTION\" rel=\"nofollow\"\u003e\u003ccode\u003emerge_action()\u003c/code\u003e\u003c/a\u003e函数返回关于已执行动作的附加信息。\u003c/p\u003e\u003cp\u003e写成\u003ccode\u003e*\u003c/code\u003e将返回源表的全部列，然后返回目标表的全部列。这往往会导致大量重复，因为源表和目标表通常有很多相同的列。可以通过使用源表或目标表的名称或别名限定\u003ccode\u003e*\u003c/code\u003e来避免这一点。\u003c/p\u003e\u003cp\u003e列名或\u003ccode\u003e*\u003c/code\u003e也可以用\u003ccode\u003eOLD\u003c/code\u003e或\u003ccode\u003eNEW\u003c/code\u003e，或者用\u003ccode\u003eOLD\u003c/code\u003e或\u003ccode\u003eNEW\u003c/code\u003e对应的\u003cem\u003e\u003ccode\u003eoutput_alias\u003c/code\u003e\u003c/em\u003e来限定，以返回目标表中的旧值或新值。来自目标表的未限定列名，或者使用目标表名或别名限定的列名或 \u003ccode\u003e*\u003c/code\u003e，会在\u003ccode\u003eINSERT\u003c/code\u003e和\u003ccode\u003eUPDATE\u003c/code\u003e动作中返回新值，在\u003ccode\u003eDELETE\u003c/code\u003e动作中返回旧值。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan\u003e\u003cem\u003e\u003ccode\u003eoutput_name\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e用于返回列的名称。\u003c/p\u003e\u003c/dd\u003e\u003c/dl\u003e\u003c/div\u003e\u003c/section\u003e\u003csection\u003e\u003ch2\u003e输出\u003c/h2\u003e\u003cp\u003e成功完成时，\u003ccode\u003eMERGE\u003c/code\u003e命令返回如下形式的命令标签：\u003c/p\u003e\u003cpre\u003eMERGE \u003cem\u003e\u003ccode\u003etotal_count\u003c/code\u003e\u003c/em\u003e\n\u003c/pre\u003e\u003cp\u003e\u003cem\u003e\u003ccode\u003etotal_count\u003c/code\u003e\u003c/em\u003e是发生变化的总行数（无论是插入、更新还是删除）。如果\u003cem\u003e\u003ccode\u003etotal_count\u003c/code\u003e\u003c/em\u003e为 0，则没有任何行以任何方式发生变化。\u003c/p\u003e\u003cp\u003e如果\u003ccode\u003eMERGE\u003c/code\u003e命令包含\u003ccode\u003eRETURNING\u003c/code\u003e子句，则其结果将类似于一条\u003ccode\u003eSELECT\u003c/code\u003e语句，包含\u003ccode\u003eRETURNING\u003c/code\u003e列表中定义的列和值，这些值是针对该命令插入、更新或删除的行计算得到的。\u003c/p\u003e\u003c/section\u003e\u003csection\u003e\u003ch2\u003e注解\u003c/h2\u003e\u003cp\u003e在执行\u003ccode\u003eMERGE\u003c/code\u003e期间会发生以下步骤：\u003c/p\u003e\u003cdiv\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e对所有已指定的动作执行任何\u003ccode\u003eBEFORE STATEMENT\u003c/code\u003e触发器，无论其\u003ccode\u003eWHEN\u003c/code\u003e子句是否匹配。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e执行从源到目标表的连接。生成的查询会按常规方式优化，并产生一组候选变更行。对于每个候选变更行，\u003c/p\u003e\u003cdiv\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e判定该行是\u003ccode\u003eMATCHED\u003c/code\u003e、\u003ccode\u003eNOT MATCHED BY SOURCE\u003c/code\u003e还是 \u003ccode\u003eNOT MATCHED [BY TARGET]\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e按指定顺序测试每个\u003ccode\u003eWHEN\u003c/code\u003e条件，直到有一个返回\u003ccode\u003etrue\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e当某个条件返回\u003ccode\u003etrue\u003c/code\u003e时，执行以下动作：\u003c/p\u003e\u003cdiv\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e执行为该动作事件类型触发的任何\u003ccode\u003eBEFORE ROW\u003c/code\u003e触发器。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e执行指定的动作，并对目标表应用任何检查约束。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e执行为该动作事件类型触发的任何\u003ccode\u003eAFTER ROW\u003c/code\u003e触发器。\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003c/div\u003e\u003cp\u003e如果目标关系是一个视图，并且为该动作的事件类型定义了 \u003ccode\u003eINSTEAD OF ROW\u003c/code\u003e触发器，则改由这些触发器执行该动作。\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003c/div\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e对已指定的动作执行任何\u003ccode\u003eAFTER STATEMENT\u003c/code\u003e触发器，无论这些动作是否实际发生。这类似于一条未修改任何行的 \u003ccode\u003eUPDATE\u003c/code\u003e语句的行为。\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003c/div\u003e\u003cp\u003e总之，只要我们\u003cspan\u003e\u003cem\u003e指定\u003c/em\u003e\u003c/span\u003e了某种动作，对应事件类型（例如\u003ccode\u003eINSERT\u003c/code\u003e）的语句级触发器就会被触发。相反，行级触发器只会针对实际被\u003cspan\u003e\u003cem\u003e执行\u003c/em\u003e\u003c/span\u003e的特定事件类型触发。因此，一条\u003ccode\u003eMERGE\u003c/code\u003e命令可能同时触发 \u003ccode\u003eUPDATE\u003c/code\u003e和\u003ccode\u003eINSERT\u003c/code\u003e的语句级触发器，即使实际上只触发了\u003ccode\u003eUPDATE\u003c/code\u003e的行级触发器。\u003c/p\u003e\u003cp\u003e你应确保该连接对每个目标行最多只生成一个候选变更行。换句话说，一个目标行不应连接到多于一个数据源行。如果发生这种情况，则只会使用其中一个候选变更行来修改目标行；随后再次尝试修改该行会导致错误。如果行级触发器对目标表进行了修改，而随后这些已被修改的行又被 \u003ccode\u003eMERGE\u003c/code\u003e再次修改，也可能发生这种情况。如果重复的动作是\u003ccode\u003eINSERT\u003c/code\u003e，则会导致唯一性违例错误；而重复的\u003ccode\u003eUPDATE\u003c/code\u003e或\u003ccode\u003eDELETE\u003c/code\u003e则会导致基数违规；后者是\u003cacronym\u003eSQL\u003c/acronym\u003e标准要求的行为。这不同于\u003cspan\u003ePostgreSQL\u003c/span\u003e历史上在 \u003ccode\u003eUPDATE\u003c/code\u003e和\u003ccode\u003eDELETE\u003c/code\u003e语句中处理连接的行为：对同一行的第二次及后续修改尝试会被直接忽略。\u003c/p\u003e\u003cp\u003e如果某个\u003ccode\u003eWHEN\u003c/code\u003e子句省略了\u003ccode\u003eAND\u003c/code\u003e子句，它就会成为该类型（\u003ccode\u003eMATCHED\u003c/code\u003e、\u003ccode\u003eNOT MATCHED BY SOURCE\u003c/code\u003e或 \u003ccode\u003eNOT MATCHED [BY TARGET]\u003c/code\u003e）最后一个可达的子句。如果之后又指定了同一类型的\u003ccode\u003eWHEN\u003c/code\u003e子句，则可证明它不可达，并会引发错误。如果这三类中都没有指定最后一个可达子句，则候选变更行可能不会执行任何动作。\u003c/p\u003e\u003cp\u003e默认情况下，从数据源生成行的顺序是不确定的。如果需要，可以使用\u003cem\u003e\u003ccode\u003esource_query\u003c/code\u003e\u003c/em\u003e指定一致的排序，这可能有助于避免并发事务之间的死锁。\u003c/p\u003e\u003cp\u003e当\u003ccode\u003eMERGE\u003c/code\u003e与其他修改目标表的命令并发运行时，适用通常的事务隔离规则；请参见\u003ca href=\"/docs/18/transaction-iso.html\" rel=\"nofollow\"\u003e第 13.2 节\u003c/a\u003e，了解各个隔离级别下的行为说明。你也可以考虑使用\u003ccode\u003eINSERT ... ON CONFLICT\u003c/code\u003e作为替代语句，它提供了在发生并发\u003ccode\u003eINSERT\u003c/code\u003e时执行\u003ccode\u003eUPDATE\u003c/code\u003e的能力。这两种语句类型之间存在各种差异和限制，因此不能互换。\u003c/p\u003e\u003c/section\u003e\u003csection\u003e\u003ch2\u003e示例\u003c/h2\u003e\u003cp\u003e根据新的\u003ccode\u003erecent_transactions\u003c/code\u003e对 \u003ccode\u003ecustomer_account\u003c/code\u003e执行维护。\u003c/p\u003e\u003cpre\u003eMERGE INTO customer_account ca\nUSING recent_transactions t\nON t.customer_id = ca.customer_id\nWHEN MATCHED THEN\n  UPDATE SET balance = balance + transaction_value\nWHEN NOT MATCHED THEN\n  INSERT (customer_id, balance)\n  VALUES (t.customer_id, t.transaction_value);\n\u003c/pre\u003e\u003cp\u003e尝试插入一个新的库存项及其库存数量。如果该项已存在，则改为更新现有项的库存数量。不允许库存为零的条目。返回所有已发生更改的详细信息。\u003c/p\u003e\u003cpre\u003eMERGE INTO wines w\nUSING wine_stock_changes s\nON s.winename = w.winename\nWHEN NOT MATCHED AND s.stock_delta \u0026gt; 0 THEN\n  INSERT VALUES(s.winename, s.stock_delta)\nWHEN MATCHED AND w.stock + s.stock_delta \u0026gt; 0 THEN\n  UPDATE SET stock = w.stock + s.stock_delta\nWHEN MATCHED THEN\n  DELETE\nRETURNING merge_action(), w.winename, old.stock AS old_stock, new.stock AS new_stock;\n\u003c/pre\u003e\u003cp\u003e例如，\u003ccode\u003ewine_stock_changes\u003c/code\u003e表可能是一个刚装载到数据库中的临时表。\u003c/p\u003e\u003cp\u003e根据替换后的酒单更新\u003ccode\u003ewines\u003c/code\u003e：为任何新库存插入行，更新已修改的库存条目，并删除新列表中不存在的任何葡萄酒。\u003c/p\u003e\u003cpre\u003eMERGE INTO wines w\nUSING new_wine_list s\nON s.winename = w.winename\nWHEN NOT MATCHED BY TARGET THEN\n  INSERT VALUES(s.winename, s.stock)\nWHEN MATCHED AND w.stock != s.stock THEN\n  UPDATE SET stock = s.stock\nWHEN NOT MATCHED BY SOURCE THEN\n  DELETE;\n\u003c/pre\u003e\u003c/section\u003e\u003csection\u003e\u003ch2\u003e兼容性\u003c/h2\u003e\u003cp\u003e这个命令符合\u003cacronym\u003eSQL\u003c/acronym\u003e标准。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eWITH\u003c/code\u003e子句、\u003ccode\u003eWHEN NOT MATCHED\u003c/code\u003e上的 \u003ccode\u003eBY SOURCE\u003c/code\u003e和\u003ccode\u003eBY TARGET\u003c/code\u003e限定词、\u003ccode\u003eDO NOTHING\u003c/code\u003e动作以及\u003ccode\u003eRETURNING\u003c/code\u003e子句，都是对\u003cacronym\u003eSQL\u003c/acronym\u003e标准的扩展。\u003c/p\u003e\u003c/section\u003e","SourceRevision":"ca936764","ContentHash":"bf96546c01f8719117dc32df14c841b1ed1cc671be1c2a1f9fba97aa26ca3d83","Payload":{"purpose_zh":"有条件地插入、更新或删除表中的行","sections":[{"html":"\u003cp\u003e\u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e使用\u003cem class=\"replaceable\"\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e 对由\u003cem class=\"replaceable\"\u003e\u003ccode\u003etarget_table_name\u003c/code\u003e\u003c/em\u003e标识的目标表中的行执行修改动作。\u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e提供了一条单独的\u003cacronym\u003eSQL\u003c/acronym\u003e语句，可按条件对行执行\u003ccode class=\"command\"\u003eINSERT\u003c/code\u003e、\u003ccode class=\"command\"\u003eUPDATE\u003c/code\u003e或\u003ccode class=\"command\"\u003eDELETE\u003c/code\u003e；否则，这项工作需要多条过程语言语句。\u003c/p\u003e\u003cp\u003e首先，\u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e命令会将\u003cem class=\"replaceable\"\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e 与目标表执行连接，生成零个或多个候选变更行。对于每个候选变更行，系统只会确定一次其状态是\u003ccode class=\"literal\"\u003eMATCHED\u003c/code\u003e、\u003ccode class=\"literal\"\u003eNOT MATCHED BY SOURCE\u003c/code\u003e还是 \u003ccode class=\"literal\"\u003eNOT MATCHED [BY TARGET]\u003c/code\u003e，然后按指定顺序对 \u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e子句求值。对于每个候选变更行，只执行第一个求值为真的子句。任何候选变更行都不会执行多个 \u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e子句。\u003c/p\u003e\u003cp\u003e\u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e中的各个动作，与常规的 \u003ccode class=\"command\"\u003eUPDATE\u003c/code\u003e、\u003ccode class=\"command\"\u003eINSERT\u003c/code\u003e或 \u003ccode class=\"command\"\u003eDELETE\u003c/code\u003e同名命令具有相同效果。不过这些动作的语法有所不同，尤其是没有\u003ccode class=\"literal\"\u003eWHERE\u003c/code\u003e子句，也不指定表名。所有动作都针对目标表，不过也可以借助触发器修改其他表。\u003c/p\u003e\u003cp\u003e当指定\u003ccode class=\"literal\"\u003eDO NOTHING\u003c/code\u003e时，源行会被跳过。由于动作会按其指定顺序求值，\u003ccode class=\"literal\"\u003eDO NOTHING\u003c/code\u003e有助于在进行更细粒度处理之前跳过不需要关注的源行。\u003c/p\u003e\u003cp\u003e可选的\u003ccode class=\"literal\"\u003eRETURNING\u003c/code\u003e子句会让\u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e 针对每个被插入、更新或删除的行计算并返回值。可以计算任何使用源表或目标表列的表达式，也可以调用\u003ca href=\"/docs/18/functions-merge-support.html#MERGE-ACTION\"\u003e\u003ccode class=\"function\"\u003emerge_action()\u003c/code\u003e\u003c/a\u003e函数。默认情况下，执行\u003ccode class=\"command\"\u003eINSERT\u003c/code\u003e或\u003ccode class=\"command\"\u003eUPDATE\u003c/code\u003e动作时，使用目标表各列的新值；执行\u003ccode class=\"command\"\u003eDELETE\u003c/code\u003e动作时，使用目标表各列的旧值，但也可以显式请求旧值和新值。\u003ccode class=\"literal\"\u003eRETURNING\u003c/code\u003e列表的语法与 \u003ccode class=\"command\"\u003eSELECT\u003c/code\u003e的输出列表完全相同。\u003c/p\u003e\u003cp\u003e没有单独的\u003ccode class=\"literal\"\u003eMERGE\u003c/code\u003e权限。如果指定更新动作，则必须对目标表中\u003ccode class=\"literal\"\u003eSET\u003c/code\u003e子句所引用的列具有\u003ccode class=\"literal\"\u003eUPDATE\u003c/code\u003e权限。如果指定插入动作，则必须对目标表具有\u003ccode class=\"literal\"\u003eINSERT\u003c/code\u003e权限。如果指定删除动作，则必须对目标表具有\u003ccode class=\"literal\"\u003eDELETE\u003c/code\u003e权限。如果指定\u003ccode class=\"literal\"\u003eDO NOTHING\u003c/code\u003e动作，则必须对目标表中至少一列具有\u003ccode class=\"literal\"\u003eSELECT\u003c/code\u003e权限。对于\u003cem class=\"replaceable\"\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e以及目标表中在任何 \u003ccode class=\"literal\"\u003econdition\u003c/code\u003e（包括\u003ccode class=\"literal\"\u003ejoin_condition\u003c/code\u003e）或 \u003ccode class=\"literal\"\u003eexpression\u003c/code\u003e中引用的列，你还必须具有\u003ccode class=\"literal\"\u003eSELECT\u003c/code\u003e权限。权限只会在语句开始时测试一次，而且无论特定的\u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e子句是否执行，都会进行检查。\u003c/p\u003e\u003cp\u003e如果目标表是物化视图、外部表，或者其上定义了任何规则，则不支持\u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e。\u003c/p\u003e","key":"description","title":"描述"},{"html":"\u003cdiv class=\"variablelist\"\u003e\u003cdl class=\"variablelist\"\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003ewith_query\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e\u003ccode class=\"literal\"\u003eWITH\u003c/code\u003e子句允许你指定一个或多个子查询，以便在\u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e查询中按名称引用它们。有关细节请参见\u003ca href=\"/docs/18/queries-with.html\" title=\"7.8. WITH查询（公共表表达式）\"\u003e第 7.8 节\u003c/a\u003e和\u003ca href=\"/docs/18/sql-select.html\" title=\"SELECT\"\u003e\u003cspan class=\"refentrytitle\"\u003eSELECT\u003c/span\u003e\u003c/a\u003e。请注意，\u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e不支持\u003ccode class=\"literal\"\u003eWITH RECURSIVE\u003c/code\u003e。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003etarget_table_name\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e要合并到其中的目标表或视图名称（可选模式限定）。如果在表名前指定\u003ccode class=\"literal\"\u003eONLY\u003c/code\u003e，则匹配行只会在该命名表中被更新或删除。如果未指定\u003ccode class=\"literal\"\u003eONLY\u003c/code\u003e，则匹配行还会在继承自该命名表的任何表中被更新或删除。也可以在表名后指定\u003ccode class=\"literal\"\u003e*\u003c/code\u003e，以显式表明包含后代表。\u003ccode class=\"literal\"\u003eONLY\u003c/code\u003e关键字和\u003ccode class=\"literal\"\u003e*\u003c/code\u003e选项不会影响插入动作，因为插入动作始终只会插入到该命名表中。\u003c/p\u003e\u003cp\u003e如果\u003cem class=\"replaceable\"\u003e\u003ccode\u003etarget_table_name\u003c/code\u003e\u003c/em\u003e是一个视图，它必须要么是没有\u003ccode class=\"literal\"\u003eINSTEAD OF\u003c/code\u003e触发器的自动可更新视图，要么为\u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e子句中指定的每一种动作类型（\u003ccode class=\"literal\"\u003eINSERT\u003c/code\u003e、\u003ccode class=\"literal\"\u003eUPDATE\u003c/code\u003e和\u003ccode class=\"literal\"\u003eDELETE\u003c/code\u003e）都定义了\u003ccode class=\"literal\"\u003eINSTEAD OF\u003c/code\u003e触发器。不支持带有规则的视图。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003etarget_alias\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e目标表的替代名称。提供别名后，它会完全隐藏表的实际名称。例如，给定\u003ccode class=\"literal\"\u003eMERGE INTO foo AS f\u003c/code\u003e，则\u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e语句的其余部分必须将该表称为\u003ccode class=\"literal\"\u003ef\u003c/code\u003e，而不是\u003ccode class=\"literal\"\u003efoo\u003c/code\u003e。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003esource_table_name\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e源表、视图或过渡表的名称（可选模式限定）。如果在表名前指定\u003ccode class=\"literal\"\u003eONLY\u003c/code\u003e，则只包含来自该命名表的匹配行。如果未指定\u003ccode class=\"literal\"\u003eONLY\u003c/code\u003e，则还会包含来自继承自该命名表的任何表的匹配行。也可以在表名后指定\u003ccode class=\"literal\"\u003e*\u003c/code\u003e，以显式表明包含后代表。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003esource_query\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e一个查询（\u003ccode class=\"command\"\u003eSELECT\u003c/code\u003e语句或\u003ccode class=\"command\"\u003eVALUES\u003c/code\u003e语句），用于提供要合并到目标表中的行。其语法说明请参见\u003ca href=\"/docs/18/sql-select.html\" title=\"SELECT\"\u003e\u003cspan class=\"refentrytitle\"\u003eSELECT\u003c/span\u003e\u003c/a\u003e语句或\u003ca href=\"/docs/18/sql-values.html\" title=\"VALUES\"\u003e\u003cspan class=\"refentrytitle\"\u003eVALUES\u003c/span\u003e\u003c/a\u003e语句。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003esource_alias\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e数据源的替代名称。提供别名后，它会完全隐藏表的实际名称，或者隐藏此处实际使用的是一个查询这一事实。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003ejoin_condition\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003ejoin_condition\u003c/code\u003e\u003c/em\u003e是一个返回 \u003ccode class=\"type\"\u003eboolean\u003c/code\u003e类型值的表达式（类似于\u003ccode class=\"literal\"\u003eWHERE\u003c/code\u003e子句），用于指定\u003cem class=\"replaceable\"\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e中的哪些行与目标表中的行匹配。\u003c/p\u003e\u003cdiv class=\"warning\"\u003e\u003ch3\u003e警告\u003c/h3\u003e\u003cp\u003e只有那些用于尝试将\u003cem class=\"replaceable\"\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e行与目标表行匹配的目标表列，才应出现在\u003cem class=\"replaceable\"\u003e\u003ccode\u003ejoin_condition\u003c/code\u003e\u003c/em\u003e中。只引用目标表列的\u003cem class=\"replaceable\"\u003e\u003ccode\u003ejoin_condition\u003c/code\u003e\u003c/em\u003e子表达式可能影响所采取的动作，而且常常会令人意外。\u003c/p\u003e\u003cp\u003e如果同时指定了\u003ccode class=\"literal\"\u003eWHEN NOT MATCHED BY SOURCE\u003c/code\u003e和 \u003ccode class=\"literal\"\u003eWHEN NOT MATCHED [BY TARGET]\u003c/code\u003e子句，\u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e命令将对\u003cem class=\"replaceable\"\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e 与目标表执行\u003ccode class=\"literal\"\u003eFULL\u003c/code\u003e连接。要做到这一点，至少有一个\u003cem class=\"replaceable\"\u003e\u003ccode\u003ejoin_condition\u003c/code\u003e\u003c/em\u003e子表达式必须使用可支持哈希连接的操作符，或者所有子表达式都必须使用可支持归并连接的操作符。\u003c/p\u003e\u003c/div\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003ewhen_clause\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e至少需要一个\u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e子句。\u003c/p\u003e\u003cp\u003e\u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e子句可以指定\u003ccode class=\"literal\"\u003eWHEN MATCHED\u003c/code\u003e、\u003ccode class=\"literal\"\u003eWHEN NOT MATCHED BY SOURCE\u003c/code\u003e或 \u003ccode class=\"literal\"\u003eWHEN NOT MATCHED [BY TARGET]\u003c/code\u003e。请注意，\u003cacronym\u003eSQL\u003c/acronym\u003e标准只定义了\u003ccode class=\"literal\"\u003eWHEN MATCHED\u003c/code\u003e和 \u003ccode class=\"literal\"\u003eWHEN NOT MATCHED\u003c/code\u003e（后者定义为没有匹配的目标行）。\u003ccode class=\"literal\"\u003eWHEN NOT MATCHED BY SOURCE\u003c/code\u003e是对\u003cacronym\u003eSQL\u003c/acronym\u003e标准的扩展，而给\u003ccode class=\"literal\"\u003eWHEN NOT MATCHED\u003c/code\u003e追加\u003ccode class=\"literal\"\u003eBY TARGET\u003c/code\u003e选项也是扩展，用以使其含义更加明确。\u003c/p\u003e\u003cp\u003e如果\u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e子句指定了\u003ccode class=\"literal\"\u003eWHEN MATCHED\u003c/code\u003e，并且候选变更行表示\u003cem class=\"replaceable\"\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e中的一行与目标表中的一行相匹配，那么如果 \u003cem class=\"replaceable\"\u003e\u003ccode\u003econdition\u003c/code\u003e\u003c/em\u003e未指定，或其求值结果为\u003ccode class=\"literal\"\u003etrue\u003c/code\u003e，就会执行该\u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e子句。\u003c/p\u003e\u003cp\u003e如果\u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e子句指定了\u003ccode class=\"literal\"\u003eWHEN NOT MATCHED BY SOURCE\u003c/code\u003e，并且候选变更行表示目标表中的某一行与 \u003cem class=\"replaceable\"\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e中的任何行都不匹配，那么如果\u003cem class=\"replaceable\"\u003e\u003ccode\u003econdition\u003c/code\u003e\u003c/em\u003e未指定，或其求值结果为\u003ccode class=\"literal\"\u003etrue\u003c/code\u003e，就会执行该\u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e子句。\u003c/p\u003e\u003cp\u003e如果\u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e子句指定了\u003ccode class=\"literal\"\u003eWHEN NOT MATCHED [BY TARGET]\u003c/code\u003e，并且候选变更行表示\u003cem class=\"replaceable\"\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e中的某一行与目标表中的任何行都不匹配，那么如果 \u003cem class=\"replaceable\"\u003e\u003ccode\u003econdition\u003c/code\u003e\u003c/em\u003e未指定，或其求值结果为\u003ccode class=\"literal\"\u003etrue\u003c/code\u003e，就会执行该\u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e子句。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003econdition\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e一个返回\u003ccode class=\"type\"\u003eboolean\u003c/code\u003e类型值的表达式。如果某个\u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e子句中的这个表达式返回\u003ccode class=\"literal\"\u003etrue\u003c/code\u003e，则会对该行执行该子句对应的动作。\u003c/p\u003e\u003cp\u003e\u003ccode class=\"literal\"\u003eWHEN MATCHED\u003c/code\u003e子句上的条件可以引用源关系和目标关系中的列。\u003ccode class=\"literal\"\u003eWHEN NOT MATCHED BY SOURCE\u003c/code\u003e子句上的条件只能引用目标关系中的列，因为按定义不存在匹配的源行。\u003ccode class=\"literal\"\u003eWHEN NOT MATCHED [BY TARGET]\u003c/code\u003e子句上的条件只能引用源关系中的列，因为按定义不存在匹配的目标行。只能访问目标表的系统属性。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003emerge_insert\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e用于向目标表插入一行的\u003ccode class=\"literal\"\u003eINSERT\u003c/code\u003e动作规范。目标列名可以按任意顺序列出。如果根本没有给出列名列表，则默认为按声明顺序使用该表的所有列。\u003c/p\u003e\u003cp\u003e任何未出现在显式或隐式列列表中的列都会填入默认值；如果没有声明默认值，则填入空值。\u003c/p\u003e\u003cp\u003e如果目标表是分区表，则每一行都会被路由到适当的分区并插入其中。如果目标表本身是一个分区，而任何输入行违反了分区约束，就会报错。\u003c/p\u003e\u003cp\u003e列名不得指定多次。\u003ccode class=\"command\"\u003eINSERT\u003c/code\u003e动作不能包含子查询。\u003c/p\u003e\u003cp\u003e只能指定一个\u003ccode class=\"literal\"\u003eVALUES\u003c/code\u003e子句。\u003ccode class=\"literal\"\u003eVALUES\u003c/code\u003e子句只能引用源关系中的列，因为按定义不存在匹配的目标行。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003emerge_update\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e用于更新目标表当前行的\u003ccode class=\"literal\"\u003eUPDATE\u003c/code\u003e动作规范。列名不得指定多次。\u003c/p\u003e\u003cp\u003e既不允许表名，也不允许\u003ccode class=\"literal\"\u003eWHERE\u003c/code\u003e子句。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003emerge_delete\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e指定一个\u003ccode class=\"literal\"\u003eDELETE\u003c/code\u003e动作，用于删除目标表的当前行。不要像通常编写\u003ca href=\"/docs/18/sql-delete.html\" title=\"DELETE\"\u003e\u003cspan class=\"refentrytitle\"\u003eDELETE\u003c/span\u003e\u003c/a\u003e命令那样包含表名或其他子句。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003ecolumn_name\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e目标表中某一列的名称。如有需要，列名可以使用子字段名或数组下标进行限定。（只向复合列的部分字段插入值会使其余字段为\u003ccode class=\"literal\"\u003eNULL\u003c/code\u003e。）在指定目标列时不要包含表名。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003ccode class=\"literal\"\u003eOVERRIDING SYSTEM VALUE\u003c/code\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e如果没有这个子句，那么为定义为\u003ccode class=\"literal\"\u003eGENERATED ALWAYS\u003c/code\u003e的标识列指定显式值（除\u003ccode class=\"literal\"\u003eDEFAULT\u003c/code\u003e外）会报错。这个子句会覆盖该限制。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003ccode class=\"literal\"\u003eOVERRIDING USER VALUE\u003c/code\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e如果指定了此子句，则会忽略为定义为\u003ccode class=\"literal\"\u003eGENERATED BY DEFAULT\u003c/code\u003e的标识列提供的任何值，并应用默认的序列生成值。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003ccode class=\"literal\"\u003eDEFAULT VALUES\u003c/code\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e所有列都会填入各自的默认值。（这种形式不允许出现\u003ccode class=\"literal\"\u003eOVERRIDING\u003c/code\u003e子句。）\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003eexpression\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e赋给该列的表达式。如果用于\u003ccode class=\"literal\"\u003eWHEN MATCHED\u003c/code\u003e子句，该表达式可以使用目标表中原始行的值以及 \u003cem class=\"replaceable\"\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e行的值。如果用于\u003ccode class=\"literal\"\u003eWHEN NOT MATCHED BY SOURCE\u003c/code\u003e子句，该表达式只能使用目标表中原始行的值。如果用于\u003ccode class=\"literal\"\u003eWHEN NOT MATCHED [BY TARGET]\u003c/code\u003e子句，该表达式只能使用\u003cem class=\"replaceable\"\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e行的值。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003ccode class=\"literal\"\u003eDEFAULT\u003c/code\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e将该列设为其默认值（如果没有为其指定特定的默认表达式，则为\u003ccode class=\"literal\"\u003eNULL\u003c/code\u003e）。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003esub-SELECT\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e一个\u003ccode class=\"literal\"\u003eSELECT\u003c/code\u003e子查询，其输出列数必须与它前面的括号列列表中列出的数量相同。执行时，该子查询最多只能产生一行。如果产生一行，其列值会赋给目标列；如果不产生任何行，则向目标列赋\u003ccode class=\"literal\"\u003eNULL\u003c/code\u003e值。如果用于\u003ccode class=\"literal\"\u003eWHEN MATCHED\u003c/code\u003e子句，子查询可以引用目标表中原始行的值，以及\u003cem class=\"replaceable\"\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e行的值。如果用于\u003ccode class=\"literal\"\u003eWHEN NOT MATCHED BY SOURCE\u003c/code\u003e子句，子查询只能引用目标表中原始行的值。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003eoutput_alias\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e在\u003ccode class=\"literal\"\u003eRETURNING\u003c/code\u003e列表中为\u003ccode class=\"literal\"\u003eOLD\u003c/code\u003e或 \u003ccode class=\"literal\"\u003eNEW\u003c/code\u003e行指定的可选替代名称。\u003c/p\u003e\u003cp\u003e默认情况下，可通过 \u003ccode class=\"literal\"\u003eOLD.\u003cem class=\"replaceable\"\u003e\u003ccode\u003ecolumn_name\u003c/code\u003e\u003c/em\u003e\u003c/code\u003e 或\u003ccode class=\"literal\"\u003eOLD.*\u003c/code\u003e返回目标表旧值，通过 \u003ccode class=\"literal\"\u003eNEW.\u003cem class=\"replaceable\"\u003e\u003ccode\u003ecolumn_name\u003c/code\u003e\u003c/em\u003e\u003c/code\u003e 或\u003ccode class=\"literal\"\u003eNEW.*\u003c/code\u003e返回新值。提供别名后，这些名称会被隐藏，必须使用别名来引用旧行或新行。例如 \u003ccode class=\"literal\"\u003eRETURNING WITH (OLD AS o, NEW AS n) o.*, n.*\u003c/code\u003e。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003eoutput_expression\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e由\u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e命令在每一行发生变化后（无论是插入、更新还是删除）计算并返回的表达式。该表达式可以使用源表或目标表的任意列，也可以使用 \u003ca href=\"/docs/18/functions-merge-support.html#MERGE-ACTION\"\u003e\u003ccode class=\"function\"\u003emerge_action()\u003c/code\u003e\u003c/a\u003e函数返回关于已执行动作的附加信息。\u003c/p\u003e\u003cp\u003e写成\u003ccode class=\"literal\"\u003e*\u003c/code\u003e将返回源表的全部列，然后返回目标表的全部列。这往往会导致大量重复，因为源表和目标表通常有很多相同的列。可以通过使用源表或目标表的名称或别名限定\u003ccode class=\"literal\"\u003e*\u003c/code\u003e来避免这一点。\u003c/p\u003e\u003cp\u003e列名或\u003ccode class=\"literal\"\u003e*\u003c/code\u003e也可以用\u003ccode class=\"literal\"\u003eOLD\u003c/code\u003e或\u003ccode class=\"literal\"\u003eNEW\u003c/code\u003e，或者用\u003ccode class=\"literal\"\u003eOLD\u003c/code\u003e或\u003ccode class=\"literal\"\u003eNEW\u003c/code\u003e对应的\u003cem class=\"replaceable\"\u003e\u003ccode\u003eoutput_alias\u003c/code\u003e\u003c/em\u003e来限定，以返回目标表中的旧值或新值。来自目标表的未限定列名，或者使用目标表名或别名限定的列名或 \u003ccode class=\"literal\"\u003e*\u003c/code\u003e，会在\u003ccode class=\"literal\"\u003eINSERT\u003c/code\u003e和\u003ccode class=\"literal\"\u003eUPDATE\u003c/code\u003e动作中返回新值，在\u003ccode class=\"literal\"\u003eDELETE\u003c/code\u003e动作中返回旧值。\u003c/p\u003e\u003c/dd\u003e\u003cdt\u003e\u003cspan class=\"term\"\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003eoutput_name\u003c/code\u003e\u003c/em\u003e\u003c/span\u003e\u003c/dt\u003e\u003cdd\u003e\u003cp\u003e用于返回列的名称。\u003c/p\u003e\u003c/dd\u003e\u003c/dl\u003e\u003c/div\u003e","key":"parameters","title":"参数"},{"html":"\u003cp\u003e成功完成时，\u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e命令返回如下形式的命令标签：\u003c/p\u003e\u003cpre class=\"screen\"\u003eMERGE \u003cem class=\"replaceable\"\u003e\u003ccode\u003etotal_count\u003c/code\u003e\u003c/em\u003e\n\u003c/pre\u003e\u003cp\u003e\u003cem class=\"replaceable\"\u003e\u003ccode\u003etotal_count\u003c/code\u003e\u003c/em\u003e是发生变化的总行数（无论是插入、更新还是删除）。如果\u003cem class=\"replaceable\"\u003e\u003ccode\u003etotal_count\u003c/code\u003e\u003c/em\u003e为 0，则没有任何行以任何方式发生变化。\u003c/p\u003e\u003cp\u003e如果\u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e命令包含\u003ccode class=\"literal\"\u003eRETURNING\u003c/code\u003e子句，则其结果将类似于一条\u003ccode class=\"command\"\u003eSELECT\u003c/code\u003e语句，包含\u003ccode class=\"literal\"\u003eRETURNING\u003c/code\u003e列表中定义的列和值，这些值是针对该命令插入、更新或删除的行计算得到的。\u003c/p\u003e","key":"outputs","title":"输出"},{"html":"\u003cp\u003e在执行\u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e期间会发生以下步骤：\u003c/p\u003e\u003cdiv class=\"orderedlist\"\u003e\u003col class=\"orderedlist\"\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003e对所有已指定的动作执行任何\u003ccode class=\"literal\"\u003eBEFORE STATEMENT\u003c/code\u003e触发器，无论其\u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e子句是否匹配。\u003c/p\u003e\u003c/li\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003e执行从源到目标表的连接。生成的查询会按常规方式优化，并产生一组候选变更行。对于每个候选变更行，\u003c/p\u003e\u003cdiv class=\"orderedlist\"\u003e\u003col class=\"orderedlist\"\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003e判定该行是\u003ccode class=\"literal\"\u003eMATCHED\u003c/code\u003e、\u003ccode class=\"literal\"\u003eNOT MATCHED BY SOURCE\u003c/code\u003e还是 \u003ccode class=\"literal\"\u003eNOT MATCHED [BY TARGET]\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003e按指定顺序测试每个\u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e条件，直到有一个返回\u003ccode class=\"literal\"\u003etrue\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003e当某个条件返回\u003ccode class=\"literal\"\u003etrue\u003c/code\u003e时，执行以下动作：\u003c/p\u003e\u003cdiv class=\"orderedlist\"\u003e\u003col class=\"orderedlist\"\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003e执行为该动作事件类型触发的任何\u003ccode class=\"literal\"\u003eBEFORE ROW\u003c/code\u003e触发器。\u003c/p\u003e\u003c/li\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003e执行指定的动作，并对目标表应用任何检查约束。\u003c/p\u003e\u003c/li\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003e执行为该动作事件类型触发的任何\u003ccode class=\"literal\"\u003eAFTER ROW\u003c/code\u003e触发器。\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003c/div\u003e\u003cp\u003e如果目标关系是一个视图，并且为该动作的事件类型定义了 \u003ccode class=\"literal\"\u003eINSTEAD OF ROW\u003c/code\u003e触发器，则改由这些触发器执行该动作。\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003c/div\u003e\u003c/li\u003e\u003cli class=\"listitem\"\u003e\u003cp\u003e对已指定的动作执行任何\u003ccode class=\"literal\"\u003eAFTER STATEMENT\u003c/code\u003e触发器，无论这些动作是否实际发生。这类似于一条未修改任何行的 \u003ccode class=\"command\"\u003eUPDATE\u003c/code\u003e语句的行为。\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003c/div\u003e\u003cp\u003e总之，只要我们\u003cspan class=\"emphasis\"\u003e\u003cem\u003e指定\u003c/em\u003e\u003c/span\u003e了某种动作，对应事件类型（例如\u003ccode class=\"command\"\u003eINSERT\u003c/code\u003e）的语句级触发器就会被触发。相反，行级触发器只会针对实际被\u003cspan class=\"emphasis\"\u003e\u003cem\u003e执行\u003c/em\u003e\u003c/span\u003e的特定事件类型触发。因此，一条\u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e命令可能同时触发 \u003ccode class=\"command\"\u003eUPDATE\u003c/code\u003e和\u003ccode class=\"command\"\u003eINSERT\u003c/code\u003e的语句级触发器，即使实际上只触发了\u003ccode class=\"command\"\u003eUPDATE\u003c/code\u003e的行级触发器。\u003c/p\u003e\u003cp\u003e你应确保该连接对每个目标行最多只生成一个候选变更行。换句话说，一个目标行不应连接到多于一个数据源行。如果发生这种情况，则只会使用其中一个候选变更行来修改目标行；随后再次尝试修改该行会导致错误。如果行级触发器对目标表进行了修改，而随后这些已被修改的行又被 \u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e再次修改，也可能发生这种情况。如果重复的动作是\u003ccode class=\"command\"\u003eINSERT\u003c/code\u003e，则会导致唯一性违例错误；而重复的\u003ccode class=\"command\"\u003eUPDATE\u003c/code\u003e或\u003ccode class=\"command\"\u003eDELETE\u003c/code\u003e则会导致基数违规；后者是\u003cacronym\u003eSQL\u003c/acronym\u003e标准要求的行为。这不同于\u003cspan class=\"productname\"\u003ePostgreSQL\u003c/span\u003e历史上在 \u003ccode class=\"command\"\u003eUPDATE\u003c/code\u003e和\u003ccode class=\"command\"\u003eDELETE\u003c/code\u003e语句中处理连接的行为：对同一行的第二次及后续修改尝试会被直接忽略。\u003c/p\u003e\u003cp\u003e如果某个\u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e子句省略了\u003ccode class=\"literal\"\u003eAND\u003c/code\u003e子句，它就会成为该类型（\u003ccode class=\"literal\"\u003eMATCHED\u003c/code\u003e、\u003ccode class=\"literal\"\u003eNOT MATCHED BY SOURCE\u003c/code\u003e或 \u003ccode class=\"literal\"\u003eNOT MATCHED [BY TARGET]\u003c/code\u003e）最后一个可达的子句。如果之后又指定了同一类型的\u003ccode class=\"literal\"\u003eWHEN\u003c/code\u003e子句，则可证明它不可达，并会引发错误。如果这三类中都没有指定最后一个可达子句，则候选变更行可能不会执行任何动作。\u003c/p\u003e\u003cp\u003e默认情况下，从数据源生成行的顺序是不确定的。如果需要，可以使用\u003cem class=\"replaceable\"\u003e\u003ccode\u003esource_query\u003c/code\u003e\u003c/em\u003e指定一致的排序，这可能有助于避免并发事务之间的死锁。\u003c/p\u003e\u003cp\u003e当\u003ccode class=\"command\"\u003eMERGE\u003c/code\u003e与其他修改目标表的命令并发运行时，适用通常的事务隔离规则；请参见\u003ca href=\"/docs/18/transaction-iso.html\" title=\"13.2. 事务隔离\"\u003e第 13.2 节\u003c/a\u003e，了解各个隔离级别下的行为说明。你也可以考虑使用\u003ccode class=\"command\"\u003eINSERT ... ON CONFLICT\u003c/code\u003e作为替代语句，它提供了在发生并发\u003ccode class=\"command\"\u003eINSERT\u003c/code\u003e时执行\u003ccode class=\"command\"\u003eUPDATE\u003c/code\u003e的能力。这两种语句类型之间存在各种差异和限制，因此不能互换。\u003c/p\u003e","key":"notes","title":"注解"},{"html":"\u003cp\u003e根据新的\u003ccode class=\"literal\"\u003erecent_transactions\u003c/code\u003e对 \u003ccode class=\"literal\"\u003ecustomer_account\u003c/code\u003e执行维护。\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eMERGE INTO customer_account ca\nUSING recent_transactions t\nON t.customer_id = ca.customer_id\nWHEN MATCHED THEN\n  UPDATE SET balance = balance + transaction_value\nWHEN NOT MATCHED THEN\n  INSERT (customer_id, balance)\n  VALUES (t.customer_id, t.transaction_value);\n\u003c/pre\u003e\u003cp\u003e尝试插入一个新的库存项及其库存数量。如果该项已存在，则改为更新现有项的库存数量。不允许库存为零的条目。返回所有已发生更改的详细信息。\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eMERGE INTO wines w\nUSING wine_stock_changes s\nON s.winename = w.winename\nWHEN NOT MATCHED AND s.stock_delta \u0026gt; 0 THEN\n  INSERT VALUES(s.winename, s.stock_delta)\nWHEN MATCHED AND w.stock + s.stock_delta \u0026gt; 0 THEN\n  UPDATE SET stock = w.stock + s.stock_delta\nWHEN MATCHED THEN\n  DELETE\nRETURNING merge_action(), w.winename, old.stock AS old_stock, new.stock AS new_stock;\n\u003c/pre\u003e\u003cp\u003e例如，\u003ccode class=\"literal\"\u003ewine_stock_changes\u003c/code\u003e表可能是一个刚装载到数据库中的临时表。\u003c/p\u003e\u003cp\u003e根据替换后的酒单更新\u003ccode class=\"literal\"\u003ewines\u003c/code\u003e：为任何新库存插入行，更新已修改的库存条目，并删除新列表中不存在的任何葡萄酒。\u003c/p\u003e\u003cpre class=\"programlisting\"\u003eMERGE INTO wines w\nUSING new_wine_list s\nON s.winename = w.winename\nWHEN NOT MATCHED BY TARGET THEN\n  INSERT VALUES(s.winename, s.stock)\nWHEN MATCHED AND w.stock != s.stock THEN\n  UPDATE SET stock = s.stock\nWHEN NOT MATCHED BY SOURCE THEN\n  DELETE;\n\u003c/pre\u003e","key":"examples","title":"示例"},{"html":"\u003cp\u003e这个命令符合\u003cacronym\u003eSQL\u003c/acronym\u003e标准。\u003c/p\u003e\u003cp\u003e\u003ccode class=\"literal\"\u003eWITH\u003c/code\u003e子句、\u003ccode class=\"literal\"\u003eWHEN NOT MATCHED\u003c/code\u003e上的 \u003ccode class=\"literal\"\u003eBY SOURCE\u003c/code\u003e和\u003ccode class=\"literal\"\u003eBY TARGET\u003c/code\u003e限定词、\u003ccode class=\"literal\"\u003eDO NOTHING\u003c/code\u003e动作以及\u003ccode class=\"literal\"\u003eRETURNING\u003c/code\u003e子句，都是对\u003cacronym\u003eSQL\u003c/acronym\u003e标准的扩展。\u003c/p\u003e","key":"compatibility","title":"兼容性"}],"sections_same_as":"","synopsis_html":"[ WITH \u003cem class=\"replaceable\"\u003e\u003ccode\u003ewith_query\u003c/code\u003e\u003c/em\u003e [, ...] ]\nMERGE INTO [ ONLY ] \u003cem class=\"replaceable\"\u003e\u003ccode\u003etarget_table_name\u003c/code\u003e\u003c/em\u003e [ * ] [ [ AS ] \u003cem class=\"replaceable\"\u003e\u003ccode\u003etarget_alias\u003c/code\u003e\u003c/em\u003e ]\n    USING \u003cem class=\"replaceable\"\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e ON \u003cem class=\"replaceable\"\u003e\u003ccode\u003ejoin_condition\u003c/code\u003e\u003c/em\u003e\n    \u003cem class=\"replaceable\"\u003e\u003ccode\u003ewhen_clause\u003c/code\u003e\u003c/em\u003e [...]\n    [ RETURNING [ WITH ( { OLD | NEW } AS \u003cem class=\"replaceable\"\u003e\u003ccode\u003eoutput_alias\u003c/code\u003e\u003c/em\u003e [, ...] ) ]\n                { * | \u003cem class=\"replaceable\"\u003e\u003ccode\u003eoutput_expression\u003c/code\u003e\u003c/em\u003e [ [ AS ] \u003cem class=\"replaceable\"\u003e\u003ccode\u003eoutput_name\u003c/code\u003e\u003c/em\u003e ] } [, ...] ]\n\n\u003cspan class=\"phrase\"\u003e其中 \u003cem class=\"replaceable\"\u003e\u003ccode\u003edata_source\u003c/code\u003e\u003c/em\u003e 为：\u003c/span\u003e\n\n    { [ ONLY ] \u003cem class=\"replaceable\"\u003e\u003ccode\u003esource_table_name\u003c/code\u003e\u003c/em\u003e [ * ] | ( \u003cem class=\"replaceable\"\u003e\u003ccode\u003esource_query\u003c/code\u003e\u003c/em\u003e ) } [ [ AS ] \u003cem class=\"replaceable\"\u003e\u003ccode\u003esource_alias\u003c/code\u003e\u003c/em\u003e ]\n\n\u003cspan class=\"phrase\"\u003e而 \u003cem class=\"replaceable\"\u003e\u003ccode\u003ewhen_clause\u003c/code\u003e\u003c/em\u003e 为：\u003c/span\u003e\n\n    { WHEN MATCHED [ AND \u003cem class=\"replaceable\"\u003e\u003ccode\u003econdition\u003c/code\u003e\u003c/em\u003e ] THEN { \u003cem class=\"replaceable\"\u003e\u003ccode\u003emerge_update\u003c/code\u003e\u003c/em\u003e | \u003cem class=\"replaceable\"\u003e\u003ccode\u003emerge_delete\u003c/code\u003e\u003c/em\u003e | DO NOTHING } |\n      WHEN NOT MATCHED BY SOURCE [ AND \u003cem class=\"replaceable\"\u003e\u003ccode\u003econdition\u003c/code\u003e\u003c/em\u003e ] THEN { \u003cem class=\"replaceable\"\u003e\u003ccode\u003emerge_update\u003c/code\u003e\u003c/em\u003e | \u003cem class=\"replaceable\"\u003e\u003ccode\u003emerge_delete\u003c/code\u003e\u003c/em\u003e | DO NOTHING } |\n      WHEN NOT MATCHED [ BY TARGET ] [ AND \u003cem class=\"replaceable\"\u003e\u003ccode\u003econdition\u003c/code\u003e\u003c/em\u003e ] THEN { \u003cem class=\"replaceable\"\u003e\u003ccode\u003emerge_insert\u003c/code\u003e\u003c/em\u003e | DO NOTHING } }\n\n\u003cspan class=\"phrase\"\u003e而 \u003cem class=\"replaceable\"\u003e\u003ccode\u003emerge_insert\u003c/code\u003e\u003c/em\u003e 为：\u003c/span\u003e\n\n    INSERT [( \u003cem class=\"replaceable\"\u003e\u003ccode\u003ecolumn_name\u003c/code\u003e\u003c/em\u003e [, ...] )]\n        [ OVERRIDING { SYSTEM | USER } VALUE ]\n        { VALUES ( { \u003cem class=\"replaceable\"\u003e\u003ccode\u003eexpression\u003c/code\u003e\u003c/em\u003e | DEFAULT } [, ...] ) | DEFAULT VALUES }\n\n\u003cspan class=\"phrase\"\u003e而 \u003cem class=\"replaceable\"\u003e\u003ccode\u003emerge_update\u003c/code\u003e\u003c/em\u003e 为：\u003c/span\u003e\n\n    UPDATE SET { \u003cem class=\"replaceable\"\u003e\u003ccode\u003ecolumn_name\u003c/code\u003e\u003c/em\u003e = { \u003cem class=\"replaceable\"\u003e\u003ccode\u003eexpression\u003c/code\u003e\u003c/em\u003e | DEFAULT } |\n                 ( \u003cem class=\"replaceable\"\u003e\u003ccode\u003ecolumn_name\u003c/code\u003e\u003c/em\u003e [, ...] ) = [ ROW ] ( { \u003cem class=\"replaceable\"\u003e\u003ccode\u003eexpression\u003c/code\u003e\u003c/em\u003e | DEFAULT } [, ...] ) |\n                 ( \u003cem class=\"replaceable\"\u003e\u003ccode\u003ecolumn_name\u003c/code\u003e\u003c/em\u003e [, ...] ) = ( \u003cem class=\"replaceable\"\u003e\u003ccode\u003esub-SELECT\u003c/code\u003e\u003c/em\u003e )\n               } [, ...]\n\n\u003cspan class=\"phrase\"\u003e而 \u003cem class=\"replaceable\"\u003e\u003ccode\u003emerge_delete\u003c/code\u003e\u003c/em\u003e 为：\u003c/span\u003e\n\n    DELETE","synopsis_text":"[ WITH with_query [, ...] ]\nMERGE INTO [ ONLY ] target_table_name [ * ] [ [ AS ] target_alias ]\nUSING data_source ON join_condition\nwhen_clause [...]\n[ RETURNING [ WITH ( { OLD | NEW } AS output_alias [, ...] ) ]\n{ * | output_expression [ [ AS ] output_name ] } [, ...] ]\n\n其中 data_source 为：\n\n{ [ ONLY ] source_table_name [ * ] | ( source_query ) } [ [ AS ] source_alias ]\n\n而 when_clause 为：\n\n{ WHEN MATCHED [ AND condition ] THEN { merge_update | merge_delete | DO NOTHING } |\nWHEN NOT MATCHED BY SOURCE [ AND condition ] THEN { merge_update | merge_delete | DO NOTHING } |\nWHEN NOT MATCHED [ BY TARGET ] [ AND condition ] THEN { merge_insert | DO NOTHING } }\n\n而 merge_insert 为：\n\nINSERT [( column_name [, ...] )]\n[ OVERRIDING { SYSTEM | USER } VALUE ]\n{ VALUES ( { expression | DEFAULT } [, ...] ) | DEFAULT VALUES }\n\n而 merge_update 为：\n\nUPDATE SET { column_name = { expression | DEFAULT } |\n( column_name [, ...] ) = [ ROW ] ( { expression | DEFAULT } [, ...] ) |\n( column_name [, ...] ) = ( sub-SELECT )\n} [, ...]\n\n而 merge_delete 为：\n\nDELETE"}},"RequestedLocale":"zh-Hans","Fallback":false,"Versions":["15","16","17","18","19","20"],"Locales":["en","zh-Hans"],"Signatures":null,"Spellings":null,"SQLState":null,"Evidence":null}
