In this article, we will explore JSON_VALUE() function in SQL Server to extract scalar values from JSON data.
Introduction to JSON
JSON is an acronym for “JavaScript Object Notation”. It is a lightweight data exchange language. If you are familiar with XML, it is a bit hard to understand. You can easily interpret JSON formatted data using its key-value pair.
JSON is a popular language and many NoSQL databases such a Couchbase, AWS DynamoDB. It is popular in modern web and mobile applications.
SQL Server 2016 and later supports JSON format data. You should know JSON format and work with JSON data in SQL Server. It also creates a bridge between a relational database and NoSQL systems.
SQL Server provides various built-in-functions to parse, read, transform, and convert JSON objects. You can also format the T-SQL results in the JSON format. You can go through article category k in SQLShack to understand more details about it.
You can refer to the following image from Microsoft docs to understand the interoperability between SQL table and JSON.
We have the following JSON functions in SQL Server:
- ISJSON(): It checks whether we have a valid JSON or not
- JSON_VALUE(): We can extract a scalar value from the JSON string. We will explore this function in detail in this article
- JSON_QUERY: We can extract an array or string from the JSON_QUERY() output
- JSON_MODIFY(): We can modify a value in the JSON Data using this JSON-MODIFY() function
Syntax of JSON_VALUE()
JSON_VALUE ( expression ,[Path Mode] JSON_path )
- Expression: It is a variable or column containing a JSON string. It should be a valid expression, and else it returns an error
- JSON_Path: It is the location of a scalar value in the JSON string
- Path mode: It is an optional argument. We can specify the lax or strict value in this mode. It uses LAX as a default path mode. We will understand it using examples
Let’s understand the JSON_VALUE() function using various examples.
Example 1: Search a key value from JSON string
In the query below, we defined a JSON expression and path.
- It has a JSON expression defined as a key (Name) and its value (“Rajendra”)
-
It specifies $.Name argument as JSON path. This path should reference the key in the JSON expression
1SELECT JSON_VALUE('{"Name": "Rajendra"}', '$.Name') AS 'Output';
We cannot use a space character in the JSON key. For example, if we run the following code for a key (First Name) and want to retrieve a value for it, it gives us inappropriate format error.
1 |
SELECT JSON_VALUE('{"First Name": "Rajendra"}', '$.First Name') AS 'Output'; |
In the below query, the JSON path does not contain an argument value that does not refer to the JSON string. Here, the JSON string does not have the first name key, therefore so we get NULL value in the output using default path mode.
1 |
SELECT JSON_VALUE('{"Name": "Rajendra"}', '$.FirstName') AS 'Output'; |
Example 2: Default LAX path mode in JSON Data
As we specified earlier, JSON_VALUE() function uses LAX as the default mode. We can specify it explicitly as well, and it returns a similar output as shown below.
Example 3: Strict path mode in JSON
Let’s change the mode to Strict, and it gives you an error message in case the key does not exist.
1 |
SELECT JSON_VALUE('{"Name": "Rajendra"}', 'strict$.FirstName') AS 'Output'; |
Now, let’s change the correct key from the JSON string, and we get output in the Strict path.
You should take a note that it is a case sensitive operation; if we specify the path mode to Strict, it gives the following error.
Similarly, you get an error if you use a capital letter in LAX mode, it also gives the error message.
Example 4: Use an Array in JSON data with JSON_VALUE() function
We can use an array to store multiple values. It uses square brackets ([]) to define the array. In the below code, we have an array for Employees records and puts JSON into a variable called @data.
The first record in JSON is always index as zero. For example, in the array, we get the first record by specifying index position zero.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
DECLARE @data NVARCHAR(4000); SET @data = N'{ "Employees": [ { "EmpName": "Rohan Sharma", "Department": "IT", "Address": "101, Sector 5, Gurugram, India", "Salary": 100000 }, { "EmpName": "Manohar Lal", "Department": "Human Resources", "Address": "17, Park Avenue, Mumbai, India", "Salary": 78000 } ] }'; SELECT JSON_VALUE(@data, '$.Employees[0].EmpName') AS 'Name', JSON_VALUE(@data, '$.Employees[0].Department') AS 'Department', JSON_VALUE(@data, '$.Employees[0].Address') AS 'Address', JSON_VALUE(@data, '$.Employees[0].Salary') AS 'Salary'; |
It returns the output of the first employee data.
We can use SQL UNION ALL operator to retrieve both records and display them in a tabular format.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
DECLARE @data NVARCHAR(4000); SET @data = N'{ "Employees": [ { "EmpName": "Rohan Sharma", "Department": "IT", "Address": "101, Sector 5, Gurugram, India", "Salary": 100000 }, { "EmpName": "Manohar Lal", "Department": "Human Resources", "Address": "17, Park Avenue, Mumbai, India", "Salary": 78000 } ] }'; SELECT JSON_VALUE(@data, '$.Employees[0].EmpName') AS 'Name', JSON_VALUE(@data, '$.Employees[0].Department') AS 'Department', JSON_VALUE(@data, '$.Employees[0].Address') AS 'Address', JSON_VALUE(@data, '$.Employees[0].Salary') AS 'Salary' UNION ALL SELECT JSON_VALUE(@data, '$.Employees[1].EmpName') AS 'Name', JSON_VALUE(@data, '$.Employees[1].Department') AS 'Department', JSON_VALUE(@data, '$.Employees[1].Address') AS 'Address', JSON_VALUE(@data, '$.Employees[1].Salary') AS 'Salary' |
We get the following output from the JSON_VALUE() function in an array.
Similarly, look at the following example. It holds an array for favorite subjects of a student in the info JSON key. We require to retrieve student name and his second favorite subject listed in an array.
We can use the following code with the JSON_Value function.
-
Retrieve the student name using the JSON_VALUE function, as shown below. We specify the JSON key (info) and specify the item name you need the data
1SELECT JSON_VALUE(@data, '$.info.Name') AS 'Name', -
For the second favorite subject, we specify the array element position. As you know, in an array first item starts with zero index and we use [1] for the second element
1234567891011121314151617JSON_VALUE(@data, '$.info.Favorite_Subject[1]') AS 'Favorite Subject';DECLARE @data NVARCHAR(MAX);SET @data = N'{"info":{"ID":1,"Name":"Akshat","address":{"City":"Gurgaon","Country":"India"},"Favorite_Subject":["English", "Science"]},"type":"student"}';SELECT JSON_VALUE(@data, '$.info.Name') AS 'Name',JSON_VALUE(@data, '$.info.Favorite_Subject[1]') AS 'Favorite Subject';
It gives you the desired output, as shown below.
As specified earlier, we can get a scalar value from JSON data using the JSON_VALUE() function. In the above example, if we try to retrieve a complete array, it returns a NULL value in the output using the default lax path mode.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
DECLARE @data NVARCHAR(MAX); SET @data = N'{ "info":{ "ID":1, "Name":"Akshat", "address":{ "City":"Gurgaon", "Country":"India" }, "Favorite_Subject":["English", "Science"] }, "type":"student" }'; SELECT JSON_VALUE(@data, '$.info.Name') AS 'Name', JSON_VALUE(@data, '$.info.Favorite_Subject') AS 'Favorite Subject'; |
We do not want NULL value in the output. It gives an assumption that the specified key does not exist in JSON expression. We should use a strict path mode to get the exact error message.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
DECLARE @data NVARCHAR(MAX); SET @data = N'{ "info":{ "ID":1, "Name":"Akshat", "address":{ "City":"Gurgaon", "Country":"India" }, "Favorite_Subject":["English", "Science"] }, "type":"student" }'; SELECT JSON_VALUE(@data, '$.info.Name') AS 'Name', JSON_VALUE(@data, 'strict$.info.Favorite_Subject') AS 'Favorite Subject'; |
You get an error in the strict mode because it could not retrieve the array from the JSON data.
Example 5: Retrieve value from a nested JSON key data
In the below code, we have an address key that contains further nested elements. For example, address contains values for different keys FlatNo, Locality, and City.
Now, we want to retrieve a specific subkey from the Address JSON key. For example, we require City from the Address key. For this requirement, we need to specify the key order in the following format.
1 |
JSON_VALUE(@data, '$.Employees[0].Address.City') |
- $.Employee[0] refers to the first record in the array
-
The address is the first key in Employees, and City is the second key, so the complete expression is Employees[0].Address.City
1234567891011121314DECLARE @data NVARCHAR(4000);SET @data = N'{"Employees": [{"EmpName": "Rohan Sharma","Department": "IT","Address": {"FlatNo":101,"Locality":"Sector 5", "City":"Gurugram", "Country:"India","Salary": 100000},]}';SELECT JSON_VALUE(@data, '$.Employees[0].EmpName') AS 'Name',JSON_VALUE(@data, '$.Employees[0].Address.City') AS 'City';
It fetches the information from the JSON data and gives you an appropriate output.
Conclusion
In this article, we explored the useful JSON_VALUE() function to retrieve a scalar value from the JSON data using various examples. It also demonstrated the difference in lax and strict path modes available with this function. You should explore JSON and process it to handle it with SQL Server.
- Understanding PostgreSQL SUBSTRING function - September 21, 2024
- How to install PostgreSQL on Ubuntu - July 13, 2023
- How to use the CROSSTAB function in PostgreSQL - February 17, 2023