0% found this document useful (0 votes)
143 views

Convert SQL Server Results Into JSON

Uploaded by

luca pilotti
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
143 views

Convert SQL Server Results Into JSON

Uploaded by

luca pilotti
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 1

SQLShack SQL Server training Español 

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

SQL Server to JSON Supported Data Types


Like many of the features in SQL Server, there are terms and conditions to using them and JSON is no different.
Thus, it is important that we take note of the supported data types. SQL Server data stored in the following data
types cannot be converted into JSON:
Popular
Geometry
What is the difference between Clustered and Non-
Clustered Indexes in SQL Server?
Geography Multiple options to transposing rows into columns

How to copy tables from one database to another in


Common Language Runtime (CLR) SQL Server

All about locking in SQL Server


A breakdown of supported data types is shown in Table1   Step by step installation of SQL Server 2017

SQL replace: How to replace ASCII special characters


in SQL Server
SQL Server Data Type JSON Data Type
How to implement array-like functionality in SQL
char, nchar, varchar, nvarchar, date, datetime, datetime2, time, datetimeoffset, string Server
uniqueidentifier, money Using the SQL Coalesce function in SQL Server

How to install SQL Server 2014 Management Studio


int, bigint, float, decimal, numeric number
Multiple methods for scheduling a SQL Server
Bit Boolean backup automatically

When to Use Temporary Tables vs. Table Variables


varbinary, binary, image, timestamp, rowversion BASE64-encoded string
How to create and configure a linked server in SQL
Server Management Studio
Table 1 Techniques to bulk copy, import and export in SQL
Server

FOR JSON T-SQL Clause


How to implement error handling in SQL Server

Working with the SQL Server command line (sqlcmd)

How to move SQL database files (MDF and LDF) to


Although SQL Server’s support for XML allowed for graphical representation of the data via an editor (shown in another location
Figure 1), attempting to view JSON data via an editor may be frustrating as JSON data is shown as an
Six different methods to copy tables between
unformatted single row. databases in SQL Server

Setting up the dark theme in SQL Server


management studio

The Difference between CROSS APPLY and OUTER


APPLY in SQL Server

How to identify slow running queries in SQL Server

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

How to use SQL Server built-in functions and create


user-defined scalar functions
SELECT
sales.[Item Nr],sales.[Transaction Date],sales.[Fruit],sales.[Quantity] Database table partitioning in SQL Server
,sales.[Customer],sales.[MOP],sales.[Account Number]
FROM [selectSIFISOBlogs].[DIM].[FruitSales] sales Overview of the SQL ROW_NUMBER function
FOR JSON AUTO
Debugging stored procedures in SQL Server
Management Studio (SSMS)

SQL Convert Date functions and formats


Figure 4
Top 10 questions and answers about SQL Server
Indexes
The results of the above scripts are shown in below in which a single array (represented by square bracket)
SQL Server replication: Overview of components and
was returned with rows held as objects (represented by curly braces). topography

SQL Substring function overview

How to connect and use Microsoft SQL Server


Express LocalDB

How to drop a SQL Server Login and all its


dependencies

Various techniques to audit SQL Server databases

Functions vs stored procedures in SQL Server

How to install Microsoft SQL Server Express LocalDB

How to connect to a remote SQL Server

6 methods to write PowerShell output to a SQL


Server table

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

SQL Server database auditing techniques

How to recover SQL Server data from accidental


UPDATE and DELETE operations

How to quickly search for SQL database data and


objects

Synchronize SQL Server databases in different


remote sources

Recover SQL data from a dropped table without


backups

How to restore specific table(s) from a SQL Server


database backup

Recover deleted SQL data from transaction logs

How to recover SQL Server data from accidental


updates without backups
Figure 7 Automatically compare and synchronize SQL Server
data

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

How to recover a single table from a SQL Server


database backup
SELECT
cust.[Name],sales.[Item Nr],sales.[Transaction Date],sales.[Fruit]
Recover data lost due to a TRUNCATE operation
,sales.[Quantity],sales.[Customer],sales.[MOP],sales.[Account Number] ,cust.[DOB],cust. without backups
[Gender]
How to recover SQL Server data from accidental
FROM [selectSIFISOBlogs].[DIM].[FruitSales] sales
LEFT JOIN [selectSIFISOBlogs].[DIM].[Customer] cust DELETE, TRUNCATE and DROP operations
ON sales.[Customer] = cust.[Customer]
Reverting your SQL Server database back to a
FOR JSON AUTO
specific point in time

How to create SSIS package documentation


Figure 8 Migrate a SQL Server database to a newer version of
SQL Server

How to restore a SQL Server database backup to an


older version of SQL Server

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.

2. Convert Results Using PATH Mode


The PATH mode can be used in two ways:

a. Without a dot syntax

b. With a dot syntax Categories and tips


► Auditing and compliance (43)
When you are using it without a dot syntax, it works similar to the AUTO mode in that it will generate a
Azure (17)
JSON output based on the ordering of columns in your SELECT statement.
Azure Data Studio (19)

Backup and restore (83)


SELECT
sales.[Item Nr],sales.[Transaction Date],sales.[Fruit],sales.[Quantity] ► Business Intelligence (358)
,sales.[Customer],sales.[MOP],sales.[Account Number],cust.[Name]
,cust.[DOB],cust.[Gender] Data science (15)
FROM [selectSIFISOBlogs].[DIM].[FruitSales] sales
LEFT JOIN [selectSIFISOBlogs].[DIM].[Customer] cust ► Database design (190)
ON sales.[Customer] = cust.[Customer]
FOR JSON PATH
► Database development (264)
DBAtools (16)

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)

Installation, setup and configuration (78)

Jobs (23)

▼ Languages and coding (497)


Cursors (8)

DDL (7)

DML (3)

JSON (9)

PowerShell (62)

Python (18)

R (9)

SQL commands (140)

SQLCMD (4)

String functions (19)


Figure 11
T-SQL (207)

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)

and Cust. Machine learning (5)

Maintenance (73)

SELECT Migration (34)


sales.[Item Nr] AS [Sales.Item Nr]
► Performance tuning (604)
,sales.[Transaction Date] AS [Sales.Transaction Date]
,sales.[Fruit] AS [Sales.Fruit],sales.[Quantity] AS [Sales.Quantity] ► Professional development (31)
,sales.[Customer] AS [Sales.Customer],sales.[MOP] AS [Sales.MOP]
,sales.[Account Number] AS [Sales.Account Number],cust.[Name] AS [Cust.Name] Recovery (27)
,cust.[DOB] AS [Cust.DOB],cust.[Gender] AS [Cust.Gender]
FROM [selectSIFISOBlogs].[DIM].[FruitSales] sales Security (75)
LEFT JOIN [selectSIFISOBlogs].[DIM].[Customer] cust
ON sales.[Customer] = cust.[Customer] Server management (10)
FOR JSON PATH
SQL Azure (130)

SQL Server Management Studio (SSMS) (73)

Figure 12 ► SQL Server versions (140)


► Technologies (121)
The execution results of Figure 12 are shown below.
Uncategorized (2)

Utilities (11)

 Helpers and best practices


BI performance counters

SQL code smells rules

SQL Server wait types

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

Options FOR JSON Clause


Both AUTO and PATH modes allow you to specify additional options such as ROOT,
INCLUDE_NULL_VALUES and WITHOUT_ARRAY_WRAPPER.

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

The results of the above scripts are shown below.

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

An introduction to ApexSQL Search

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.

He currently works for Sambe Consulting as a Principal Consultant.

View all posts by Sifiso W. Ndlovu

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

ALSO ON SQL SHACK

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 …

12 Comments SQL Shack 🔒 Disqus' Privacy Policy 


1 Login

 Recommend 8 t Tweet f Share Sort by Best

Join the discussion…

LOG IN WITH
OR SIGN UP WITH DISQUS ?

Name

Andreas S • 3 years ago • edited


Very good introduction into "sql and json".
So, I have a question.
Lets assume, I have 3 Tables to join:

SELECT *
FROM A
LEFT JOIN Aa ON Aa.ID = A.ID
LEFT JOIN Ab ON Ab.ID = A.ID
FOR JSON Auto

The Result is like this


[{
ID: 1234
Aa: {
ID: 4321
Ab: {
ID: 6789
}
}
}]

Why is Ab nested in Aa? Is it possible to put Ab in node A? Like Aa is?


Thank you.
Without subselects, please
6△ ▽ • Reply • Share ›

Sifiso Ndlovu > Andreas S • 3 years ago


Ab is nested in Aa because you are using FOR JSON AUTO clause. Switch to FOR JSON PATH clause
instead
6△ ▽ • Reply • Share ›

Sifiso Ndlovu > Andreas S • 3 years ago


thanks for the response @Andreas S let me work on a scenario/t-sql code for you and I will get back to
you
5△ ▽ • Reply • Share ›

Kris Clegg • 2 months ago • edited


Thank you so much for this summary. Much easier to comprehend than MSFT's documentation of these
functions.

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 ›

Sifiso Ndlovu > Kris Clegg • 2 months ago


are you able to give me an example of what you mean? you should be able to combine numeric data
using T-SQL and then later convert the combined output to a JSON format. Are you able to send me an
example?
△ ▽ • Reply • Share ›

Kris Clegg > Sifiso Ndlovu • 2 months ago


Thanks for the quick response Sifiso! I think I figured it out after much time on Stack Overflow:
Use JSON_QUERY() to wrap the JSON data's column in the SELECT statement and then you
can effectively merge numeric data and JSON-formatted strings into a unified output!
△ ▽ • Reply • Share ›

Eric A. O. • 8 months ago


Thanks for the nice article, do you have any examples on how to generate json for each table in a database?
1△ ▽ • Reply • Share ›

Sifiso Ndlovu > Eric A. O. • 2 months ago


my pleasure and thanks for feedback
△ ▽ • Reply • Share ›

Gabe • a year ago


Thank you! This really saved me a lot of time and effort doing some non-trivial object-relational mapping with
Dapper.
1△ ▽ • Reply • Share ›

Sifiso Ndlovu > Gabe • a year ago


thanks for your feedback Gabe
△ ▽ • Reply • Share ›

Savineers T • a year ago


Nice article this is exactly what I need for my Project. Thank you!
1△ ▽ • Reply • Share ›

Sifiso Ndlovu > Savineers T • a year ago


my pleasure
△ ▽ • Reply • Share ›

✉ Subscribe d Add Disqus to your siteAdd DisqusAdd ⚠ Do Not Sell My Data

© 2020 Quest Software Inc. ALL RIGHTS RESERVED.   |   GDPR   |   Terms of Use   |   Privacy

You might also like