【问题标题】:MariaDB updating json attribute across array in JSONMariaDB 在 JSON 中跨数组更新 json 属性
【发布时间】:2019-11-26 14:42:49
【问题描述】:

目标 我的表中有一个 json 列,我想在 MariaDB 10.3.18 中更新它。

CREATE TABLE IF NOT EXISTS `json_data` (
  `name` VARCHAR(255),
  `config_json` MEDIUMTEXT(10000)
);

config_json 字段具有这样的值。

{
    "one": {
        "filters": [
            {
                "type": "campaign_categories_5",
                "title": "Title1"
            }
        ],
        "value1": "one",
        "containers": [],
        "combined": false
    },
    "description": "",
    "columns": [
        {
            "dataType": "STRING",
            "title": "Title1"
        },
        {
            "dataType": "STRING",
            "title": "Title2"
        },
        {
            "dataType": "STRING",
            "title": "Title3"
        },
        {
            "dataType": "STRING",
            "title": "Title1"
        }
    ]
}

我正在尝试通过将值“Title1”替换为“Updated Title1”、“Title2”替换为“Updated Title2”和“Title3”来替换路径column[*].title 中config_json 的属性“title”来更新表中的每个条目” 与“更新的 Title3”。 更新后的 json 应该是这样的

{
    "one": {
        "filters": [
            {
                "type": "campaign_categories_5",
                "title": "Title1"
            }
        ],
        "value1": "one",
        "containers": [],
        "combined": false
    },
    "description": "",
    "columns": [
        {
            "dataType": "STRING",
            "title": "Updated Title1"
        },
        {
            "dataType": "STRING",
            "title": "Updated Title2"
        },
        {
            "dataType": "STRING",
            "title": "Updated Title3"
        },
        {
            "dataType": "STRING",
            "title": "Updated Title1"
        }
    ]
}

正如您在上面看到的,我不应该在其他路径中更改标题属性。 我正在尝试这个

drop FUNCTION  if EXISTS modify_json;
create FUNCTION modify_json(myvar json)
returns json
deterministic
begin

    SET @i = 0;
    SET @len = JSON_LENGTH(myvar, '$.columns');
    while i < @len do
        IF JSON_CONTAINS(myvar, '"Title1"', concat('$.columns[', i, '].title')) THEN
            set myvar = json_replace(myvar, concat('$.columns[', i, '].title'), '"Updated Title1"');
        END IF;
        IF JSON_CONTAINS(myvar, '"Title2"', concat('$.columns[', i, '].title')) THEN
            set myvar = json_replace(myvar, concat('$.columns[', i, '].title'), '"Updated Title2"');
        END IF;
        IF JSON_CONTAINS(myvar, '"Title3"', concat('$.columns[', i, '].title')) THEN
            set myvar = json_replace(myvar, concat('$.columns[', i, '].title'), '"Updated Title3"');
        END IF;
        set i = i + 1;
    end while;
    return myvar;
end;

update config_suite_reports_element set config_json = modify_json(config_json)
where json_contains_path(config_json, 'one', '$.columns[*].title');

但我收到以下错误

Error occurred during SQL script execution

Reason:
SQL Error [1064] [42000]: (conn=5434951) You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 6

【问题讨论】:

  • 这个问题和 JSON 完全没有关系。你只是忘了使用DELIMITER
  • 我也使用了分隔符,但面临类似的命运。即使我尝试了类似的代码作为没有参数的过程,请让我知道我做错了什么。谢谢。
  • 带有@ 印记的变量是user-defined session variables。没有@ 标记的变量要么是内置变量,要么是您使用DECLARE 定义的局部变量。有时您不能使用@。变量@ii 不是同一个变量。
  • @BillKarwin 非常感谢,真的很有帮助。我修正了,最后这是一个愚蠢的错误。

标签: sql json mariadb sql-function


【解决方案1】:

我发现了问题。 1. 分隔符 2. 最新mariaDB 10.3中的变量命名约定

DROP FUNCTION IF EXISTS func;
DELIMITER //

CREATE FUNCTION func(myvar json) RETURNS json DETERMINISTIC
BEGIN
  DECLARE i TINYINT;
  DECLARE len TINYINT;
  SET i = 0;
  SET len = JSON_LENGTH(myvar, '$.columns');
  while i < len do
    IF JSON_CONTAINS(myvar, '"Title1"', concat('$.columns[', i, '].title')) THEN
        set myvar = json_replace(myvar, concat('$.columns[', i, '].title'), 'Updated Title1');
    ELSEIF JSON_CONTAINS(myvar, '"Title2"', concat('$.columns[', i, '].title')) THEN
        set myvar = json_replace(myvar, concat('$.columns[', i, '].title'), 'Updated Title2');
    ELSEIF JSON_CONTAINS(myvar, '"Title3"', concat('$.columns[', i, '].title')) THEN
        set myvar = json_replace(myvar, concat('$.columns[', i, '].title'), 'Updated Title3');
    END IF;
    set i = i + 1;
  end while;
  RETURN myvar;
END 

//

DELIMITER ;

谢谢@BillKarwin

【讨论】:

    猜你喜欢
    • 2018-05-07
    • 2015-07-30
    • 1970-01-01
    • 2021-11-19
    • 2022-01-04
    • 2017-07-21
    • 1970-01-01
    • 2021-12-07
    • 1970-01-01
    相关资源
    最近更新 更多