Convert SQL Server Results Into JSON
Convert SQL Server Results Into JSON
Newsletter
Convert SQL Server results into JSON
July 12, 2016 by Sifiso W. Ndlovu Enter your email
Subscribe
Follow us!
In my article, Warehousing JSON Formatted Data in SQL Server 2016, we had a look at available T-SQL options for
converting JSON data into rows and columns for the purposes of populating a SQL Server based data
warehouse. The increased popularity of JSON in modern web applications may create a requirement for data
teams to expose some of their data to client applications (i.e. reporting tools, web services etc.) in a JSON format.
In this article we take a look at how such a requirement can be implemented by data teams using SQL Server
2016 FOR JSON clause
Figure 1
Figure 2
It is therefore advisable that whilst you teach yourself JSON in SQL Server that you find yourself a JSON editor.
For the purposes of this discussion, I will be using JSONFormatter from curiousconcept.com. As can be seen in
Figure 3, the JSON output from Figure 2 is now properly formatted.
Figure3
There are two ways that relational results can be converted into JSON, namely, the AUTO and PATH options.
Trending
1. Convert Results Using AUTO Mode SQL Server table hints – WITH (NOLOCK) best
practices
This is the simplest way to convert relational data into a JSON format as all that you have to do is to add Overview of the SQL REPLACE function
FOR JSON AUTO clause at the end of your SELECT statement. In this mode, the structure of the JSON Understanding the GUID data type in SQL Server
output is determined by a combination of the order of columns in your SELECT statement as well as the Query optimization techniques in SQL Server: tips
tables that are referenced by the SELECT statement. Figure 4 shows a T-SQL statement that converts the and tricks
results from our fictitious Fruit Sales data mart into JSON. CASE statement in SQL
Figure 5
The sample script provided in Figure 4 does not fully demonstrate the role of column and table ordering in
FOR JSON AUTO clause as only a single table was used. Figure 6 shows the revised script with a join to
another fictitious customer lookup dimension that stores additional information regarding customers that
have purchased fruits.
SELECT
sales.[Item Nr],sales.[Transaction Date],sales.[Fruit],sales.[Quantity]
,sales.[Customer],sales.[MOP],sales.[Account Number],cust.[Name]
,cust.[DOB],cust.[Gender]
FROM [selectSIFISOBlogs].[DIM].[FruitSales] sales
LEFT JOIN [selectSIFISOBlogs].[DIM].[Customer] cust
ON sales.[Customer] = cust.[Customer]
FOR JSON AUTO
Figure 6
The execution of the above script results into an output that is shown in Figure 7. You will now notice that
another child array (with its own objects) labelled cust appears in the output. The child array represents the
information retrieved from the customer dimension.
Solutions
Read a SQL Server transaction log
However, when we change the column order of the SELECT statement such that it begins with a column Open LDF file and view LDF file content
from the customer dimension as shown in Figure 8, we get a different output than the one in Figure 7 in Quickly convert SQL code to language-specific client
that the child array is now based off the FruitSales dimension. code
Figure 9
Therefore, although using the AUTO mode is convenient, it often returns an inconsistent output whose
ordering is subject to change based on the column ordering in the SELECT statement. To ensure that your
JSON results are consistent, you will have to make use of the PATH mode.
DevOps (21)
Figure 10
DevSecOps (2)
Documentation (17)
However, as it can be seen in Figure 11, the PATH mode doesn’t automatically group information from
joined tables into child arrays. In fact, all columns from the two tables are shown in the same root level. ETL (48)
► Features (180)
Importing, exporting (39)
Jobs (23)
DDL (7)
DML (3)
JSON (9)
PowerShell (62)
Python (18)
R (9)
SQLCMD (4)
XML (11)
To organise the JSON output into child arrays, you will have to use the dot syntax as shown in Figure 12.
The label before the dot represents the name of the object – in this case we have two objects named Sales Lists (14)
Maintenance (73)
Utilities (11)
Figure 13
You can still organise your JSON PATH output into child arrays by converting your script into a nested join
as shown in Figure 14.
SELECT
(
SELECT cust.[Name],cust.[DOB],cust.[Gender]
FROM [selectSIFISOBlogs].[DIM].[Customer] cust
WHERE cust.[Customer] = sales.[Customer]
FOR JSON PATH
) cust
,sales.[Item Nr],sales.[Transaction Date],sales.[Fruit],sales.[Quantity]
,sales.[Customer],sales.[MOP],sales.[Account Number]
FROM [selectSIFISOBlogs].[DIM].[FruitSales] sales
FOR JSON PATH
Figure 14
Figure 15
1. ROOT
The ROOT option is used assign a label to the top-level array. Figure 16 shows the application of the
ROOT option.
SELECT
sales.[Item Nr] AS [Sales.Item Nr],sales.[Transaction Date] AS [Sales.Transaction
Date]
,sales.[Fruit] AS [Sales.Fruit],sales.[Quantity] AS [Sales.Quantity]
,sales.[Customer] AS [Sales.Customer],sales.[MOP] AS [Sales.MOP]
,sales.[Account Number] AS [Sales.Account Number],cust.[Name] AS [Cust.Name]
,cust.[DOB] AS [Cust.DOB],cust.[Gender] AS [Cust.Gender]
FROM [selectSIFISOBlogs].[DIM].[FruitSales] sales
LEFT JOIN [selectSIFISOBlogs].[DIM].[Customer] cust
ON sales.[Customer] = cust.[Customer]
FOR JSON PATH, ROOT ('TOP_LEVEL')
Figure 16
As it can be seen in Figure 17, our main array is now titled TOP_LEVEL.
Figure 17
2. INCLUDE_NULL_VALUES
The default behaviour when using FOR JSON clause is that NULL values will not be included in your
JSON output. This can be overridden by specifying the INCLUDE_NULL_VALUES option. To illustrate
this point I have added a dummy fruit transaction in my SELECT statement as shown in Figure 18. You
will notice that the last four values in my dummy transaction are NULL.
SELECT
sales.[Item Nr],sales.[Transaction Date],sales.[Fruit],sales.[Quantity]
,sales.[Customer],sales.[MOP],sales.[Account Number]
FROM [selectSIFISOBlogs].[DIM].[FruitSales] sales
UNION
SELECT 12,20990101,'Dummy Fruit',NULL,NULL,NULL,NULL
FOR JSON AUTO
Figure 18
The output of this statement is shown in Figure 19 in which the last 4 values that were NULL are not
included in the JSON output.
Figure 19
To override this behaviour, you just need to include INCLUDE_NULL_VALUES option as shown in
Figure 20.
SELECT
sales.[Item Nr],sales.[Transaction Date],sales.[Fruit],sales.[Quantity]
,sales.[Customer],sales.[MOP],sales.[Account Number]
FROM [selectSIFISOBlogs].[DIM].[FruitSales] sales
UNION
SELECT 12,20990101,'Dummy Fruit',NULL,NULL,NULL,NULL
FOR JSON AUTO, INCLUDE_NULL_VALUES
Figure 20
As it can now be seen in Figure 21, after including the INCLUDE_NULL_VALUES option, our JSON
output includes NULL values.
Figure 21
3. WITHOUT_ARRAY_WRAPPER
By default every FOR JSON clause returns JSON data wrapped around square brackets – also known
as, an array. There are instances whereby you want the square brackets excluded from the output
because you may want to concatenate two or more JSON data. Figure 22 shows the application of
the WITHOUT_ARRAY_WRAPPER option.
SELECT
sales.[Item Nr],sales.[Transaction Date],sales.[Fruit],sales.[Quantity]
,sales.[Customer],sales.[MOP],sales.[Account Number]
FROM [selectSIFISOBlogs].[DIM].[FruitSales] sales
FOR JSON AUTO, WITHOUT_ARRAY_WRAPPER
Figure 22
Figure 23
Finally, you would have noticed in Figure 22 that I used a TOP clause to limit my selection into a single row.
This is because when you use the WITHOUT_ARRAY_WRAPPER option against a dataset that has more than
one row, you will run into JSON validation error (shown in below) caused by the missing square brackets.
Thus, be careful in the way you use the WITHOUT_ARRAY_WRAPPER option as it may lead to unintended
validation errors.
Figure 24
Downloads
Sample selectSIFISOBlogs database
Reference
INCLUDE_NULL_VALUES Option
JSON Data in SQL Server 2016
WITHOUT_ARRAY_WRAPPER
See more
To boost SQL coding productivity, check out these free SQL tools for SSMS and Visual Studio including T-
SQL formatting, refactoring, auto-complete, text and data search, snippets and auto-replacements, SQL
code and object comparison, multi-db script comparison, object decryption and more
Sifiso W. Ndlovu
Sifiso is a Johannesburg based certified professional within a wide range of
Microsoft Technology Competencies such SQL Server and Visual Studio Application
Lifecycle Management.
He is the member of the Johannesburg SQL User Group and also hold a Master’s Degree in
MCom IT Management from the University of Johannesburg.
Related Posts:
1. How to import/export JSON data using SQL Server 2016
2. Import JSON data into SQL Server
3. Illustration of an example availability monitoring service Using PowerShell and SQL
4. Top SQL Server Books
5. Native JSON Support in SQL Server 2016
JSON
70,867 Views
Manage Unicode Import JSON data into Using SSH keys to An overview of the
Characters in Data … SQL Server connect to a remote … column level SQL …
6 months ago • 1 comment 3 months ago • 1 comment 5 months ago • 1 comment 3 months ago • 1 comment
In this article, I’ll provide This article explores the In this article, it will be This article gives an
some useful information to process of JSON data described how to connect to overview of Column level
help you understand how … import in the SQL Server … remote MySQL Server on … SQL Server Encryption …
LOG IN WITH
OR SIGN UP WITH DISQUS ?
Name
SELECT *
FROM A
LEFT JOIN Aa ON Aa.ID = A.ID
LEFT JOIN Ab ON Ab.ID = A.ID
FOR JSON Auto
Do you have any suggestions on how to write the SQL to combine the numeric data in the columns of a table
and and JSON strings in a column of the same table into a single unified JSON output using FOR JSON in SQL
Server?
1△ ▽ • Reply • Share ›
© 2020 Quest Software Inc. ALL RIGHTS RESERVED. | GDPR | Terms of Use | Privacy