Hai trong số nhiều hàm T-SQL có sẵn trong SQL Server là JSON_QUERY()
và JSON_VALUE()
. Các hàm này có thể được sử dụng để trích xuất dữ liệu từ các tài liệu JSON.
Cú pháp chung của chúng tương tự nhau và thoạt nhìn, bạn có thể nghĩ rằng chúng làm chính xác những điều tương tự, nhưng thực tế thì không. Chắc chắn có một vị trí cho cả hai chức năng khi làm việc với JSON và SQL Server.
Bài viết này xem xét sự khác biệt giữa JSON_QUERY()
và JSON_VALUE()
.
Sự khác biệt
Hai hàm này có định nghĩa hơi khác nhau, cú pháp hơi khác và giá trị trả về của chúng hơi khác nhau.
Định nghĩa
Dưới đây là cách xác định hai hàm:
-
JSON_QUERY()
- Trích xuất một đối tượng hoặc một mảng từ chuỗi JSON.
-
JSON_VALUE()
- Trích xuất một giá trị vô hướng từ một chuỗi JSON.
Vì vậy, sự khác biệt giữa hai chức năng này là những gì chúng trích xuất. Một phần trích xuất một đối tượng hoặc một mảng, phần còn lại trích xuất một giá trị vô hướng.
Sự khác biệt về cú pháp
Một sự khác biệt nữa là ở cú pháp:
JSON_QUERY ( expression [ , path ] ) JSON_VALUE ( expression , path )
Nhìn vào JSON_QUERY()
cú pháp. Các dấu ngoặc vuông xung quanh path
đối số có nghĩa là nó là một đối số tùy chọn. Đó là vì hàm này có thể trả về toàn bộ tài liệu JSON nếu được yêu cầu.
Tuy nhiên, đối số đường dẫn là đối số bắt buộc khi sử dụng JSON_VALUE()
hàm số. Vì vậy, bạn phải cung cấp cả hai đối số khi sử dụng hàm này.
Giá trị trả lại
Và một điểm khác biệt nữa là giá trị trả về của chúng.
-
JSON_QUERY()
trả về một đoạn JSON thuộc loạinvarchar(max)
-
JSON_VALUE()
trả về một giá trị văn bản duy nhất của kiểunvarchar(4000)
Ví dụ 1 - Trích xuất Giá trị vô hướng
Dưới đây là một ví dụ để chứng minh sự khác biệt giữa các hàm này khi cố gắng trích xuất một giá trị vô hướng.
SELECT JSON_VALUE('{"Name": "Homer"}', '$.Name') AS 'JSON_VALUE', JSON_QUERY('{"Name": "Homer"}', '$.Name') AS 'JSON_QUERY';
Kết quả:
+--------------+--------------+ | JSON_VALUE | JSON_QUERY | |--------------+--------------| | Homer | NULL | +--------------+--------------+
Vì vậy, cả hai hàm đang cố gắng trích xuất cùng một giá trị từ tài liệu JSON, nhưng chỉ một hàm thành công:JSON_VALUE()
. Điều này là do giá trị mà họ đang cố gắng trích xuất là một giá trị vô hướng. Về cơ bản, giá trị vô hướng là một đơn vị dữ liệu. Nó có thể là một chuỗi văn bản hoặc một số. Nhưng nó không thể là một đối tượng hoặc một mảng.
Ví dụ 2 - Trích xuất một mảng
Trong ví dụ này, cả hai hàm đều cố gắng trích xuất toàn bộ một mảng.
DECLARE @data NVARCHAR(4000) SET @data=N'{ "Suspect": { "Name": "Homer Simpson", "Hobbies": ["Eating", "Sleeping", "Base Jumping"] } }' SELECT JSON_VALUE(@data,'$.Suspect.Hobbies') AS 'JSON_VALUE', JSON_QUERY(@data,'$.Suspect.Hobbies') AS 'JSON_QUERY';
Kết quả:
+--------------+----------------------------------------+ | JSON_VALUE | JSON_QUERY | |--------------+----------------------------------------| | NULL | ["Eating", "Sleeping", "Base Jumping"] | +--------------+----------------------------------------+
Trong trường hợp này, chỉ JSON_QUERY()
chức năng thành công.
Ví dụ 3 - Trích xuất một mục mảng
Ví dụ này tương tự như ví dụ trước, ngoại trừ việc thay vì cố gắng trích xuất toàn bộ mảng, chúng tôi chỉ muốn một mục duy nhất từ mảng.
DECLARE @data NVARCHAR(4000) SET @data=N'{ "Suspect": { "Name": "Homer Simpson", "Hobbies": ["Eating", "Sleeping", "Base Jumping"] } }' SELECT JSON_VALUE(@data,'$.Suspect.Hobbies[2]') AS 'JSON_VALUE', JSON_QUERY(@data,'$.Suspect.Hobbies[2]') AS 'JSON_QUERY';
Kết quả:
+--------------+--------------+ | JSON_VALUE | JSON_QUERY | |--------------+--------------| | Base Jumping | NULL | +--------------+--------------+
Vì vậy, lần này JSON_VALUE()
là người chiến thắng.
Ví dụ 4 - Trích xuất một đối tượng
Hãy thử cho toàn bộ đối tượng.
DECLARE @data NVARCHAR(4000) SET @data=N'{ "Suspect": { "Name": "Homer Simpson", "Hobbies": ["Eating", "Sleeping", "Base Jumping"] } }' SELECT JSON_VALUE(@data,'$.Suspect') AS 'JSON_VALUE', JSON_QUERY(@data,'$.Suspect') AS 'JSON_QUERY';
Kết quả:
+--------------+--------------+ | JSON_VALUE | JSON_QUERY | |--------------+--------------| | NULL | { "Name": "Homer Simpson", "Hobbies": ["Eating", "Sleeping", "Base Jumping"] } | +--------------+--------------+
Và JSON_QUERY()
thắng.
(Xin lỗi vì định dạng, đây là cách công cụ dòng lệnh MSSQL của tôi trả về kết quả).
Ví dụ 5 - Trích xuất Toàn bộ Tài liệu JSON
Hãy thử toàn bộ tài liệu JSON.
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_VALUE(@data, '$') AS 'JSON_VALUE', JSON_QUERY(@data, '$') AS 'JSON_QUERY';
Kết quả:
+--------------+--------------+ | JSON_VALUE | JSON_QUERY | |--------------+--------------| | NULL | { "Cities": [ { "Name": "Kabul", "CountryCode": "AFG", "District": "Kabol", "Population": 1780000 }, { "Name": "Qandahar", "CountryCode": "AFG", "District": "Qandahar", "Population": 237500 } ] } | +--------------+--------------+
Vì vậy, JSON_QUERY()
là cái duy nhất có thể trả về toàn bộ tài liệu.
Ví dụ 6 - Bỏ qua đường dẫn
Một sự khác biệt khác giữa hai hàm này là, đối số đường dẫn là tùy chọn khi sử dụng JSON_QUERY()
. Nếu bạn bỏ qua điều này, toàn bộ tài liệu JSON sẽ được trả về.
Bạn không thể bỏ qua đối số này khi sử dụng JSON_VALUE()
, vì nó là một đối số bắt buộc. Điều này có thể là do hàm chỉ có thể trả về một giá trị vô hướng. Nếu đối số đầu tiên chỉ bao gồm một giá trị vô hướng, nó sẽ không phải là JSON hợp lệ.
Dù sao, đây là một ví dụ về việc bỏ qua đối số đường dẫn khỏi JSON_QUERY()
:
SELECT JSON_QUERY('{"Name": "Homer"}') AS 'Result';
Kết quả:
+-------------------+ | Result | |-------------------| | {"Name": "Homer"} | +-------------------+
Và đây là điều sẽ xảy ra nếu chúng ta thử thủ thuật đó với JSON_VALUE()
:
SELECT JSON_VALUE('{"Name": "Homer"}') AS 'Result';
Kết quả:
Msg 174, Level 15, State 1, Line 1 The json_value function requires 2 argument(s).
Ví dụ 7 - Chế độ Đường dẫn
Trong các ví dụ trước đó, khi một hàm không thể xử lý đường dẫn được cung cấp, nó sẽ trả về NULL
. Điều này là do tất cả các ví dụ đó đã được chạy ở chế độ lỏng lẻo (chế độ mặc định).
Nếu chúng tôi chạy chúng ở chế độ nghiêm ngặt, chúng tôi sẽ nhận được lỗi. Để chỉ định rõ ràng chế độ đường dẫn, chỉ cần thêm nó vào trước ký hiệu đô la (và để lại khoảng cách giữa chúng).
Dưới đây là một ví dụ về những gì sẽ xảy ra khi bạn cung cấp một đường dẫn không hợp lệ khi ở chế độ nghiêm ngặt:
SELECT JSON_VALUE('{"Name": "Homer"}', 'strict $.Name') AS 'JSON_VALUE', JSON_QUERY('{"Name": "Homer"}', 'strict $.Name') AS 'JSON_QUERY';
Kết quả:
Msg 13624, Level 16, State 2, Line 1 Object or array cannot be found in the specified JSON path.