MySQL
ORACLE
POSTGRESQL
SQL
SQL SERVER

SQL Upsert: Inserting a Record If It Does Not Exist

intro

Let's find out everything you need to know about the SQL upsert operation to either add or update rows in a table.

Tools used in the tutorial
Tool Description Link
Dbvisualizer DBVISUALIZER
TOP RATED DATABASE MANAGEMENT TOOL AND SQL CLIENT

A common scenario for avoiding duplicates in a table is to insert a record only if it is not already present. Otherwise, you need to update the existing record with new values. Normally, this would require multiple queries and/or application-level logic. However, considering how frequent that scenario is, most databases provide an SQL upsert implementation to either insert or update records in a single operation.

In this guide, you will learn about the upsert SQL operation, including how it works and when to use it.

Let's dive in!

What Is the SQL Upsert Operation?

The term "upsert" comes from the combination of the words "update" and "insert." So, the SQL upsert operation merges the functionality of both INSERT and UPDATE commands. Specifically, it inserts a new record into a table if it does not already exist or updates the existing record if it does.

Typically, the database determines whether a record exists based on unique indexes or conflict conditions specified in the upsert query. Thus, when performing an upsert in SQL, the database inserts a new row if the record does not already exist based on some conflict conditions, or it updates the existing record with the new values if a conflict is detected.

Use Cases of the SQL Upsert Command

The upsert SQL operation helps maintain data integrity by preventing duplicate records in a table. This operation is particularly useful in three scenarios:

  1. Data synchronization: Ensure that data is up-to-date by either inserting new records or updating existing ones when merging information from different systems or applications.
  2. Batch data processing: Manage large volumes of data efficiently by handling multiple updates and inserts in a single operation, minimizing the need for separate INSERT and UPDATE statements.
  3. Data warehousing: Simplify data loading into data warehouses by inserting new records and updating existing ones during ETL (Extract, Transform, Load) processes.

As you can imagine, the applications of the SQL upsert statement are broad, ranging from inventory management to order processing.

Upsert SQL Syntax

Time to explore how to use the upsert operation in different SQL dialects!

From now on, let's assume we have a users table with an auto-incrementing id as the primary key and a username column with a UNIQUE constraint. The table contains a row where the username is 'maria_williams' and the email is 'maria.williams@example.com' :

The Data tab of the users table in DbVisualizer
The Data tab of the users table in DbVisualizer

MySQL

MySQL allows you to implement the SQL upsert operation through the INSERT ... ON DUPLICATE KEY UPDATE statement.

If the ON DUPLICATE KEY UPDATE clause is specified in an INSERT statement and the value is a duplicate, your database will update the existing row.

Use the INSERT ... ON DUPLICATE KEY UPDATE statement as shown below:

Copy
        
1 INSERT INTO users (username, email) 2 VALUES ('maria_williams', 'maria.williams_2@example.com') 3 ON DUPLICATE KEY UPDATE email = 'maria.williams_2@example.com';

Equivalently, if you want to avoid repeating the email, you can write:

Copy
        
1 INSERT INTO users (username, email) 2 VALUES ('maria_williams', 'maria.williams_2@example.com') 3 ON DUPLICATE KEY UPDATE email = VALUES(email);

Now, if no row with username = 'maria_williams' exists, the following INSERT query will be executed:

Copy
        
1 INSERT INTO users (username, email) 2 VALUES ('maria_williams', 'maria.williams_2@example.com');

If a row with username = 'maria_williams' already exists, this UPDATE query will be run:

Copy
        
1 UPDATE users 2 SET email = 'maria.williams_2@example.com' 3 WHERE username = 'maria_williams';

Thus, if maria_williams already exists in the database, the statement updates the email field to 'maria.williams_2@example.com'. Otherwise, it adds a new row.

If the email column had a UNIQUE constraint, and a condition like username = 'maria_williams' OR email = 'maria.williams_2@example.com' matched several rows, only one row would be updated. In general, it is a good practice to avoid using ON DUPLICATE KEY UPDATE on tables with multiple unique indexes, as that can lead to unexpected behavior by the database.

Keep in mind that ON DUPLICATE KEY UPDATE clause can contain multiple column assignments separated by commas.

Note that the same approach is also supported by MariaDB. Learn more about the two database management systems in our comparison guide on MariaDB vs MySQL.

PostgreSQL

PostgreSQL supports the upsert SQL operation via the INSERT ... ON CONFLICT statement. Use it as in the following example:

Copy
        
1 INSERT INTO users (username, email) 2 VALUES ('maria_williams', 'maria.williams_2@example.com') 3 ON CONFLICT 4 DO UPDATE SET email = 'maria.williams_2@example.com';

Or, equivalently:

Copy
        
1 INSERT INTO users (username, email) 2 VALUES ('maria_williams', 'maria.williams_2@example.com') 3 ON CONFLICT 4 DO UPDATE SET email = EXCLUDED.email;

If the specified username already exists, PostgreSQL will update the email field to the new value. The EXCLUDED keyword refers to the values proposed for insertion.

Note that ON CONFLICT lets you specify an optional alternative action to raise a unique violation or exclusion constraint violation error. In the following example, the conflict occurs on duplicate emails:

Copy
        
1 INSERT INTO users (username, email) 2 VALUES ('john_doe', 'john.doe@example.com') 3 ON CONFLICT (email) 4 DO UPDATE SET username = EXCLUDED.username, email = EXCLUDED.email;

In this case, the conflict happens if the email column has a duplicate value. In that scenario, PostgreSQL will update the username and email fields of the row with the conflicting email with the new values read using the EXCLUDED syntax. As you can see, the DO UPDATE SET clause can include a list of columns separated by commas.

To execute the ON CONFLICT DO UPDATE queries, you need both the INSERT and UPDATE privileges on the columns that are listed on the statement.

Find out more about this approach in our dedicated PostgreSQL upsert guide.

SQL Server

Unfortunately, SQL Server does not provide a direct upsert statement. However, that does not mean you cannot achieve an SQL Server upsert mechanism with some custom logic!

A common way to implement upsert in SQL Server is to use the MERGE statement as in this example:

Copy
        
1 MERGE INTO users AS target 2 USING (VALUES ('maria_williams', 'maria.williams_2@example.com')) AS source (username, email) 3 ON target.username = source.username 4 WHEN MATCHED THEN 5 UPDATE SET target.email = source.email 6 WHEN NOT MATCHED THEN 7 INSERT (username, email) 8 VALUES (source.username, source.email);

The MERGE statement merges the source and target tables. In detail, if the username already exists in the users table (the target), the email field is updated. If no match is found, a new row is inserted with the given username and email values.

Another way to implement upsert is by using the system function @@ROWCOUNT to check whether an update happened. If it did not happen, you can use an INSERT as follows:

Copy
        
1 UPDATE users 2 SET email = 'maria.williams_2@example.com' 3 WHERE username = 'maria_williams'; 4 5 IF @@ROWCOUNT = 0 6 BEGIN 7 INSERT INTO users (username, email) 8 VALUES ('maria_williams', 'maria.williams_2@example.com'); 9 END;

This SQL script attempts to update the existing row with the username = 'maria_williams'. @@ROWCOUNT returns the number of rows affected by the last statement. So, if @@ROWCOUNT equals 0, no rows were updated. That means the maria_williams row does not exist, and the INSERT statement is executed accordingly.

There are other possible approaches to implement the upsert SQL Server operation, but the two methods above are the most commonly used.

Oracle

Similar to SQL Server, in Oracle, you can implement upsert using the MERGE statement:

Copy
        
1 MERGE INTO users target 2 USING (SELECT 'maria_williams' AS username, 'maria.williams_2@example.com' AS email FROM dual) source 3 ON (target.username = source.username) 4 WHEN MATCHED THEN 5 UPDATE SET target.email = source.email 6 WHEN NOT MATCHED THEN 7 INSERT (username, email) 8 VALUES (source.username, source.email);

dual is a special dummy table used to select data in cases where no real table is involved, as in the above query.

Equivalently, you can write the following PL/SQL upsert logic using a BEGIN ... EXCEPTION block and catching the DUP_VAL_ON_INDEX exception:

Copy
        
1 BEGIN 2 INSERT INTO users (username, email) 3 VALUES ('maria_williams', 'maria.williams_2@example.com'); 4 EXCEPTION 5 WHEN DUP_VAL_ON_INDEX THEN 6 UPDATE users 7 SET email = 'maria.williams_2@example.com' 8 WHERE username = 'maria_williams'; 9 END;

Advanced Data Management with DbVisualizer

Upsert is definitely a useful operation for managing data, but it is nothing compared to the capabilities offered by a feature-rich tool like DbVisualizer.

DbVisualizer is a top-ranked database client with a range of advanced features, including in-line data editing. This feature allows you to visually insert or edit data directly within tables, saving significant time and effort in data management:

The in-line editing in action in Dbvisualizer
The in-line editing in action in Dbvisualizer

Explore all DbVisualizer’s advanced features and take advantage of a 21-day free trial of the Pro version. Enhance your data management experience!

Conclusion

In this article, you saw what the SQL upsert operation is, how it works, and how to use it in MySQL, PostgreSQL, SQL Server, and Oracle. With this knowledge, you are now equipped to handle conditional inserts in SQL.

Upsert is a powerful data management feature that becomes easier to handle with a robust database client like DbVisualizer. DbVisualizer supports numerous DBMSs and offers in-line data editing, advanced query optimization, and drag-and-drop query construction. Download DbVisualizer for free now!

FAQ

Is upsert part of the SQL standard?

No, the upsert operation is not part of the SQL ISO/ANSI standard. Still, it is widely supported across various database systems with different syntaxes. While the exact implementation varies among SQL dialects, the concept of combining insert and update functionality is available in most databases.

When should you use upsert in SQL?

The use of upsert in SQL is recommended in situations where you need to insert a new record into a table or update an existing record in case of a conflict. That helps maintain data integrity and avoid duplicate rows.

Is there a direct implementation of upsert in SQL Server?

No, unfortunately, there is not a direct implementation of upsert in SQL Server. However, you can implement SQL Server upsert operations by using MERGE statements or a combination of INSERT and UPDATE with @@ROWCOUNT.

Is the upsert SQL operation an anti-pattern?

Many consider the upsert SQL operation an anti-pattern because it can lead to performance issues, such as the database having to locate the record that needs to be updated twice, particularly in some SQL Server implementations. To learn more about avoiding these drawbacks, refer to the dedicated guide by Aaron Bertrand.

Is UPSERT part of the SQL commands like INSERT or UPDATE?

No, UPSERT is not a standard SQL command like INSERT or UPDATE. Instead, it is a concept implemented using different syntaxes across various databases. Explore our article to discover all SQL commands.

Dbvis download link img
About the author
Antonello Zanini

Antonello is a software engineer, and often refers to himself as a technology bishop. His mission is to spread knowledge through writing.

The Table Icon
Sign up to receive The Table's roundup
More from the table
Title Author Tags Length Published
title

Automating SQL Queries with SQL CLI and SQL Job Scheduling

author Bonnie tags AUTOMATION SQL 6 min 2025-01-14
title

A Guide to SQL Server Indexes on Partitioned Tables

author Antonello Zanini tags SQL SERVER 7 min 2025-01-13
title

How to Display All Duplicate Records in a MySQL Table

author Antonello Zanini tags MySQL 6 min 2025-01-08
title

Understanding the SQL UNIQUE Constraint

author Leslie S. Gyamfi tags DbVisualizer SQL 6 min 2025-01-07
title

How to Drop an Index By Partition Number in SQL Server

author Antonello Zanini tags SQL SERVER 7 min 2025-01-06
title

Exploring Cursors and Temporary Tables in SQL

author Ochuko Onojakpor tags Cursors SQL 10 min 2024-12-30
title

The Most Interesting Functions in MySQL – A Guide

author Lukas Vileikis tags MySQL 5 min 2024-12-27
title

MySQL Primary Key: What It Is, How It Works, and When to Use It

author Lukas Vileikis tags Data Visualization Tools DbVisualizer MySQL 8 min 2024-12-23
title

What Is a PostgreSQL Primary Key?

author Leslie S. Gyamfi tags POSTGRESQL 8 min 2024-12-18
title

SQL CHECK Constraint: Definitive Guide With Examples

author Antonello Zanini tags MySQL ORACLE POSTGRESQL SQL SQL SERVER 8 min 2024-12-16

The content provided on dbvis.com/thetable, including but not limited to code and examples, is intended for educational and informational purposes only. We do not make any warranties or representations of any kind. Read more here.