Skip to main content

INSERT … ON CONFLICT (Upsert)

The upsert clause is an extension to INSERT that specifies what to do when the insert would violate a UNIQUE or PRIMARY KEY constraint. Instead of failing with an error, the statement can either skip the conflicting row or update it.

Syntax

Where conflict-target is:

Description

An upsert clause is added to the end of an INSERT statement to handle constraint violations gracefully. There are two actions: DO NOTHING silently skips the conflicting row, and DO UPDATE modifies the existing row in place.

DO NOTHING

DO NOTHING causes the INSERT to silently skip any row that would violate the specified constraint. No error is raised and the existing row is left unchanged. When a conflict target is specified, only violations on that particular constraint trigger the skip. When no conflict target is specified, any constraint violation triggers the skip.

DO UPDATE

DO UPDATE causes the INSERT to update the existing row when a constraint violation occurs. The SET clause specifies which columns to update and what values to assign. A conflict target is required for DO UPDATE.

Conflict Target

The conflict target identifies which UNIQUE or PRIMARY KEY constraint the clause applies to. It is a parenthesized list of column names that must exactly match the columns of an existing unique constraint on the table. For partial unique indexes (indexes with a WHERE clause), the conflict target must also include a WHERE clause that matches the index’s condition.

The excluded Table

Inside the SET and WHERE clauses of DO UPDATE, the special excluded table contains the values that were proposed for insertion. This allows the update expression to reference both the existing row (using the table name) and the proposed new row (using excluded).

WHERE Clause on DO UPDATE

The DO UPDATE clause can include a WHERE expression that further restricts when the update occurs. If the WHERE condition evaluates to false for a conflicting row, that row is left unchanged (the insert is silently skipped, as with DO NOTHING).
In this example, the price is only updated if the new price is lower than the existing price.

Multiple ON CONFLICT Clauses

An INSERT statement can have multiple ON CONFLICT clauses, each targeting a different constraint. The clauses are evaluated in order. When a constraint violation occurs, the first matching clause is used.
At most one ON CONFLICT clause can omit the conflict target. A clause without a conflict target acts as a catch-all and must appear last. Only DO NOTHING is allowed without a conflict target.

Examples

Upsert a counter

Bulk insert, skipping duplicates

Conditional update with excluded

See Also

  • INSERT for standard insert operations
  • REPLACE for delete-and-reinsert conflict resolution
  • UPDATE for modifying existing rows directly
  • CREATE TABLE for defining UNIQUE and PRIMARY KEY constraints