Upsert JSON documents in SQL Server 2016

Published Mar 23 2019 02:18 PM 1,026 Views
Microsoft
First published on MSDN on Mar 03, 2016
In Sql Server 2016 you can easily insert or update JSON documents by combining OPENJSON and MERGE statement. In this example I will create one procedure that imports events formatted as JSON in Events table.

Example code is shown in the following listing. I'm creating one table that will contain events and procedure that will de-serialize events formatted as JSON and upsert them into destination table.
-- Drop sp_ImportEvents stored procedure
DROP PROCEDURE IF EXISTS dbo.sp_ImportEvents
GO

-- Drop Events table
DROP TABLE IF EXISTS dbo.Events
GO

-- Create Events table
CREATE TABLE dbo.Events(
EventId int PRIMARY KEY,
DeviceId int NOT NULL,
Value int NOT NULL,
Timestamp datetime2(7) NULL
)
GO
-- Create sp_InsertEvents stored procedure
CREATE PROCEDURE dbo.sp_ImportEvents
@Events NVARCHAR(MAX)
AS
BEGIN
MERGE INTO dbo.Events AS A
USING (
SELECT *
FROM OPENJSON(@Events) WITH (EventId int, DeviceId int, Value int, Timestamp datetime2(7))) B
ON (A.EventId = B.EventId)
WHEN MATCHED THEN
UPDATE SET A.DeviceId = B.DeviceId,
A.Value = B.Value,
A.Timestamp = B.Timestamp
WHEN NOT MATCHED THEN
INSERT (EventId, DeviceId, Value, Timestamp)
VALUES(B.EventId, B.DeviceId, B.Value, B.Timestamp);
END
GO



Events are provided as JSON array (or single JSON object) that has EventId, DeviceId, Value, and Timestamp properties. OPENJSON will open this document and transform it to table results. Then you can provide this resultset to MERGE statement where you can insert new row or update existing based on the Id column.

Now you can easily import one or many JSON documents into Event table:
EXEC sp_ImportEvents N'{"EventId":1,"DeviceId":17,"Value":35,"Timestamp":"2015-10-23 12:45:37.1237"}'
SELECT * FROM Events

GO

EXEC sp_ImportEvents
N'[{"EventId":1,"DeviceId":17,"Value":37,"Timestamp":"2015-10-23 12:45:37.1237"},
{"EventId":2,"DeviceId":17,"Value":35,"Timestamp":"2015-10-23 12:45:37.1237"}]'
SELECT * FROM Events
1 Comment
%3CLINGO-SUB%20id%3D%22lingo-sub-384637%22%20slang%3D%22en-US%22%3EUpsert%20JSON%20documents%20in%20SQL%20Server%202016%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-384637%22%20slang%3D%22en-US%22%3E%0A%20%26lt%3Bmeta%20http-equiv%3D%22Content-Type%22%20content%3D%22text%2Fhtml%3B%20charset%3DUTF-8%22%20%2F%26gt%3B%3CSTRONG%3E%20First%20published%20on%20MSDN%20on%20Mar%2003%2C%202016%20%3C%2FSTRONG%3E%20%3CBR%20%2F%3E%20In%20Sql%20Server%202016%20you%20can%20easily%20insert%20or%20update%20JSON%20documents%20by%20combining%20OPENJSON%20and%20MERGE%20statement.%20In%20this%20example%20I%20will%20create%20one%20procedure%20that%20imports%20events%20formatted%20as%20JSON%20in%20Events%20table.%20%3CBR%20%2F%3E%20%3CBR%20%2F%3E%20Example%20code%20is%20shown%20in%20the%20following%20listing.%20I'm%20creating%20one%20table%20that%20will%20contain%20events%20and%20procedure%20that%20will%20de-serialize%20events%20formatted%20as%20JSON%20and%20upsert%20them%20into%20destination%20table.%20%3CBR%20%2F%3E%20--%20Drop%20sp_ImportEvents%20stored%20procedure%20%3CBR%20%2F%3E%20DROP%20PROCEDURE%20IF%20EXISTS%20dbo.sp_ImportEvents%20%3CBR%20%2F%3E%20GO%20%3CBR%20%2F%3E%20%3CBR%20%2F%3E%20--%20Drop%20Events%20table%20%3CBR%20%2F%3E%20DROP%20TABLE%20IF%20EXISTS%20dbo.Events%20%3CBR%20%2F%3E%20GO%20%3CBR%20%2F%3E%20%3CBR%20%2F%3E%20--%20Create%20Events%20table%20%3CBR%20%2F%3E%20CREATE%20TABLE%20dbo.Events(%20%3CBR%20%2F%3E%20EventId%20int%20PRIMARY%20KEY%2C%20%3CBR%20%2F%3E%20DeviceId%20int%20NOT%20NULL%2C%20%3CBR%20%2F%3E%20Value%20int%20NOT%20NULL%2C%20%3CBR%20%2F%3E%20Timestamp%20datetime2(7)%20NULL%20%3CBR%20%2F%3E%20)%20%3CBR%20%2F%3E%20GO%20%3CBR%20%2F%3E%20--%20Create%20sp_InsertEvents%20stored%20procedure%20%3CBR%20%2F%3E%20CREATE%20PROCEDURE%20dbo.sp_ImportEvents%20%3CBR%20%2F%3E%20%40Events%20NVARCHAR(MAX)%20%3CBR%20%2F%3E%20AS%20%3CBR%20%2F%3E%20BEGIN%20%3CBR%20%2F%3E%20MERGE%20INTO%20dbo.Events%20AS%20A%20%3CBR%20%2F%3E%20USING%20(%20%3CBR%20%2F%3E%20SELECT%20*%20%3CBR%20%2F%3E%20FROM%20OPENJSON(%40Events)%20WITH%20(EventId%20int%2C%20DeviceId%20int%2C%20Value%20int%2C%20Timestamp%20datetime2(7)))%20B%20%3CBR%20%2F%3E%20ON%20(A.EventId%20%3D%20B.EventId)%20%3CBR%20%2F%3E%20WHEN%20MATCHED%20THEN%20%3CBR%20%2F%3E%20UPDATE%20SET%20A.DeviceId%20%3D%20B.DeviceId%2C%20%3CBR%20%2F%3E%20A.Value%20%3D%20B.Value%2C%20%3CBR%20%2F%3E%20A.Timestamp%20%3D%20B.Timestamp%20%3CBR%20%2F%3E%20WHEN%20NOT%20MATCHED%20THEN%20%3CBR%20%2F%3E%20INSERT%20(EventId%2C%20DeviceId%2C%20Value%2C%20Timestamp)%20%3CBR%20%2F%3E%20VALUES(B.EventId%2C%20B.DeviceId%2C%20B.Value%2C%20B.Timestamp)%3B%20%3CBR%20%2F%3E%20END%20%3CBR%20%2F%3E%20GO%20%3CBR%20%2F%3E%20%3CBR%20%2F%3E%20%3CBR%20%2F%3E%20%3CBR%20%2F%3E%20Events%20are%20provided%20as%20JSON%20array%20(or%20single%20JSON%20object)%20that%20has%20EventId%2C%20DeviceId%2C%20Value%2C%20and%20Timestamp%20properties.%20OPENJSON%20will%20open%20this%20document%20and%20transform%20it%20to%20table%20results.%20Then%20you%20can%20provide%20this%20resultset%20to%20MERGE%20statement%20where%20you%20can%20insert%20new%20row%20or%20update%20existing%20based%20on%20the%20Id%20column.%20%3CBR%20%2F%3E%20%3CBR%20%2F%3E%20Now%20you%20can%20easily%20import%20one%20or%20many%20JSON%20documents%20into%20Event%20table%3A%20%3CBR%20%2F%3E%20EXEC%20sp_ImportEvents%20N'%7B%22EventId%22%3A1%2C%22DeviceId%22%3A17%2C%22Value%22%3A35%2C%22Timestamp%22%3A%222015-10-23%2012%3A45%3A37.1237%22%7D'%20%3CBR%20%2F%3E%20SELECT%20*%20FROM%20Events%20%3CBR%20%2F%3E%20%3CBR%20%2F%3E%20GO%20%3CBR%20%2F%3E%20%3CBR%20%2F%3E%20EXEC%20sp_ImportEvents%20%3CBR%20%2F%3E%20N'%5B%7B%22EventId%22%3A1%2C%22DeviceId%22%3A17%2C%22Value%22%3A37%2C%22Timestamp%22%3A%222015-10-23%2012%3A45%3A37.1237%22%7D%2C%20%3CBR%20%2F%3E%20%7B%22EventId%22%3A2%2C%22DeviceId%22%3A17%2C%22Value%22%3A35%2C%22Timestamp%22%3A%222015-10-23%2012%3A45%3A37.1237%22%7D%5D'%20%3CBR%20%2F%3E%20SELECT%20*%20FROM%20Events%3C%2FLINGO-BODY%3E%3CLINGO-TEASER%20id%3D%22lingo-teaser-384637%22%20slang%3D%22en-US%22%3EFirst%20published%20on%20MSDN%20on%20Mar%2003%2C%202016%20In%20Sql%20Server%202016%20you%20can%20easily%20insert%20or%20update%20JSON%20documents%20by%20combining%20OPENJSON%20and%20MERGE%20statement.%3C%2FLINGO-TEASER%3E%3CLINGO-LABS%20id%3D%22lingo-labs-384637%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3ESQLServerStorageEngine%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E
Version history
Last update:
‎Mar 23 2019 02:18 PM
Updated by: