SQL सर्वर में एक टेबल-वैल्यू फ़ंक्शन होता है जिसे OPENJSON()
. कहा जाता है जो JSON डेटा का एक संबंधपरक दृश्य बनाता है।
जब आप इसे कॉल करते हैं, तो आप एक JSON दस्तावेज़ को तर्क के रूप में पास करते हैं, और OPENJSON()
फिर इसे पार्स करता है और JSON दस्तावेज़ की वस्तुओं और गुणों को एक सारणीबद्ध प्रारूप में - पंक्तियों और स्तंभों के रूप में लौटाता है।
उदाहरण
प्रदर्शित करने के लिए यहां एक सरल उदाहरण दिया गया है।
SELECT * FROM OPENJSON('["Cat","Dog","Bird"]');
परिणाम:
+-------+---------+--------+ | key | value | type | |-------+---------+--------| | 0 | Cat | 1 | | 1 | Dog | 1 | | 2 | Bird | 1 | +-------+---------+--------+
डिफ़ॉल्ट रूप से, OPENJSON()
तीन स्तंभों वाली तालिका लौटाता है; कुंजी , मान , और टाइप करें ।
आपके पास अपना स्वयं का स्कीमा निर्दिष्ट करने का विकल्प भी है (जिसका अर्थ है कि आप अपने स्वयं के कॉलम परिभाषित कर सकते हैं)। मेरे सरल उदाहरण में, मैंने डिफ़ॉल्ट स्कीमा का उपयोग किया, और इसलिए तीन डिफ़ॉल्ट कॉलम लौटा दिए गए।
इन स्तंभों को इस प्रकार परिभाषित किया गया है:
कॉलम | <थ>विवरण|
---|---|
कुंजी | में निर्दिष्ट संपत्ति का नाम या निर्दिष्ट सरणी में तत्व की अनुक्रमणिका शामिल है। यह एक nvarchar(4000) . है मान, और स्तंभ में एक BIN2 संयोजन है। |
मान | संपत्ति का मूल्य समाहित करता है। यह एक nvarchar(अधिकतम) . है मान, और कॉलम को प्रदान किए गए JSON से इसके संयोजन को इनहेरिट करता है। |
टाइप करें | में JSON प्रकार का मान होता है। इसे int . के रूप में दर्शाया जाता है मान (0 . से) करने के लिए 5 ) यह कॉलम केवल तभी लौटाया जाता है जब आप डिफ़ॉल्ट स्कीमा का उपयोग करते हैं। |
डिफ़ॉल्ट प्रकार
JSON की दुनिया में, छह डेटा प्रकार हैं। ये हैं स्ट्रिंग , संख्या , सच/गलत (बूलियन), शून्य , ऑब्जेक्ट , और सरणी ।
जब आप कुछ JSON को OPENJSON()
. के माध्यम से पार्स करते हैं डिफ़ॉल्ट स्कीमा का उपयोग करके, OPENJSON()
पता लगाता है कि JSON प्रकार क्या है, और फिर प्रकार . को पॉप्युलेट करता है int . वाला कॉलम मान जो उस प्रकार का प्रतिनिधित्व करता है।
इंट इसलिए मान 0
. से हो सकता है करने के लिए 5
. प्रत्येक int मान एक JSON प्रकार का प्रतिनिधित्व करता है जैसा कि निम्न तालिका में बताया गया है।
“प्रकार” कॉलम में मान | JSON डेटा प्रकार |
---|---|
0 | शून्य |
1 | स्ट्रिंग |
2 | संख्या |
3 | सही/गलत |
4 | सरणी |
5 | वस्तु |
निम्नलिखित उदाहरण इन सभी छह JSON प्रकारों को लौटाता है।
SELECT * FROM OPENJSON('{"name" : null}');
SELECT * FROM OPENJSON('["Cat","Dog","Bird"]');
SELECT * FROM OPENJSON('[1,2,3]');
SELECT * FROM OPENJSON('[true,false]');
SELECT * FROM OPENJSON('{"cats":[{ "id":1, "name":"Fluffy"},{ "id":2, "name":"Scratch"}]}');
SELECT * FROM OPENJSON('[{"A":1,"B":0,"C":1}]');
परिणाम:
+-------+---------+--------+ | key | value | type | |-------+---------+--------| | name | NULL | 0 | +-------+---------+--------+ (1 row affected) +-------+---------+--------+ | key | value | type | |-------+---------+--------| | 0 | Cat | 1 | | 1 | Dog | 1 | | 2 | Bird | 1 | +-------+---------+--------+ (3 rows affected) +-------+---------+--------+ | key | value | type | |-------+---------+--------| | 0 | 1 | 2 | | 1 | 2 | 2 | | 2 | 3 | 2 | +-------+---------+--------+ (3 rows affected) +-------+---------+--------+ | key | value | type | |-------+---------+--------| | 0 | true | 3 | | 1 | false | 3 | +-------+---------+--------+ (2 rows affected) +-------+----------------------------------------------------------+--------+ | key | value | type | |-------+----------------------------------------------------------+--------| | cats | [{ "id":1, "name":"Fluffy"},{ "id":2, "name":"Scratch"}] | 4 | +-------+----------------------------------------------------------+--------+ (1 row affected) +-------+---------------------+--------+ | key | value | type | |-------+---------------------+--------| | 0 | {"A":1,"B":0,"C":1} | 5 | +-------+---------------------+--------+ (1 row affected)
नेस्टेड JSON लौटाएं
आप वैकल्पिक दूसरे तर्क के रूप में किसी नेस्टेड ऑब्जेक्ट या सरणी के पथ को निर्दिष्ट करके वापस कर सकते हैं।
दूसरे शब्दों में, आपको संपूर्ण JSON दस्तावेज़ को पार्स करने की आवश्यकता नहीं है - आप केवल उस भाग को पार्स करना चुन सकते हैं जिसमें आप रुचि रखते हैं।
यहाँ एक उदाहरण है।
DECLARE @json NVARCHAR(4000) = N'{
"pets" : {
"cats" : [
{ "id" : 1, "name" : "Fluffy", "sex" : "Female" },
{ "id" : 2, "name" : "Long Tail", "sex" : "Female" },
{ "id" : 3, "name" : "Scratch", "sex" : "Male" }
],
"dogs" : [
{ "name" : "Fetch", "sex" : "Male" },
{ "name" : "Fluffy", "sex" : "Male" },
{ "name" : "Wag", "sex" : "Female" }
]
}
}';
SELECT * FROM OPENJSON(@json, '$.pets.cats');
परिणाम:
+-------+------------------------------------------------------+--------+ | key | value | type | |-------+------------------------------------------------------+--------| | 0 | { "id" : 1, "name" : "Fluffy", "sex" : "Female" } | 5 | | 1 | { "id" : 2, "name" : "Long Tail", "sex" : "Female" } | 5 | | 2 | { "id" : 3, "name" : "Scratch", "sex" : "Male" } | 5 | +-------+------------------------------------------------------+--------+
इस मामले में, मैंने $.pets.cats
. का पथ निर्दिष्ट किया है , जिसके परिणामस्वरूप केवल बिल्लियों . का मान प्राप्त हुआ वापस किया जा रहा है। बिल्लियों . का महत्व एक सरणी है, इसलिए पूरी सरणी वापस कर दी गई थी।
केवल एक बिल्ली (यानी एक सरणी तत्व) को वापस करने के लिए, हम सरणी मानों को वापस करने के लिए वर्ग ब्रैकेट सिंटैक्स का उपयोग कर सकते हैं (जैसे यह $.pets.cats[1]
)
यहाँ वही उदाहरण दिया गया है जिसे केवल एक सरणी तत्व लौटाने के लिए संशोधित किया गया है:
DECLARE @json NVARCHAR(4000) = N'{
"pets" : {
"cats" : [
{ "id" : 1, "name" : "Fluffy", "sex" : "Female" },
{ "id" : 2, "name" : "Long Tail", "sex" : "Female" },
{ "id" : 3, "name" : "Scratch", "sex" : "Male" }
],
"dogs" : [
{ "name" : "Fetch", "sex" : "Male" },
{ "name" : "Fluffy", "sex" : "Male" },
{ "name" : "Wag", "sex" : "Female" }
]
}
}';
SELECT * FROM OPENJSON(@json, '$.pets.cats[1]');
परिणाम:
+-------+-----------+--------+ | key | value | type | |-------+-----------+--------| | id | 2 | 2 | | name | Long Tail | 1 | | sex | Female | 1 | +-------+-----------+--------+
JSON सरणी अनुक्रमणिका शून्य-आधारित हैं, इसलिए इस उदाहरण ने दूसरा सरणी मान लौटाया (क्योंकि मैंने $.pets.cats[1]
निर्दिष्ट किया था )
अगर मैंने $.pets.cats[0]
. निर्दिष्ट किया होता , पहला मान वापस कर दिया गया होता (अर्थात "शराबी" नाम की बिल्ली)।
स्कीमा परिभाषित करें
जैसा कि बताया गया है, आप अपनी खुद की स्कीमा निर्दिष्ट कर सकते हैं (यानी अपने स्वयं के कॉलम और प्रकार परिभाषित करें)।
ऐसा करने का एक उदाहरण यहां दिया गया है।
DECLARE @json NVARCHAR(4000) = N'{
"pets" : {
"cats" : [
{ "id" : 1, "name" : "Fluffy", "sex" : "Female" },
{ "id" : 2, "name" : "Long Tail", "sex" : "Female" },
{ "id" : 3, "name" : "Scratch", "sex" : "Male" }
],
"dogs" : [
{ "name" : "Fetch", "sex" : "Male" },
{ "name" : "Fluffy", "sex" : "Male" },
{ "name" : "Wag", "sex" : "Female" }
]
}
}';
SELECT * FROM OPENJSON(@json, '$.pets.cats')
WITH (
[Cat Id] int '$.id',
[Cat Name] varchar(60) '$.name',
[Sex] varchar(6) '$.sex',
[Cats] nvarchar(max) '$' AS JSON
);
परिणाम:
+----------+------------+--------+------------------------------------------------------+ | Cat Id | Cat Name | Sex | Cats | |----------+------------+--------+------------------------------------------------------| | 1 | Fluffy | Female | { "id" : 1, "name" : "Fluffy", "sex" : "Female" } | | 2 | Long Tail | Female | { "id" : 2, "name" : "Long Tail", "sex" : "Female" } | | 3 | Scratch | Male | { "id" : 3, "name" : "Scratch", "sex" : "Male" } | +----------+------------+--------+------------------------------------------------------+
हम देख सकते हैं कि कॉलम नाम उन नामों को दर्शाते हैं जिन्हें मैंने WITH
. में निर्दिष्ट किया है खंड। उस खंड में, मैंने प्रत्येक JSON कुंजी को अपने पसंदीदा कॉलम नामों में मैप किया। मैंने SQL सर्वर डेटा प्रकार भी निर्दिष्ट किया है जो मुझे प्रत्येक कॉलम के लिए चाहिए।
मैंने AS JSON
. का भी इस्तेमाल किया उस कॉलम को JSON खंड के रूप में वापस करने के लिए अंतिम कॉलम पर। जब आप AS JSON का उपयोग करते हैं, तो डेटा प्रकार nvarchar(max) . होना चाहिए ।
डेटा प्रकार सत्यापित करें
हम प्रत्येक कॉलम के डेटा प्रकारों को सत्यापित करने के लिए निम्नलिखित क्वेरी का उपयोग कर सकते हैं।
यह क्वेरी sys.dm_exec_describe_first_result_set
. का उपयोग करती है सिस्टम गतिशील प्रबंधन दृश्य, जो किसी क्वेरी से सेट किए गए पहले परिणाम के बारे में मेटाडेटा लौटाता है।
DECLARE @json NVARCHAR(4000) = N'{
"pets" : {
"cats" : [
{ "id" : 1, "name" : "Fluffy", "sex" : "Female" },
{ "id" : 2, "name" : "Long Tail", "sex" : "Female" },
{ "id" : 3, "name" : "Scratch", "sex" : "Male" }
],
"dogs" : [
{ "name" : "Fetch", "sex" : "Male" },
{ "name" : "Fluffy", "sex" : "Male" },
{ "name" : "Wag", "sex" : "Female" }
]
}
}';
SELECT
name,
system_type_name
FROM sys.dm_exec_describe_first_result_set(
'SELECT * FROM OPENJSON(@json, ''$.pets.cats'') WITH (
[Cat Id] int ''$.id'',
[Cat Name] varchar(60) ''$.name'',
[Sex] varchar(6) ''$.sex'',
[Cats] nvarchar(max) ''$'' AS JSON
)',
null,
0
);
परिणाम:
+----------+--------------------+ | name | system_type_name | |----------+--------------------| | Cat Id | int | | Cat Name | varchar(60) | | Sex | varchar(6) | | Cats | nvarchar(max) | +----------+--------------------+
हम देख सकते हैं कि वे मेरे स्कीमा से पूरी तरह मेल खाते हैं।
ध्यान दें कि कुंजी , मान , और टाइप करें जब आप अपनी खुद की स्कीमा परिभाषित करते हैं तो कॉलम उपलब्ध नहीं होते हैं। वे कॉलम केवल डिफ़ॉल्ट स्कीमा का उपयोग करते समय उपलब्ध होते हैं।
पार्स किए गए JSON को टेबल में डालें
अब तक आप सोच रहे होंगे कि हम अपने पार्स किए गए JSON को डेटाबेस तालिका में आसानी से सम्मिलित कर सकते हैं।
और आप सही होंगे।
हमने इसे पहले ही कॉलम और पंक्तियों के साथ तैयार कर लिया है, और हमने कॉलम को नाम भी दिया है और उन्हें डेटा प्रकार दिए हैं।
अब इसे एक टेबल में डालने का समय आ गया है।
DECLARE @json NVARCHAR(4000) = N'{
"pets" : {
"cats" : [
{ "id" : 1, "name" : "Fluffy", "sex" : "Female" },
{ "id" : 2, "name" : "Long Tail", "sex" : "Female" },
{ "id" : 3, "name" : "Scratch", "sex" : "Male" }
],
"dogs" : [
{ "name" : "Fetch", "sex" : "Male" },
{ "name" : "Fluffy", "sex" : "Male" },
{ "name" : "Wag", "sex" : "Female" }
]
}
}';
SELECT * INTO JsonCats
FROM OPENJSON(@json, '$.pets.cats')
WITH (
[Cat Id] int '$.id',
[Cat Name] varchar(60) '$.name',
[Sex] varchar(6) '$.sex',
[Cats] nvarchar(max) '$' AS JSON
);
मैंने केवल INTO JsonCats
जोड़ दिया था मेरी क्वेरी के लिए, JsonCats
. नामक तालिका बनाने के लिए और इसमें क्वेरी के परिणाम डालें।
अब उस तालिका की सामग्री का चयन करें।
SELECT * FROM JsonCats;
परिणाम:
+----------+------------+--------+------------------------------------------------------+ | Cat Id | Cat Name | Sex | Cats | |----------+------------+--------+------------------------------------------------------| | 1 | Fluffy | Female | { "id" : 1, "name" : "Fluffy", "sex" : "Female" } | | 2 | Long Tail | Female | { "id" : 2, "name" : "Long Tail", "sex" : "Female" } | | 3 | Scratch | Male | { "id" : 3, "name" : "Scratch", "sex" : "Male" } | +----------+------------+--------+------------------------------------------------------+
सामग्री ठीक वैसी ही है जैसी हमने उन्हें पहले के उदाहरण में देखी थी।
और पूरी तरह से सुनिश्चित होने के लिए, अब हम sys.column
. का उपयोग कर सकते हैं सिस्टम कैटलॉग व्यू तालिका के कॉलम नामों और प्रकारों की जांच करता है।
SELECT
name AS [Column],
TYPE_NAME(system_type_id) AS [Type],
max_length
FROM sys.columns
WHERE OBJECT_ID('JsonCats') = object_id;
परिणाम:
+----------+----------+--------------+ | Column | Type | max_length | |----------+----------+--------------| | Cat Id | int | 4 | | Cat Name | varchar | 60 | | Sex | varchar | 6 | | Cats | nvarchar | -1 | +----------+----------+--------------+
फिर से, हमने इसे कैसे निर्दिष्ट किया है।
ध्यान दें कि sys.columns
हमेशा एक max_length
देता है का -1
जब कॉलम डेटा प्रकार varchar(max) . हो , nvarchar(अधिकतम) , varbinary(अधिकतम) , या xml . हमने nvarchar(max) . निर्दिष्ट किया है और इसलिए -1
. का मान बिल्कुल अपेक्षित है।
पथ मोड:लैक्स बनाम स्ट्रिक्ट
दूसरे तर्क में या WITH
. में दिया गया पथ क्लॉज (वैकल्पिक रूप से) lax
से शुरू हो सकता है या strict
कीवर्ड।
lax
में मोड,OPENJSON()
यदि निर्दिष्ट पथ पर वस्तु या मान नहीं मिल सकता है तो कोई त्रुटि नहीं होती है। यदि पथ नहीं मिल रहा है,OPENJSON()
या तो एक खाली परिणाम सेट या एकNULL
देता है मूल्य।strict
में मोड,OPENJSON()
पथ नहीं मिलने पर त्रुटि देता है।
डिफ़ॉल्ट मान lax
है , इसलिए यदि आप पथ मोड निर्दिष्ट नहीं करते हैं, तो lax
मोड का उपयोग किया जाएगा।
जब पथ नहीं मिल पाता है तो प्रत्येक मोड के साथ क्या होता है, यह प्रदर्शित करने के लिए यहां कुछ उदाहरण दिए गए हैं।
दूसरा तर्क
अगले दो उदाहरणों में, मैं OPENJSON()
को कॉल करते समय दूसरे तर्क में एक गैर-मौजूद पथ प्रदान करता हूं . पहला उदाहरण दिखाता है कि लैक्स मोड का उपयोग करते समय क्या होता है, दूसरा उदाहरण दिखाता है कि सख्त मोड का उपयोग करते समय क्या होता है।
लैक्स मोड
यहाँ क्या होता है lax
मोड जब पथ नहीं मिल सकता है।
DECLARE @json NVARCHAR(4000) = N'{
"pets" : {
"cats" : [
{ "id" : 1, "name" : "Fluffy", "sex" : "Female" },
{ "id" : 2, "name" : "Long Tail", "sex" : "Female" },
{ "id" : 3, "name" : "Scratch", "sex" : "Male" }
],
"dogs" : [
{ "name" : "Fetch", "sex" : "Male" },
{ "name" : "Fluffy", "sex" : "Male" },
{ "name" : "Wag", "sex" : "Female" }
]
}
}';
SELECT * FROM OPENJSON(@json, 'lax $.pets.cows');
परिणाम:
(0 rows affected)
कोई त्रुटि नहीं। बस शून्य परिणाम लौटा।
सख्त मोड
अब यहाँ यह strict
में है तरीका।
DECLARE @json NVARCHAR(4000) = N'{
"pets" : {
"cats" : [
{ "id" : 1, "name" : "Fluffy", "sex" : "Female" },
{ "id" : 2, "name" : "Long Tail", "sex" : "Female" },
{ "id" : 3, "name" : "Scratch", "sex" : "Male" }
],
"dogs" : [
{ "name" : "Fetch", "sex" : "Male" },
{ "name" : "Fluffy", "sex" : "Male" },
{ "name" : "Wag", "sex" : "Female" }
]
}
}'
SELECT * FROM OPENJSON(@json, 'strict $.pets.cows');
परिणाम:
Msg 13608, Level 16, State 3, Line 15 Property cannot be found on the specified JSON path.
जैसा कि अपेक्षित था, सख्त मोड के परिणामस्वरूप त्रुटि हुई।
साथ में
अगले दो उदाहरणों में, हम फिर से लैक्स मोड बनाम सख्त मोड का परीक्षण करते हैं, इस समय को छोड़कर हम इसे WITH
में निर्दिष्ट करते हैं स्कीमा को परिभाषित करते समय खंड।
लैक्स मोड
यहाँ क्या होता है lax
मोड।
DECLARE @json NVARCHAR(4000) = N'{
"pets" : {
"cats" : [
{ "id" : 1, "name" : "Fluffy", "sex" : "Female" },
{ "id" : 2, "name" : "Long Tail", "sex" : "Female" },
{ "id" : 3, "name" : "Scratch", "sex" : "Male" }
],
"dogs" : [
{ "name" : "Fetch", "sex" : "Male" },
{ "name" : "Fluffy", "sex" : "Male" },
{ "name" : "Wag", "sex" : "Female" }
]
}
}';
SELECT *
FROM OPENJSON(@json, '$.pets.cats')
WITH (
[Cat Id] int '$.id',
[Cat Name] varchar(60) '$.name',
[Born] date 'lax $.born',
[Cats] nvarchar(max) '$' AS JSON
);
परिणाम:
+----------+------------+--------+------------------------------------------------------+ | Cat Id | Cat Name | Born | Cats | |----------+------------+--------+------------------------------------------------------| | 1 | Fluffy | NULL | { "id" : 1, "name" : "Fluffy", "sex" : "Female" } | | 2 | Long Tail | NULL | { "id" : 2, "name" : "Long Tail", "sex" : "Female" } | | 3 | Scratch | NULL | { "id" : 3, "name" : "Scratch", "sex" : "Male" } | +----------+------------+--------+------------------------------------------------------+
इस मामले में मैं 'lax $.born'
. का उपयोग करता हूं क्योंकि मैं born
. नामक एक कुंजी को संदर्भित करने का प्रयास कर रहा हूं , लेकिन ऐसी कुंजी JSON में मौजूद नहीं है।
इस बार जो कॉलम नहीं मिल रहा है उसका परिणाम NULL
. है मूल्य।
सख्त मोड
अब यहाँ यह strict
में है मोड।
DECLARE @json NVARCHAR(4000) = N'{
"pets" : {
"cats" : [
{ "id" : 1, "name" : "Fluffy", "sex" : "Female" },
{ "id" : 2, "name" : "Long Tail", "sex" : "Female" },
{ "id" : 3, "name" : "Scratch", "sex" : "Male" }
],
"dogs" : [
{ "name" : "Fetch", "sex" : "Male" },
{ "name" : "Fluffy", "sex" : "Male" },
{ "name" : "Wag", "sex" : "Female" }
]
}
}';
SELECT *
FROM OPENJSON(@json, '$.pets.cats')
WITH (
[Cat Id] int '$.id',
[Cat Name] varchar(60) '$.name',
[Born] date 'strict $.born',
[Cats] nvarchar(max) '$' AS JSON
);
परिणाम:
Msg 13608, Level 16, State 6, Line 16 Property cannot be found on the specified JSON path.
इस बार मैंने 'strict $.born'
. का इस्तेमाल किया .
जैसा कि अपेक्षित था, सख्त मोड के परिणामस्वरूप त्रुटि हुई।
संगतता स्तर
OPENJSON()
फ़ंक्शन केवल संगतता स्तर 130 या उच्चतर के अंतर्गत उपलब्ध है।
अगर आपका डेटाबेस संगतता स्तर 130 से कम है, तो SQL सर्वर OPENJSON()
को ढूंढ और चला नहीं पाएगा , और आपको एक त्रुटि मिलेगी।
आप sys.databases
. के माध्यम से अपने डेटाबेस संगतता स्तर की जांच कर सकते हैं कैटलॉग दृश्य।
आप इसके अनुकूलता स्तर को इस तरह बदल सकते हैं:
ALTER DATABASE DatabaseName
SET COMPATIBILITY_LEVEL = 150;
JSON में नए हैं?
यदि आप JSON से इतने परिचित नहीं हैं, तो Quackit पर मेरा JSON ट्यूटोरियल देखें।