Khi sử dụng JSON với SQL Server, bạn có thể sử dụng JSON_QUERY()
hàm để trích xuất một đối tượng hoặc một mảng từ chuỗi JSON.
Để sử dụng hàm này, bạn cung cấp biểu thức JSON làm đối số. Bạn cũng có thể cung cấp đối số thứ hai (tùy chọn) để chỉ định đối tượng hoặc mảng cần trích xuất.
Cú pháp
Cú pháp như sau:
JSON_QUERY ( expression [ , path ] )
Ở đâu expression
là biểu thức chuỗi JSON và path
là đối tượng hoặc mảng mà bạn muốn trích xuất từ biểu thức đó. path
đối số là tùy chọn (nếu bạn không cung cấp, toàn bộ tài liệu JSON sẽ được trả về).
Đối số đường dẫn (nếu được cung cấp) có thể bao gồm một chế độ đường dẫn tùy chọn thành phần. Chế độ đường dẫn tùy chọn này có thể là một giá trị của lax
hoặc strict
. Giá trị này xác định điều gì sẽ xảy ra trong trường hợp đường dẫn được cung cấp không hợp lệ. Chế độ đường dẫn (nếu được cung cấp) đứng trước ký hiệu đô la.
Ví dụ 1 - Cách sử dụng cơ bản
Dưới đây là một ví dụ để chứng minh cách sử dụng cơ bản của JSON_QUERY()
chức năng.
DECLARE @data NVARCHAR(4000) SET @data=N'{ "Cities": [ { "Name": "Kabul", "CountryCode": "AFG", "District": "Kabol", "Population": 1780000 }, { "Name": "Qandahar", "CountryCode": "AFG", "District": "Qandahar", "Population": 237500 } ] }' SELECT JSON_QUERY(@data, '$.Cities[0]') AS 'Result';
Kết quả:
+----------+ | Result | |----------| | { "Name": "Kabul", "CountryCode": "AFG", "District": "Kabol", "Population": 1780000 } | +----------+
Trong ví dụ này, trước tiên tôi khai báo và đặt một biến có tên là @data
. Sau đó, tôi gán một mảng cho biến này. Sau khi hoàn thành việc này, tôi sẽ chạy một truy vấn đối với mảng đó.
Trong trường hợp này, tôi sử dụng Cities[0]
để tham chiếu đến mục đầu tiên trong mảng (mảng JSON sử dụng cách đánh số dựa trên 0).
Tôi có thể truy cập mục thứ hai bằng cách sử dụng Cities[1]
. Như thế này:
DECLARE @data NVARCHAR(4000) SET @data=N'{ "Cities": [ { "Name": "Kabul", "CountryCode": "AFG", "District": "Kabol", "Population": 1780000 }, { "Name": "Qandahar", "CountryCode": "AFG", "District": "Qandahar", "Population": 237500 } ] }' SELECT JSON_QUERY(@data, '$.Cities[1]') AS 'Result';
Kết quả:
+----------+ | Result | |----------| | { "Name": "Qandahar", "CountryCode": "AFG", "District": "Qandahar", "Population": 237500 } | +----------+
Ví dụ 2 - Trả về Toàn bộ Biểu thức JSON
Đối số thứ hai là tùy chọn, vì vậy nếu bạn bỏ qua nó, toàn bộ tài liệu JSON sẽ được trả về. Dưới đây là những gì sẽ xảy ra khi chúng tôi làm điều đó bằng cách sử dụng cùng một dữ liệu từ các ví dụ trước:
DECLARE @data NVARCHAR(4000) SET @data=N'{ "Cities": [ { "Name": "Kabul", "CountryCode": "AFG", "District": "Kabol", "Population": 1780000 }, { "Name": "Qandahar", "CountryCode": "AFG", "District": "Qandahar", "Population": 237500 } ] }' SELECT JSON_QUERY(@data) AS 'Result';
Kết quả:
+----------+ | Result | |----------| | { "Cities": [ { "Name": "Kabul", "CountryCode": "AFG", "District": "Kabol", "Population": 1780000 }, { "Name": "Qandahar", "CountryCode": "AFG", "District": "Qandahar", "Population": 237500 } ] } | +----------+
Ví dụ 3 - Ví dụ về Cơ sở dữ liệu
Nếu chúng ta đặt dữ liệu từ ví dụ trước vào cơ sở dữ liệu, chúng ta có thể viết lại truy vấn như sau:
SELECT JSON_QUERY(Document,'$.Cities[0]') AS 'City 1' FROM Json_Documents
Kết quả:
+----------+ | City 1 | |----------| | { "ID": 1, "Name": "Kabul", "CountryCode": "AFG", "District": "Kabol", "Population": 1780000 } | +----------+
Điều này giả định rằng tài liệu JSON được lưu trữ trong một cột có tên là Document
, nằm trong bảng có tên Json_Documents
.
Ví dụ 4 - Giá trị vô hướng
JSON_QUERY()
hàm không được thiết kế để trả về giá trị vô hướng. Nếu bạn muốn trả về một giá trị vô hướng, hãy sử dụng JSON_VALUE()
chức năng thay thế.
Tuy nhiên, không có gì có thể ngăn bạn kết hợp cả hai hàm trong một truy vấn để trả về dữ liệu ở nhiều cấp độ chi tiết khác nhau.
Đây là một ví dụ:
DECLARE @data NVARCHAR(4000) SET @data=N'{ "Suspect": { "Name": "Homer Simpson", "Hobbies": ["Eating", "Sleeping", "Base Jumping"] } }' SELECT JSON_VALUE(@data,'$.Suspect.Name') AS 'Name', JSON_QUERY(@data,'$.Suspect.Hobbies') AS 'Hobbies', JSON_VALUE(@data,'$.Suspect.Hobbies[2]') AS 'Last Hobby';
Kết quả:
+---------------+----------------------------------------+--------------+ | Name | Hobbies | Last Hobby | |---------------+----------------------------------------+--------------| | Homer Simpson | ["Eating", "Sleeping", "Base Jumping"] | Base Jumping | +---------------+----------------------------------------+--------------+
Trong ví dụ này, tôi đã sử dụng JSON_VALUE()
để trích xuất các giá trị vô hướng khác nhau, nhưng tôi cũng đã sử dụng JSON_QUERY()
để trả về toàn bộ mảng (mà JSON_VALUE()
không làm được).
Ví dụ 5 - Chế độ Đường dẫn
Như đã đề cập, bạn cũng có tùy chọn chỉ định chế độ đường dẫn. Đây có thể là lax
hoặc strict
.
Giá trị của chế độ đường dẫn xác định điều gì sẽ xảy ra khi biểu thức đường dẫn có lỗi. Cụ thể:
- Trong lỏng lẻo , hàm trả về các giá trị trống nếu biểu thức đường dẫn có lỗi. Ví dụ:nếu bạn yêu cầu giá trị $ .name và văn bản JSON không chứa tên , hàm trả về null, nhưng không tạo ra lỗi.
-
Trong nghiêm ngặt , hàm phát sinh lỗi nếu biểu thức đường dẫn có lỗi.
Giá trị mặc định là lax
.
Dưới đây là một ví dụ để chứng minh sự khác biệt giữa hai chế độ này.
Lỗi ở chế độ lỏng lẻo
Đây là những gì sẽ xảy ra khi biểu thức đường dẫn có lỗi khi ở chế độ lỏng lẻo.
SELECT JSON_QUERY('{"Name": "Bruce"}', 'lax $.Name') AS 'Result';
Kết quả:
+----------+ | Result | |----------| | NULL | +----------+
Trong ví dụ này, chúng tôi đang cố gắng trả về một giá trị vô hướng, nhưng JSON_QUERY()
không làm giá trị vô hướng. Như đã đề cập, nó chỉ trả về các đối tượng và mảng. Trong trường hợp này, chúng tôi nhận được giá trị null (vì chúng tôi đang sử dụng chế độ lỏng lẻo).
Lỗi ở chế độ nghiêm ngặt
Đây là những gì sẽ xảy ra khi chúng tôi chạy cùng một mã ở chế độ nghiêm ngặt.
SELECT JSON_QUERY('{"Name": "Bruce"}', 'strict $.Name') AS 'Result';
Kết quả:
Msg 13624, Level 16, State 2, Line 1 Object or array cannot be found in the specified JSON path.
Như mong đợi, chế độ nghiêm ngặt dẫn đến thông báo lỗi giải thích lỗi.