Jika Anda menggunakan OPENJSON()
, tetapi Anda mencoba mengingat cara memilih fragmen bagian dalam dari dokumen JSON, baca terus.
OPENJSON()
sintaks memungkinkan Anda untuk mengubah dokumen JSON menjadi tampilan tabel. Ini juga memungkinkan Anda untuk memilih fragmen JSON bersarang dari dokumen JSON.
Cara melakukannya adalah dengan jalur .
Jalur
Jalur terdiri dari berikut ini:
- Tanda dolar (
$
), yang mewakili item konteks. - Satu set langkah-langkah jalur. Langkah-langkah jalur dapat berisi elemen dan operator berikut:
- Nama-nama kunci. Misalnya,
$.pets
dan$.pets.dogs
. Jika nama kunci dimulai dengan tanda dolar atau berisi karakter khusus seperti spasi, nama kunci harus diapit dengan tanda kutip (misalnya$."my pets"
). - Elemen larik. Misalnya,
$.pets.dogs[1]
. Indeks larik berbasis nol, jadi contoh ini memilih elemen kedua dalam larik. - Operator titik (
.
) menunjukkan anggota suatu objek. Misalnya, di$.pets.dogs
,dogs
adalah anggotapets
.
- Nama-nama kunci. Misalnya,
Contoh Dasar
Berikut adalah contoh sederhana untuk didemonstrasikan.
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" : [
{ "id" : 1, "name" : "Fetch", "sex" : "Male" },
{ "id" : 2, "name" : "Fluffy", "sex" : "Male" },
{ "id" : 3, "name" : "Wag", "sex" : "Female" }
]
}
}';
SELECT *
FROM OPENJSON(@json, '$.pets.dogs')
WITH (
[id] int,
[name] varchar(60),
[sex] varchar(6)
);
Hasil:
+------+--------+--------+ | id | name | sex | |------+--------+--------| | 1 | Fetch | Male | | 2 | Fluffy | Male | | 3 | Wag | Female | +------+--------+--------+
Dalam hal ini, argumen kedua untuk OPENJSON()
adalah '$.pets.dogs'
, yang berarti kita memilih nilai dogs
key, yang merupakan anak dari pets
.
Tanda dolar ($
) mewakili item konteks.
Perhatikan bahwa dalam contoh ini, saya juga menggunakan WITH
klausa untuk mendefinisikan skema. Jika saya tidak menyertakan itu, skema default akan digunakan sebagai gantinya.
Berikut tampilannya menggunakan skema default.
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" : [
{ "id" : 1, "name" : "Fetch", "sex" : "Male" },
{ "id" : 2, "name" : "Fluffy", "sex" : "Male" },
{ "id" : 3, "name" : "Wag", "sex" : "Female" }
]
}
}';
SELECT *
FROM OPENJSON(@json, '$.pets.dogs');
Hasil:
+-------+-------------------------------------------------+--------+ | key | value | type | |-------+-------------------------------------------------+--------| | 0 | { "id" : 1, "name" : "Fetch", "sex" : "Male" } | 5 | | 1 | { "id" : 2, "name" : "Fluffy", "sex" : "Male" } | 5 | | 2 | { "id" : 3, "name" : "Wag", "sex" : "Female" } | 5 | +-------+-------------------------------------------------+--------+
Jadi kita masih memilih nested JSON yang sama, hanya saja kita menggunakan skema yang berbeda.
Skema default selalu mengembalikan tiga kolom; kunci , nilai , dan ketik .
Memilih Elemen Array
Seperti yang disebutkan, Anda dapat menggunakan notasi kurung siku untuk memilih elemen tertentu dalam array.
Ini contohnya.
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" : [
{ "id" : 1, "name" : "Fetch", "sex" : "Male" },
{ "id" : 2, "name" : "Fluffy", "sex" : "Male" },
{ "id" : 3, "name" : "Wag", "sex" : "Female" }
]
}
}';
SELECT *
FROM OPENJSON(@json, '$.pets.dogs[0]')
WITH (
[id] int,
[name] varchar(60),
[sex] varchar(6)
);
Hasil:
+------+--------+-------+ | id | name | sex | |------+--------+-------| | 1 | Fetch | Male | +------+--------+-------+
Melihat indeks array berbasis nol, menetapkan nilai 0
mengembalikan elemen pertama dalam larik.
Berikut adalah tampilan contoh ini saat menggunakan skema default (yaitu tanpa WITH
klausa).
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" : [
{ "id" : 1, "name" : "Fetch", "sex" : "Male" },
{ "id" : 2, "name" : "Fluffy", "sex" : "Male" },
{ "id" : 3, "name" : "Wag", "sex" : "Female" }
]
}
}';
SELECT *
FROM OPENJSON(@json, '$.pets.dogs[0]');
Hasil:
+-------+---------+--------+ | key | value | type | |-------+---------+--------| | id | 1 | 2 | | name | Fetch | 1 | | sex | Male | 1 | +-------+---------+--------+
Mode Jalur
Saat menggunakan jalur, Anda memiliki opsi untuk mendeklarasikan mode jalur.
Mode jalur menentukan apa yang terjadi ketika ekspresi jalur berisi kesalahan.
Mode jalur dapat berupa lax
atau strict
.
- Dalam
lax
mode, fungsi mengembalikan nilai kosong jika jalur tidak dapat ditemukan. Misalnya, jika Anda meminta nilai$.pets.cows
, tetapi JSON tidak berisi kunci itu, fungsi mengembalikan null, tetapi tidak menimbulkan kesalahan. - Dalam
strict
mode, fungsi memunculkan kesalahan jika jalur tidak dapat ditemukan.
Mode jalur default adalah lax
, jadi jika Anda tidak mendeklarasikannya, lax
digunakan.
Contoh
Berikut adalah contoh untuk menunjukkan bagaimana setiap mode jalur menangani jalur yang hilang.
Mode 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" : [
{ "id" : 1, "name" : "Fetch", "sex" : "Male" },
{ "id" : 2, "name" : "Fluffy", "sex" : "Male" },
{ "id" : 3, "name" : "Wag", "sex" : "Female" }
]
}
}';
SELECT *
FROM OPENJSON(@json, 'lax $.pets.cows');
Hasil:
(0 rows affected)
Jadi mode longgar tidak menimbulkan kesalahan apa pun. Itu hanya mengakibatkan nol baris terpengaruh.
Jika kami menentukan skema kami sendiri, dan kami memilih sub-objek yang benar, tetapi kami menggunakan jalur yang hilang untuk memetakan ke nama kolom, itu akan mengembalikan NULL
di kolom itu.
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" : [
{ "id" : 1, "name" : "Fetch", "sex" : "Male" },
{ "id" : 2, "name" : "Fluffy", "sex" : "Male" },
{ "id" : 3, "name" : "Wag", "sex" : "Female" }
]
}
}'
SELECT *
FROM OPENJSON(@json, 'lax $.pets.dogs')
WITH (
[id] int 'lax $.id',
[name] varchar(60) 'lax $.name',
[color] varchar(6) 'lax $.color'
);
Hasil:
+------+--------+---------+ | id | name | color | |------+--------+---------| | 1 | Fetch | NULL | | 2 | Fluffy | NULL | | 3 | Wag | NULL | +------+--------+---------+
Mode Ketat
Inilah yang terjadi jika kita menggunakan mode ketat.
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" : [
{ "id" : 1, "name" : "Fetch", "sex" : "Male" },
{ "id" : 2, "name" : "Fluffy", "sex" : "Male" },
{ "id" : 3, "name" : "Wag", "sex" : "Female" }
]
}
}';
SELECT *
FROM OPENJSON(@json, 'strict $.pets.cows');
Hasil:
Msg 13608, Level 16, State 3, Line 16 Property cannot be found on the specified JSON path.
Seperti yang diharapkan, ini menghasilkan kesalahan.
Kesalahan yang sama terjadi saat kami memilih kunci JSON yang benar, tetapi memetakan kolom ke kunci yang tidak ada.
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" : [
{ "id" : 1, "name" : "Fetch", "sex" : "Male" },
{ "id" : 2, "name" : "Fluffy", "sex" : "Male" },
{ "id" : 3, "name" : "Wag", "sex" : "Female" }
]
}
}';
SELECT *
FROM OPENJSON(@json, 'strict $.pets.dogs')
WITH (
[id] int 'strict $.id',
[name] varchar(60) 'strict $.name',
[color] varchar(6) 'strict $.color'
);
Hasil:
Msg 13608, Level 16, State 6, Line 16 Property cannot be found on the specified JSON path.
Jalur Duplikat
Jika dokumen JSON Anda berisi jalur duplikat pada tingkat bersarang yang sama, OPENJSON()
dapat mengembalikan semuanya.
Ini berbeda dengan JSON_VALUE()
dan JSON_QUERY()
, keduanya hanya mengembalikan nilai pertama yang cocok dengan jalurnya.
Berikut ini contoh penggunaan OPENJSON()
untuk mengembalikan jalur duplikat.
DECLARE @json NVARCHAR(4000) = N'{
"dog": {
"names": {
"name": "Fetch",
"name": "Good Dog"
}
}
}';
SELECT * FROM OPENJSON(@json, '$.dog.names');
Hasil:
+-------+----------+--------+ | key | value | type | |-------+----------+--------| | name | Fetch | 1 | | name | Good Dog | 1 | +-------+----------+--------+
Sub-Objek Bersarang
Saat mendefinisikan skema Anda sendiri, Anda dapat menggunakan AS JSON
opsi untuk mengembalikan seluruh sub-objek sebagai dokumen JSON-nya sendiri.
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" : [
{ "id" : 1, "name" : "Fetch", "sex" : "Male" },
{ "id" : 2, "name" : "Fluffy", "sex" : "Male" },
{ "id" : 3, "name" : "Wag", "sex" : "Female" }
]
}
}';
SELECT *
FROM OPENJSON(@json, '$.pets')
WITH (
[dogs] nvarchar(max) '$.dogs' AS JSON
);
Hasil:
+--------+ | dogs | |--------| | [ { "id" : 1, "name" : "Fetch", "sex" : "Male" }, { "id" : 2, "name" : "Fluffy", "sex" : "Male" }, { "id" : 3, "name" : "Wag", "sex" : "Female" } ] | +--------+
Jika kami tidak menggunakan AS JSON
opsi, kami akan menerima kesalahan atau NULL, tergantung pada apakah kami telah menentukan lax
atau strict
modus.
Ini dia di setiap mode saat menghilangkan AS JSON
pilihan.
Mode longgar
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" : [
{ "id" : 1, "name" : "Fetch", "sex" : "Male" },
{ "id" : 2, "name" : "Fluffy", "sex" : "Male" },
{ "id" : 3, "name" : "Wag", "sex" : "Female" }
]
}
}';
SELECT *
FROM OPENJSON(@json, '$.pets')
WITH (
[dogs] nvarchar(max) 'lax $.dogs'
);
Hasil:
+--------+ | dogs | |--------| | NULL | +--------+
Mode ketat
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" : [
{ "id" : 1, "name" : "Fetch", "sex" : "Male" },
{ "id" : 2, "name" : "Fluffy", "sex" : "Male" },
{ "id" : 3, "name" : "Wag", "sex" : "Female" }
]
}
}';
SELECT *
FROM OPENJSON(@json, '$.pets')
WITH (
[dogs] nvarchar(max) 'strict $.dogs'
);
Hasil:
Msg 13624, Level 16, State 1, Line 16 Object or array cannot be found in the specified JSON path.