如何在我的 Sql 中为 Json 数组创建自定义函数

How to create custom function for Json array in My Sql

想要创建新的自定义函数来获取 json 数组数据,我使用的是 mysql 服务器 5.6 版本,所以我试图创建自定义 json 函数。 无法更新 mysql 版本尝试使用 Whosebug 建议的所有功能 我希望我的 select 查询只获取键“文本”的值。我尝试使用 Regex 和 Substring 但没有成功。

我只想要类似的JSON_EXTRACT功能

下面的示例 Json。

{
        "map": [
            {
                "text": "a"
            },
            {
                "text": "b"
            },
            {
                "text": "c"
            },
            {
                "text": "d"
            },
            {
                "text": "e"
            },
            {
                "text": "f"
            }
        ]
    }

输出: [a,b,c,d,e,f]

我试过

CREATE DEFINER=`root`@`localhost` FUNCTION `json_extract_c`(
details TEXT,
required_field VARCHAR (255)
) RETURNS text CHARSET utf8mb4
    NO SQL
    DETERMINISTIC
BEGIN
  DECLARE search_term, val TEXT;
  DECLARE pos INT signed DEFAULT 1;
  SET details = SUBSTRING_INDEX(details, "{", -1);
  SET details = SUBSTRING_INDEX(details, "}", 1);
  SET search_term = CONCAT('"', SUBSTRING_INDEX(required_field,'$.', - 1), '"');
  searching: LOOP
    SET pos = LOCATE(search_term, details);
    
    WHILE pos > 0 AND RIGHT(LEFT(details, pos-1), 1) = '\'
    DO
      SET details = SUBSTR(details, pos+LENGTH(search_term));
      SET pos = LOCATE(search_term, details);
    END WHILE;
    -- Return NULL if not found
    IF pos <= 0 THEN
      RETURN NULL;
    END IF;
    SET pos = LENGTH(search_term)+pos;
    SET details = SUBSTR(details, pos);
    SET val = TRIM(details);
    IF LEFT(val, 1) = ':' THEN
      RETURN TRIM(
        TRAILING ',' FROM 
        TRIM(
          SUBSTRING_INDEX(
            TRIM(
              BOTH '"' FROM TRIM(
                SUBSTR(
                  val
                , 2
                )
              )
            )
          , '"', 1
          )
        )
      );
    ELSE
      ITERATE searching;
    END IF;
  END LOOP;
END
CREATE FUNCTION json_extract_c ( details TEXT,
                                 required_field VARCHAR (255) ) 
RETURNS text CHARSET utf8mb4
NO SQL
DETERMINISTIC
BEGIN
SET @json := details;
SET @field := required_field;
SET @output := '[';
WHILE LOCATE(@field, @json) DO
    SET @json := SUBSTRING(@json FROM LOCATE(@field, @json));
    SET @json := SUBSTRING(@json FROM 1 + LOCATE(':', @json));
    SET @json := TRIM(@json);
    SET @value := LEFT(@json, LEAST(LOCATE(' ', CONCAT(@json, ' ')),
                                    LOCATE(',', CONCAT(@json, ',')),
                                    LOCATE(']', CONCAT(@json, ']')),
                                    LOCATE('}', CONCAT(@json, '}'))) - 1);
    SET @json := SUBSTRING(@json FROM 1 + LENGTH(@value));
    SET @output := CONCAT(@output, @value, ',');
-- or SET @output := CONCAT(@output, TRIM(BOTH '"' FROM @value), ',');
END WHILE;
RETURN CONCAT(TRIM(TRAILING ',' FROM @output), ']');
END

fiddle

PS。我使用 step-by-step 转换。这必须让您了解这是如何工作的。您可以通过将大量语句组合成一个可能的语句并使用参数变量而不是中间变量 user-defined 来压缩代码。