How to deal with JSON in SQL Server? – Part 2

In the Part 1, We have gone through how to extract and manipulate JSON string in SQL. In this article, let us see how to format the query result as JSON.

FOR JSON

Used to export SQL table data in JSON format. It take column or alias as a key. It is similar to FOR XML in SQL Server.

  • AUTO – It will create nested JSON sub-array based on the table hierarchy used in the query. It is most commonly used.
  • PATH – It defines the required JSON structure using the column name or alias. It is used to control how JSON data is generated or nested.
SELECT <COL_NAME> .. 
FROM <TABLE>
FOR JSON AUTO| PATH

Let us create a table with some data to see how this FOR JSON function works.

CREATE TABLE [dbo].[Addresses](

[Id] [int] IDENTITY(1,1) NOT NULL,
[CustomerId] [int] NULL,
[Address] [varchar](250) NULL,
[City] [varchar](50) NULL,
[Country] [varchar](50) NULL,
CONSTRAINT [PK_Addresses] PRIMARY KEY CLUSTERED
(
[Id] ASC
))

CREATE TABLE [dbo].[Customer](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Code] [varchar](50) NULL,
[FirstName] [varchar](50) NULL,
[LastName] [varchar](50) NULL,
CONSTRAINT [PK_Customer] PRIMARY KEY CLUSTERED
(
[Id] ASC
))

GO
SET IDENTITY_INSERT [dbo].[Addresses] ON

GO
INSERT [dbo].[Addresses] ([Id], [CustomerId], [Address], [City], [Country]) VALUES (1, 1, N'XXXX', N'Oxford', N'UK')
GO
INSERT [dbo].[Addresses] ([Id], [CustomerId], [Address], [City], [Country]) VALUES (2, 1, N'YYYY', N'London', N'UK')
GO
INSERT [dbo].[Addresses] ([Id], [CustomerId], [Address], [City], [Country]) VALUES (3, 2, N'ZZZZ', N'Birmingham', N'UK')
GO
INSERT [dbo].[Addresses] ([Id], [CustomerId], [Address], [City], [Country]) VALUES (4, 2, N'XYXY', N'Chennai', N'India')
GO
SET IDENTITY_INSERT [dbo].[Addresses] OFF
GO
SET IDENTITY_INSERT [dbo].[Customer] ON

GO
INSERT [dbo].[Customer] ([Id], [Code], [FirstName], [LastName]) VALUES (1, N'ABCD', N'Kumar', N'Thamilarasan')
GO
INSERT [dbo].[Customer] ([Id], [Code], [FirstName], [LastName]) VALUES (2, N'XYZ', N'Cholan', N'Kumaran')
GO
SET IDENTITY_INSERT [dbo].[Customer] OFF
GO
ALTER TABLE [dbo].[Addresses] WITH CHECK ADD CONSTRAINT [FK_Addresses_Customer] FOREIGN KEY([CustomerId])
REFERENCES [dbo].[Customer] ([Id])
GO
ALTER TABLE [dbo].[Addresses] CHECK CONSTRAINT [FK_Addresses_Customer]
Go

Let use JSON AUTO to display data in JSON format.

SELECT * FROM [dbo].[Customer] c

INNER JOIN [dbo].[Addresses] Addresses ON c.Id = Addresses.CustomerId
WHERE c.Id = 1
FOR JSON AUTO

It will return result as below.

Let’s try with JSON PATH.

SELECT Id, Code, FirstName, LastName,
    (SELECT Id, Address, City, Country
    FROM [dbo].[Addresses] a
    WHERE a.CustomerId = c.Id
    FOR JSON AUTO
    ) as Addresses
FROM [dbo].[Customer] c
WHERE c.Id =1
FOR JSON PATH, ROOT ('Customer');

OPENJSON

A table value function will generate a relational table with its content from the JSON string.

Basically, it will iterate through the JSON object and arrays and generate a row for each element. We can define and generate a table with and without predefined schema.

Without Predefined Schema
DECLARE @JSONData AS NVARCHAR(4000);

SET @JSONData = N'{
"FirstName":"Kumar",
"LastName":"Thamilarasan",
"Code":"ABC123",
"Addresses":[
{ "Address":"XXXX", "City":"Oxford", "Country":"UK"},
{ "Address":"YYYY", "City":"London", "State":"UK"}
]
}';
SELECT * FROM OPENJSON(@JSONData);

With Pre-defined schema
DECLARE @JSONData AS NVARCHAR(4000);

SET @JSONData = N'{
"FirstName":"Kumar",
"LastName":"Thamilarasan",
"Code":"ABC123",
"Addresses":[
{ "Address":"XXXX", "City":"Oxford", "Country":"UK"},
{ "Address":"YYYY", "City":"London", "Country":"UK"}
]
}';


SELECT
FirstName, LastName, Address, City, Country
FROM OPENJSON(@JSONData)
WITH (FirstName VARCHAR(50),
LastName VARCHAR(50),
Code VARCHAR(50),
Addresses NVARCHAR(max) as json
) as B
cross apply openjson (B.Addresses)
with
(
Address VARCHAR(50),
City VARCHAR(50),
Country VARCHAR(50)
);

We can also access child JSON objects using OPENJSON by using CROSS APPLY function. If the column specified with AS JSON , then the type must be NVARCHAR(MAX). Without this option, it will return NULL or if we specify strict option, it will throw an error.

Hope this gives some idea on how to format the query result in JSON.

Happy SQL’ing 🙂

How to deal with JSON in SQL Server? – Part 1

As we might know, JSON (JavaScript Object Notation) is a simple and lightweight key-value pair message exchanging format. Its a very popular format and used in most modern services. SQL Server is also support to work with JSON format.

So, in this article , let us see how to deal with JSON data in SQL Server.

SQL Server provides the capabilities to provide built-in JSON support.

So, in this part, let us see how to extract JSON data and use them in queries.

The following built-in functions help us to achieve parse and manipulate the JSON Data

ISJSON

Checks whether the string contains data in a valid JSON format.

Basically, it returns in int data type. It returns either 0 or 1.

0 – False. Not a valid JSON format.

1 – True. Is a valid JSON format.

For an example,

DECLARE @JSONData AS NVARCHAR(4000)

SET @JSONData = N'{
"Customer":{
"FirstName":"Kumar",
"LastName":"Thamilarasan",
"Code":"ABC123",
"Addresses":[
{ "Address":"XXXX", "City":"Oxford", "Country":"UK"},
{ "Address":"YYYY", "City":"London", "State":"UK"}
]
}
}'
Select ISJSON(@JSONData) as 'Is valid JSON';

JSON_VALUE

It extracts the scalar value from JSON string.

JSON_VALUE(<json_string>, <path>);

First parameter is string in JSON format. Second parameter is a path and it expects in a specific format. For example,

  • $ – Refers to a whole JSON object
  • $.Property1 – Refers to a specific field in an object
  • $.ArrayProperty[1] – Refers to a second element in the array property
  • $.RootProperty.NestedProperty.ArrayProperty[2] – Refer to a nested property in a JSON object.

Based on the above example,

SELECT JSON_VALUE(@JSONData,'$.Customer.FirstName') as 'First Name';

To extract from an array

SELECT JSON_VALUE(@JSONData,'$.Customer.Addresses[0].Address') as 'Address';

If the path is not valid, it returns NULL.

SELECT JSON_VALUE(@JSONData,'$.Customer.Addresses[0].Invalid') as 'Address';

If we want to throw an error, if the path is not valid. Use strict keyword.

SELECT JSON_VALUE(@JSONData,' strict $.Customer.Addresses[0].Invalid') as 'Address';

JSON_QUERY

It extracts an object or array of objects from the JSON string.

JSON_QUERY ( expression [ , path ] )
  • expression – Name of the variable or column that contains JSON text.
  • path – Specify the path to the object or array to extract.

For example,

To return an array of objects

SELECT JSON_QUERY(@JSONData,'$.Customer.Addresses');

To return an object

SELECT JSON_QUERY(@JSONData,'$.Customer.Addresses[1]');

A note to consider,

If there is a duplicate property at the same level on the JSON data, both JSON_Value and JSON_Query always returns the first one.

For example

DECLARE @JSONData AS NVARCHAR(4000);

SET @JSONData = N'{
"Customer":{
"FirstName":"Kumar",
"LastName":"Thamilarasan",
"FirstName":"Kumaraguru",
"Code":"CCEEDD
}
}'
SELECT JSON_VALUE(@JSONData,'$.Customer.FirstName') as 'First Name';

Now, let us see how we can extract JSON string and manipulate it.

JSON_MODIFY

It returns an updated JSON string in NVARCHAR type.

JSON_MODIFY(<json_string>, <path>, <new_value>)
  • <json_string> – Name of the variable or a table column.
  • <path> – Path of field in a JSON string.
    • <new_value> – Insert/updates with a new value in the specified path.
Updates an existing value

Let us replace the first name of the customer.

SET @JSONData = JSON_MODIFY(@JSONData,'$.Customer.Addresses[0].Address', 'Updated XXXX');
Insert a new value

In the JSON string, if the path is exist, then it will update the attribute specified in the path. If the attribute is not exist, it will insert the new attribute at the end of the string.

In the example, We will insert the new field called MiddleName .

SET @JSONData = JSON_MODIFY(@JSONData,'$.Customer.MiddleName', 'G');

Append a value

In the JSON string, we can append to the existing field using append . In an array field, it will append an item to the end of array items.

SET @JSONData = JSON_MODIFY(@JSONData,'append $.Customer.Addresses', JSON_QUERY('{"Address":"ZZZZ", "City":"Birmingham", "Country":"UK"}','$'));
Update multiple fields

In the JSON string, we can also update multiple fields at once.

For example

Let us modify FirstName and LastName fields.

SET @JSONData = JSON_MODIFY(JSON_MODIFY(@JSONData,'$.Customer.FirstName', 'Cholan'),'$.Customer.LastName','Kumaran');
Delete existing field

In the JSON string, specify the field value to NULL to remove it.

For example

Let us remove the LastName field.

SET @JSONData = JSON_MODIFY(@JSONData,'$.Customer.LastName', NULL);
Rename a field

In the JSON string, rename a field.

For example, let rename the FirstName field to ForeName.


SET @JSONData = JSON_MODIFY(JSON_MODIFY(@JSONData,'$.Customer.ForeName',
   JSON_VALUE(@JSONData,'$.Customer.FirstName')),'$.Customer.FirstName', NULL);

Hope, it makes sense on how to extract and manipulate the JSON string.

Happy SQL`ing 🙂

Serialize JSON data in to Binary Form in C#

Nowadays, data operations such as  data reading and writing are quite common in application development. As increase in no. of clients with different platforms, it consumes different types of data. So, to support interoperability to suit with all clients, we could use binary format/XML format. In Web application development,  sending data in binary format from server to client/ vice versa is a challenge due to its format as it may get blocked by port. XML format is easy to read and textual, simple to transfer across different ports. Though XML is acceptable over binary, it needs encoding when send over HTTP. So, for that it should be escaped/unescaped.  For example,

  •  ‘<‘ should be replaced with ‘&lt’
  • ‘&’ should be replaced with ‘&amp’

So, it costs some extra space (increase in size), when transferring the data over the network.

What is JSON?

JSON is JavaScript Object Notation. It provides human readable format, has got the data in text format, so no need of encoding. So, it is supported by REST services, mobile client applications.

As JSON is not natively supported by .NET programming language, it uses Newton.JSON to use JSON in .NET.

What is BSON?

BSON is Binary JSON. It accepts in  binary format and stores key/value pairs in an entity. An entity is called as documents and it supports all JSON types (object, array, string, integers) and stores binary data directly. It removes the base64 encoded text  overhead that JSON has with binary data. It is faster than JSON when reading/writing data.

In .NET environment, Newton.JSON used to read/write data in binary format. In this article, I have used  NewtonSoft.Json package to serialize/deserialize JSON data. We can install this package using Nuget packages Manager in Visual studio.

Let us see how BSON works with a simple example  in the following.

Csharp_BSON_1

The output are as follows.

Csharp_BSON_2

This is the way we can serialize JSON data in binary format in C#. Hope it helps.

 

Happy C’Sharping 🙂