簡體   English   中英

MySQL JSON_SET() 處理空數組

[英]MySQL JSON_SET() to work with empty arrays

我有一張這樣的表:

CREATE TABLE `test` (
  `id` int(11) NOT NULL,
  `settings` json NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

INSERT INTO `test` (`id`, `settings`) VALUES 
    ('1', '{\"foo\": {\"bar\": 1}}'),
    ('2', '{\"foobar\": 2}'),
    ('3', '[]');

我想在一行中添加一個新設置,所以我嘗試了JSON_SET

SELECT *, JSON_SET(settings, '$.newFoo', 10) FROM test;

在此處輸入圖片說明

如您所見,它不適用於第 3 行。預期結果當然與第 4 行相同; []是在 php 中對空數組進行 json 編碼的結果,如果該項目沒有任何設置。

可以進行適用於所有情況的單個查詢嗎?


PS:我需要做的是一個UPDATE,即UPDATE test SET settings=JSON_SET(...) WHERE id=?;

JSON_SET的調用JSON_SET預期運行的原因是,處理 JSON 數組所需的語法與處理單個 JSON 所需的語法不同。 考慮以下查詢,它將 JSON 添加到空數組:

SELECT JSON_SET('[]', '$[0]', '{"newFoo": 10}') AS output;

這打印:

["{\"newFoo\": 10}"]

演示

所以JSON_SET函數似乎有兩種行為。 在正確操作 JSON 時,它可以插入新密鑰或更新已存在的密鑰。 在對數組進行操作時,它可以插入/更新數組的元素,這些元素可能是整個 JSON 對象。

這也難倒了我很長一段時間,但嘗試使用 JSON_ARRAY() 而不是雙括號符號“[]”。 例如:

INSERT INTO `test` (`id`, `settings`) VALUES 
    ('1', '{\"foo\": {\"bar\": 1}}'),
    ('2', '{\"foobar\": 2}'),
    ('3', JSON_ARRAY());

您可以使用CASE .. WHEN條件運算符在單個查詢中處理此問題。 此外,由於您的settings數據類型是Json ,您需要先將它Cast()到字符串 (Char) 以檢查[]

SELECT *, 
       CASE WHEN CAST(settings AS CHAR) = '[]'  
            THEN JSON_SET('{}', '$.newFoo', 10)
            ELSE JSON_SET(settings, '$.newFoo', 10) 
       END AS modified_settings 
FROM test;

相同的Update查詢如下:

UPDATE test 
SET settings = CASE WHEN CAST(settings AS CHAR) = '[]'  
                    THEN JSON_SET('{}', '$.newFoo', 10)
                    ELSE JSON_SET(settings, '$.newFoo', 10) 
               END

我通過始終將值存儲為對象而不是數組來解決,在 PHP 中您需要向json_encode函數添加一個標志:

json_encode($value, JSON_FORCE_OBJECT)

或者,作為替代,使字段可以為空並使用COALESCE

SELECT *, JSON_SET(COALESCE(settings, '{}'), '$.newFoo', 10) FROM test;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM