Skip to content

Instantly share code, notes, and snippets.

@DaveSanders
Created January 30, 2014 22:46
Show Gist options
  • Save DaveSanders/8721734 to your computer and use it in GitHub Desktop.
Save DaveSanders/8721734 to your computer and use it in GitHub Desktop.
SQL MERGE for Upsert example
--- CREATE THE TABLE
USE [Bench]
GO
/****** Object: Table [dbo].[users] Script Date: 1/30/2014 5:42:46 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[users](
[id] [int] IDENTITY(1,1) NOT NULL,
[first_name] [nvarchar](50) NOT NULL,
[last_name] [nvarchar](50) NOT NULL,
[nickname] [nvarchar](50) NULL,
[created_at] [datetime] NOT NULL,
[updated_at] [datetime] NOT NULL,
CONSTRAINT [PK_users] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
--- INSERT A RECORD
INSERT INTO users (first_name, last_name, nickname, created_at, updated_at)
VALUES ('John', 'Doe', 'Johnny', getdate(), getdate())
GO
--- UPSERT THE RECORD
MERGE
users as target --Table name
USING (
VALUES (1, 'Joe', 'Doe', null, getdate(), getdate())
) as source (id, first_name, last_name, nickname, created_at, updated_at)
ON target.id = source.id
WHEN MATCHED THEN
UPDATE SET
first_name = source.first_name,
last_name = source.last_name,
nickname = source.nickname,
created_at = source.created_at,
updated_at = source.updated_at
WHEN NOT MATCHED THEN
INSERT (first_name, last_name, nickname, created_at, updated_at)
VALUES (source.first_name, source.last_name, source.nickname, source.created_at, source.updated_at)
; -- semicolon important for merge
--- UPSERT A NEW RECORD
MERGE
users as target --Table name
USING (
VALUES (2, 'Jane', 'Doe', null, getdate(), getdate())
) as source (id, first_name, last_name, nickname, created_at, updated_at)
ON target.id = source.id
WHEN MATCHED THEN
UPDATE SET
first_name = source.first_name,
last_name = source.last_name,
nickname = source.nickname,
created_at = source.created_at,
updated_at = source.updated_at
WHEN NOT MATCHED THEN
INSERT (first_name, last_name, nickname, created_at, updated_at)
VALUES (source.first_name, source.last_name, source.nickname, source.created_at, source.updated_at)
;
SELECT * FROM users -- should be two records
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment