advancedupserting MySQL MariaDB SQL Server PostgreSQL SQLite
Insert Or Update A Row With UPSERT
Atomically insert a row if it does not exist or update it if it does, using the database's native conflict-resolution syntax.
Created Last updated 5/5 supported engines validation-green1 example2 scenarios
Docker-validated Not currently validation-green
Example 1
Record a page view, inserting on first visit or incrementing on return
The home page already exists with 5 views. The upsert detects the conflict on the primary key and increments views to 6 instead of inserting a duplicate. If home had not existed, a new row with views = 1 would have been inserted.
INSERTINTO
page_views (page, views)
VALUES
('home', 1) ON CONFLICT (page) DO
UPDATESET
views = page_views.views + 1;
SELECT
page,
views
FROM
page_views
ORDERBY
page;
Expected result
page
views
home
6
Each engine uses different upsert syntax. The final table state is identical: views incremented from 5 to 6.
Useful when
Where this command helps.
recording counters or snapshots keyed by a unique id
synchronizing incoming data when rows may already exist
Explanation
What the command is doing.
An upsert avoids the race condition of checking for a row and then inserting or updating in separate statements. Each database engine has its own syntax for this operation: MySQL and MariaDB use ON DUPLICATE KEY UPDATE, PostgreSQL uses ON CONFLICT DO UPDATE, and SQL Server uses the MERGE statement. All approaches are atomic within a single statement.