->
và ->>
các toán tử đã được giới thiệu trong phiên bản SQLite 3.38.0, được phát hành vào ngày 22 tháng 2 năm 2022. Cả hai toán tử đều được sử dụng để trích xuất các thành phần con của JSON. Nhưng có một sự khác biệt nhỏ giữa chúng.
Sự khác biệt
Sự khác biệt giữa các toán tử này như sau:
-
->
toán tử luôn trả về một JSON đại diện của thành phần con được chỉ định -
->>
toán tử luôn trả về một SQL đại diện của thành phần con được chỉ định
Ví dụ
Dưới đây là một ví dụ minh họa sự khác biệt giữa hai toán tử này:
SELECT
'{ "name" : "Wag", "type" : "Dog" }' -> '$.type' AS "->",
'{ "name" : "Wag", "type" : "Dog" }' ->> '$.type' AS "->>";
Kết quả:
+-------+-----+ | -> | ->> | +-------+-----+ | "Dog" | Dog | +-------+-----+
Chúng ta có thể thấy rằng ->
trả về giá trị được đặt trong dấu ngoặc kép trong khi ->>
không.
Đó là bởi vì ->
trả về một biểu diễn JSON của giá trị và ->>
đã trả về một biểu diễn SQL.
Số
Dưới đây là một ví dụ sử dụng số:
SELECT
'{ "age" : 10 }' -> '$.age' AS "->",
'{ "age" : 10 }' ->> '$.age' AS "->>";
Kết quả:
+----+-----+ | -> | ->> | +----+-----+ | 10 | 10 | +----+-----+
Đây là những gì sẽ xảy ra khi chúng tôi sử dụng typeof()
hàm lấy kiểu SQL:
SELECT
typeof('{ "age" : 10 }' -> '$.age') AS "->",
typeof('{ "age" : 10 }' ->> '$.age') AS "->>";
Kết quả:
+------+---------+ | -> | ->> | +------+---------+ | text | integer | +------+---------+
Tuy nhiên, nếu chúng ta sử dụng json_type()
, chúng tôi sẽ nhận được loại JSON:
SELECT
json_type('{ "age" : 10 }' -> '$.age') AS "->",
json_type('{ "age" : 10 }' ->> '$.age') AS "->>";
Kết quả:
+---------+---------+ | -> | ->> | +---------+---------+ | integer | integer | +---------+---------+
Dưới đây là một ví dụ sử dụng số thực:
SELECT
typeof('{ "age" : 1.2 }' -> '$.age') AS "->",
typeof('{ "age" : 1.2 }' ->> '$.age') AS "->>";
Kết quả:
+------+------+ | -> | ->> | +------+------+ | text | real | +------+------+
Và với json_type()
:
SELECT
json_type('{ "age" : 1.2 }' -> '$.age') AS "->",
json_type('{ "age" : 1.2 }' ->> '$.age') AS "->>";
Kết quả:
+------+------+ | -> | ->> | +------+------+ | real | real | +------+------+
Giá trị rỗng
Nếu tài liệu JSON chứa null
, rồi đến ->
sẽ trả về biểu diễn JSON của null và ->>
sẽ chỉ trả về giá trị null.
Dưới đây là một ví dụ để chứng minh ý tôi muốn nói:
SELECT
'{ "name" : "Wag", "type" : null }' -> '$.type' AS "->",
'{ "name" : "Wag", "type" : null }' ->> '$.type' AS "->>";
Kết quả:
+------+-----+ | -> | ->> | +------+-----+ | null | | +------+-----+
Theo mặc định, giao diện dòng lệnh SQLite (CLI) trả về chuỗi trống bất cứ khi nào giá trị rỗng được trả về. Vì vậy, chúng ta có thể thấy từ ví dụ của mình rằng ->
trả về giá trị JSON thực tế null, trong khi ->>
đã trả về một giá trị null thực tế.
Để chứng minh thêm điều này, chúng tôi có thể đặt .nullvalue
của chúng tôi sang một cái gì đó khác với chuỗi trống:
.nullvalue n/a
Bây giờ chúng ta hãy chạy lại truy vấn trước:
SELECT
'{ "name" : "Wag", "type" : null }' -> '$.type' AS "->",
'{ "name" : "Wag", "type" : null }' ->> '$.type' AS "->>";
Kết quả:
+------+-----+ | -> | ->> | +------+-----+ | null | n/a | +------+-----+
Lần này n/a
được xuất cho ->>
toán tử thay vì chuỗi trống.
Và đây là những gì sẽ xảy ra khi chúng tôi chuyển đầu ra cho typeof()
và json_type()
chức năng:
SELECT
typeof('{ "name" : "Wag", "type" : null }' -> '$.type') AS "->",
typeof('{ "name" : "Wag", "type" : null }' ->> '$.type') AS "->>";
SELECT
json_type('{ "name" : "Wag", "type" : null }' -> '$.type') AS "->",
json_type('{ "name" : "Wag", "type" : null }' ->> '$.type') AS "->>";
Kết quả:
+------+------+ | -> | ->> | +------+------+ | text | null | +------+------+ +------+-----+ | -> | ->> | +------+-----+ | null | n/a | +------+-----+
Một giải pháp thay thế:json_extract()
Một cách khác để trích xuất các giá trị từ tài liệu JSON trong SQLite là sử dụng json_extract()
hàm số. Hàm này hoạt động hơi khác với ->
và ->>
trong đó kiểu trả về phụ thuộc vào ngữ cảnh.
json_extract()
hàm chỉ trả về JSON nếu có hai hoặc nhiều đối số đường dẫn (vì kết quả sau đó là một mảng JSON) hoặc nếu đối số đường dẫn đơn tham chiếu đến một mảng hoặc đối tượng.
Nếu chỉ có một đối số đường dẫn và đường dẫn đó tham chiếu đến JSON null hoặc một chuỗi hoặc một giá trị số, thì json_extract()
trả về giá trị SQL NULL, TEXT, INTEGER hoặc REAL tương ứng.