استفاده از JSON در SQL

استفاده از JSON در SQL

بیشتر اپلیکیشن های تحت وب امکان خروجی JSON را فراهم میکنند. از این خروجی ها میتواند برای تحلیل، گزارشات و .. استفاده نمود. راه های زیادی برای تبدیل اطلاعاتی در قالب JSON به فرمت هایی مانند DataTable در مانهای مختلف مانند سی شارپ وجود داره. اما کاری که ما میخواهیم در مقاله انجام دهیم این است که بتواین دادهای رشته ای در قالب JSON را در SQL به جداولی تبدیل کنیم که براحتی بتوان انواع کوئری های مورد نیاز را بر روی آن اعمال کنیم.

در این مثال فایل داده های ما شامل جزییات سفارشات می باشد. این اطلاعات شامل OrderID,CustometID,OrderStatus می باشد.

Orders JSON File - Description: Orders JSON File

اولین کاری که باید انجام دهیم این است که منبع داده هایی که قرار است در قالب فایل JSON باشد به نحوی مشخص کنیم.

Openrowset تابعی از نوع Table Value است که این کار را برای ما انجام میدهد. این تابع یک table با یک ستون به نام BulkColumn بر میگرداند که شامل محتویات فایل JSON میباشد

دستور زیر فایل JSON را از مسیر E:\Temp\Data\Orders.JSON را لود میکند
SELECT * 
FROM OPENROWSET (BULK 'E:\Temp\Data\Orders.JSON', SINGLE_CLOB) as j

 

Simple method to Query a JSON file - Description: Simple method to Query a JSON file

البته پیشنهاد میشود که حتما محتوای فایل JSON را با استفاده از تابع ISJSON  بررسی کنید تا از JSON بودن آن اطمینان حاصل شود!

Declare @JSON varchar(max)

SELECT @JSON = BulkColumn
FROM OPENROWSET (BULK 'E:\Temp\Data\Orders.JSON', SINGLE_CLOB) as j

Select @JSON

If (ISJSON(@JSON)=1)
Print 'Valid JSON'

 

Store the JSON file content into a variable - Description: Store the JSON file content into a variable

حالا میتوانیم با دستور OpenJSON میتونیم محتوای فایل JSON را به بصورت نتایج رابطه ای Result Relational تبدیل کنیم. تابع OpenJSON به دو صورت می تواند اطلاعات را برگرداند.

حالت اول که حالت پپیشفرض نیز میباشدبصورت کلید/مقدار عمل میکند و به ازای هر المان در فایل JSON یه ستون برمیگرداند. در حالت دوم میتوان صراحتا تعیین کردن کدام المان ها را به عنوان ستون در نظر بگیرد و در خروجی نمایش دهد.

در زیر نمونه ای از حالت پیشفرض استفاده از تابع OpenJSON را میبینیم

Using OpenJSON for JSON file - Description: Using OpenJSON for JSON file

حالا اگر بخواهیم فیلدها را صراحتا بیان کنیم و نوع انها را مشخص نماییم بصورت زیر عمل میکنیم

Declare @JSON varchar(max)

SELECT @JSON = BulkColumn
FROM OPENROWSET (BULK 'E:\Temp\Data\Orders.JSON', SINGLE_CLOB) as j

SELECT * FROM OPENJSON (@JSON) 
WITH(OrderID int,CustomerID int,OrderStatus char(1)) as Orders

Using With Clause in OpenJSON - Description: Using With Clause in OpenJSON

مثال هایی که تا الان ذکر کردیم ساده بودند. حالا بیاید تصور کنیم که فایلی که داریم بصورت تودرتو باشد به این معنی که برخی از المان ها JSON خود دارای ساختاری و الملن های دیگر هستند. برای نمونه این فایل JSON  را دانلود کنید و با استفاده از دستوراتی که یاد گرفتیم آنرا در SQL  لود میکنیم

Declare @JSON varchar(max)

SELECT @JSON = BulkColumn
FROM OPENROWSET (BULK 'E:\Temp\Data\AllState.JSON', SINGLE_CLOB) as j

SELECT * FROM OPENJSON (@JSON)

Using UK Petition JSON file for analysis - Description: Using UK Petition JSON file for analysis

میبینیم که دو المان links  و data که در بالاترین صطح هستند لود شده اند. شما میتواند با پیشوند $ به اطدلاعات سطوح پایینتر فایل نیز دسترسی داشته باشد

برای مثال با دستور زیر شما فقط نود links  را بازیابی میکنید

Declare @JSON varchar(max)

SELECT @JSON = BulkColumn
FROM OPENROWSET (BULK 'E:\Temp\Data\AllState.JSON', SINGLE_CLOB) as j

SELECT * FROM OPENJSON (@JSON,'$.links') 
Go

و با دستور زیر فقط داده ها نود Data

Declare @JSON varchar(max)

SELECT @JSON = BulkColumn
FROM OPENROWSET (BULK 'E:\Temp\Data\AllState.JSON', SINGLE_CLOB) as j

SELECT * FROM OPENJSON (@JSON,'$.data')
Go

Querying the Links element - Description: Querying the Links element

Querying data element - Description: Querying data element

اگر سعی کنیم تا محتوای نود Data را با دستور زیر بازیابی کنیم میبینیم که ستون های لینک و attribute هر دو مقدار NULL گرفته اند

Declare @JSON varchar(max)

SELECT @JSON = BulkColumn
FROM OPENROWSET (BULK 'E:\Temp\Data\AllState.JSON', SINGLE_CLOB) as j

SELECT * FROM OPENJSON (@JSON,'$.data') 
With (type varchar(50),id int, Link varchar(4000),attributes varchar(4000)) as Dataset
Go

Querying the petition details with WITH clause - Description: Querying the petition details with WITH clause

یکباری دیگه به ساختار فایل JSON مثالمون نگاه میکنیم

Petition JSON file - Description: Petition JSON file

المان های links  و attribute هر دو دارای زیرمجموعه می باشند پس به تنهایی مقداری ندارند بلکه باید مقادری زیرمجموعه انها نمایش داده شود. بنابراین از کارکتر جادویی $  برای دسترسی به سطوح پایینتر یکبار دیگه استفاده میکینیم

Declare @JSON varchar(max)

SELECT @JSON = BulkColumn
FROM OPENROWSET (BULK 'E:\Temp\Data\AllState.JSON', SINGLE_CLOB) as j

SELECT * FROM OPENJSON (@JSON,'$.data') 
With (type varchar(50),id int, 
Link varchar(4000) '$.links.self',
action varchar(4000) '$.attributes.action', 
background varchar(4000) '$.attributes.background', 
PetitionStatus varchar(50) '$.attributes.state', 
signature_count int '$.attributes.signature_count', 
CreatedDate varchar(50) '$.attributes.created_at'
) as Dataset
Go

UK petition JSON file has been transformed into relational format - Description: UK petition JSON file has been transformed into relational format

مرتضی جنگجو

برنامه نویس fullstack با بیش از 14 سال سابقه کار و همکاری در توسعه و پیاده سازی نرم افزارهای تحت وب با تکنولوژی Net. در شرکتهای بزرگ ایرانی، هلندی، فنلاندی و ترکیه

شبکه های اجتماعی نویسنده

دیدگاه کاربران