Skip to content

Bits of .NET

Daily micro-tips for C#, SQL, performance, and scalable backend engineering.

  • Asp.Net Core
  • C#
  • SQL
  • JavaScript
  • CSS
  • About
  • ErcanOPAK.com
  • No Access
  • Privacy Policy
SQL

SQL: Use UPSERT (INSERT ON CONFLICT) for Insert or Update

- 30.05.26 - ErcanOPAK

🔄 One Query: Insert or Update

Check if exists → Update or Insert = 2 queries. UPSERT does it in one. Faster, atomic, race-condition free.

📝 PostgreSQL (ON CONFLICT)

-- Basic UPSERT (update if conflict)
INSERT INTO users (id, name, email, last_login)
VALUES (1, 'Alice', 'alice@example.com', NOW())
ON CONFLICT (id) DO UPDATE 
SET name = EXCLUDED.name,
    email = EXCLUDED.email,
    last_login = EXCLUDED.last_login;

-- UPSERT with specific columns
INSERT INTO products (sku, name, price, stock)
VALUES ('ABC-123', 'Widget', 19.99, 100)
ON CONFLICT (sku) DO UPDATE 
SET price = EXCLUDED.price,
    stock = products.stock + EXCLUDED.stock;  -- Increment stock

-- WHERE clause in UPSERT
INSERT INTO inventory (product_id, warehouse_id, quantity)
VALUES (1, 5, 50)
ON CONFLICT (product_id, warehouse_id) DO UPDATE 
SET quantity = EXCLUDED.quantity
WHERE inventory.quantity < 100;  -- Only update if less than 100

-- DO NOTHING (ignore if exists)
INSERT INTO logs (event_id, message)
VALUES (123, 'User login')
ON CONFLICT (event_id) DO NOTHING;

🎯 MySQL (ON DUPLICATE KEY)

INSERT INTO users (id, name, email)
VALUES (1, 'Alice', 'alice@example.com')
ON DUPLICATE KEY UPDATE 
    name = VALUES(name),
    email = VALUES(email);

-- Increment counter
INSERT INTO page_views (page_url, view_count)
VALUES ('/home', 1)
ON DUPLICATE KEY UPDATE 
    view_count = view_count + 1;

✅ Use Cases

-- Daily stats aggregation
INSERT INTO daily_stats (stat_date, user_count, revenue)
VALUES (CURRENT_DATE, 1, 99.99)
ON CONFLICT (stat_date) DO UPDATE 
SET user_count = daily_stats.user_count + 1,
    revenue = daily_stats.revenue + EXCLUDED.revenue;

-- Session tracking
INSERT INTO user_sessions (session_id, user_id, last_active)
VALUES ('abc123', 42, NOW())
ON CONFLICT (session_id) DO UPDATE 
SET last_active = EXCLUDED.last_active;

-- Batch import (ignore duplicates)
INSERT INTO products (sku, name, price)
VALUES 
    ('A001', 'Product 1', 10.00),
    ('A002', 'Product 2', 20.00)
ON CONFLICT (sku) DO NOTHING;

💡 Database Support

  • PostgreSQL: ON CONFLICT (most flexible)
  • MySQL: ON DUPLICATE KEY (simpler)
  • SQLite: ON CONFLICT (similar to PostgreSQL)
  • SQL Server: MERGE (more verbose)

"Race condition: two requests tried to upsert same row. SELECT + INSERT/UPDATE failed. ON CONFLICT is atomic. No more duplicate rows or lost updates."

— Database Developer

Related posts:

SQL Server — COUNT(*) vs COUNT(column) Is Not the Same

Get the User Name and Domain Name from an Email Address in SQL

SQL Deletes Lock Tables

Post Views: 6

Post navigation

.NET Core: Implement API Versioning Without Breaking Clients
C#: Use Primary Constructors to Reduce Boilerplate (.NET 8)

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

June 2026
M T W T F S S
1234567
891011121314
15161718192021
22232425262728
2930  
« May    

Most Viewed Posts

  • Get the User Name and Domain Name from an Email Address in SQL (953)
  • How to add default value for Entity Framework migrations for DateTime and Bool (882)
  • Get the First and Last Word from a String or Sentence in SQL (838)
  • How to select distinct rows in a datatable in C# (808)
  • How to make theater mode the default for Youtube (805)
  • Add Constraint to SQL Table to ensure email contains @ (580)
  • How to enable, disable and check if Service Broker is enabled on a database in SQL Server (579)
  • Average of all values in a column that are not zero in SQL (538)
  • How to use Map Mode for Vertical Scroll Mode in Visual Studio (505)
  • Find numbers with more than two decimal places in SQL (454)

Recent Posts

  • C#: Use String Interpolation Instead of Concatenation
  • C#: Use Tuples to Return Multiple Values from Methods
  • SQL: Use ISNULL and NULLIF for Smart NULL Handling
  • .NET Core: Use Data Annotations for Model Validation
  • Git: Use Git Clean to Remove Untracked Files
  • Ajax: Add Custom Headers to Fetch Requests
  • JavaScript: Use console.table to Display Arrays as Tables
  • HTML: Use Spellcheck Attribute to Enable Browser Spell Check
  • CSS: Use user-select to Prevent Text Selection
  • Windows 11: Use Snipping Tool for Instant Screenshots

Most Viewed Posts

  • Get the User Name and Domain Name from an Email Address in SQL (953)
  • How to add default value for Entity Framework migrations for DateTime and Bool (882)
  • Get the First and Last Word from a String or Sentence in SQL (838)
  • How to select distinct rows in a datatable in C# (808)
  • How to make theater mode the default for Youtube (805)

Recent Posts

  • C#: Use String Interpolation Instead of Concatenation
  • C#: Use Tuples to Return Multiple Values from Methods
  • SQL: Use ISNULL and NULLIF for Smart NULL Handling
  • .NET Core: Use Data Annotations for Model Validation
  • Git: Use Git Clean to Remove Untracked Files

Social

  • ErcanOPAK.com
  • GoodReads
  • LetterBoxD
  • Linkedin
  • The Blog
  • Twitter
© 2026 Bits of .NET | Built with Xblog Plus free WordPress theme by wpthemespace.com