In SQL Server 2016 will be added a new table value function that can transform JSON text into row(s). In this post I will show how you can directly insert/update table rows using JSON objects.
Our database receives JSON documents from external systems. These JSON documents might be values sent to REST web services, information from sensors, records from log files formatted as JSON, or other system transform information as JSON during data transfer. We need a way to import JSON documents into SQL tables.
OPENJSON table value function transforms JSON object to one or many rows. These rows can be imported into tables or they can be used to update existing records in tables.
Syntax of OPENJSON function that transforms JSON document to rowset looks like:
OPENJSON(<json text>)
WITH ( <<column/mapping definitions>> )
In the WITH clause you can define schema of the returned rows with names of columns and their types. OPENJSON function will parse JSON object, match properties in JSON object with column names and convert their values to specified types. Example of query that opens content of JSON variable is shown in the following listing:
declare @json nvarchar(max) = '{
"id" : 2,
"firstName": "John",
"lastName": "Smith",
"isAlive": true,
"age": 25,
"dateOfBirth": "2015-03-25T12:00:00",
"spouse": null
}';
SELECT *
FROM OPENJSON(@json)
WITH (id int,
firstName nvarchar(50), lastName nvarchar(50),
isAlive bit, age int,
dateOfBirth datetime2, spouse nvarchar(50))
In this example, we have opened json object and mapped fields to columns by name. Result of execution would look like:
id | firstName | lastName | isAlive | age | dateOfBirth | spouse |
2 | John | Smith | 1 | 25 | 2015-03-25T12:00:00 | NULL |
OPENJSON function will also work with JSON arrays. In that case, it will return a multi-row table (each table row will match one JSON object in array) instead of single row table. This function can also open nested/hierarchical JSON object (I will describe this in a separate post). In this post you will see how easily you can insert and update tables using JSON objects.
Now, when we have opened JSON we can do anything. As an example, we can use OPENJSON function to directly load JSON object into a table:
declare @json nvarchar(max) = '{
"id" : 2,
"firstName": "John",
"lastName": "Smith",
"isAlive": true,
"age": 25,
"dateOfBirth": "2015-03-25T12:00:00",
"spouse": null
}';
INSERT INTO Person
SELECT *
FROM OPENJSON(@json)
WITH (id int,
firstName nvarchar(50), lastName nvarchar(50),
isAlive bit, age int,
dateOfBirth datetime2, spouse nvarchar(50))
JSON variable will be converted to a row that can be inserted into a table as any other row. You can use this approach to directly load JSON objects received via REST service without need to transform JSON to object model, set values as parameters in SQL command etc. This way, you can directly send single JSON text file and load it into table. If your JSON is valid there is no risk that you will have some SQL injection attack. OPENJSON will not execute any command - it just returns a table row if JSON text is properly formatted.
You can also insert an array of JSON rows because the same code will work. OPENJSON will just return set of rows instead of single row that should be inserted.
We can easily update any table based on JSON text. You just need to pass entire JSON object, open it using OPENJSON function and update table row as shown in the following example:
declare @json nvarchar(max) = N'{
"id" : 2,
"firstName": "George",
"lastName": "Smith",
"isAlive": true,
"age": 31,
"dateOfBirth": "2015-03-25T12:00:00",
"spouse": "Marry"
}';
UPDATE Person
SET firstName = json.firstname,
lastName = json.lastname,
isAlive = json.isAlive,
age = json.age,
dateOfBirth = json.dateOfBirth,
spouse = json.spouse
FROM OPENJSON(@json)
WITH (id int,
firstName nvarchar(50), lastName nvarchar(50),
isAlive bit, age int,
dateOfBirth datetime2, spouse nvarchar(50)) AS json
WHERE Person.id = json.id
In this example we have opened JSON variable and updated columns in the Person table. We have used id field from the opened JSON to match the row that should be updated, while the other fields are used to update Person row.
I don't believe that you will send JSON object if you want to delete it (probably you will directly send id of table row). However, even if you decide to use this approach, you can delete row in the table using following example:
DELETE Person
WHERE id = CAST(JSON_VALUE(@json, '$.id') AS int)
JSON_VALUE function will take id on the path $.id and row in the table will be deleted. You can use OPENJSON instead of JSON_VALUE, but this is simpler approach.
OPENJSON function will help you to easily parse, open and transform JSON object to table rows. Using OPENJSON you can easily insert or update table rows using JSON text.
You don't need to parse JSON in application layer, you don't need to pass properties as SQL parameters, there is no risk of SQL injection attacks if you have valid JSON.
This is probably easiest and most secure method to import your JSON documents in Sql Server.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.