使用 JSON (MySQL/MariaDB) 替换字符串中的值
Replacing values in a string using JSON (MySQL/MariaDB)
我尝试了一种方法,但未成功,即使用包含 JSON 的列的值来替换仅使用 SQL 查询功能的字符串段。
下面是一些示例数据:
MariaDB [test_db]> SELECT * FROM events_log LIMIT 3;
+----+-------------------------------+----------------------+-----------------+----------------+-----------------+-----------+---------------------+------+
| id | textMessage | textMessageVariables | referenceColumn | referenceValue | referenceSource | createdBy | createdAt | meta |
+----+-------------------------------+----------------------+-----------------+----------------+-----------------+-----------+---------------------+------+
| 1 | Data added (#%referenceCode%) | {"%referenceCode%":254} | id | 1 | surveys | 1 | 2022-02-14 15:41:58 | {} |
| 2 | Data added (#%referenceCode%) | {"%referenceCode%":354} | id | 2 | surveys | 1 | 2022-02-14 15:42:09 | {} |
| 3 | Data added (#%referenceCode%) | {"%referenceCode%":687} | id | 3 | surveys | 5 | 2022-02-15 09:42:36 | {} |
+----+-------------------------------+----------------------+-----------------+----------------+-----------------+-----------+---------------------+------+
期望的结果是能够使用 textMessageVariables 列中相应的 JSON 值替换 %referenceCode% 值,而不必专门声明每个替换,以便为 N 个变量保留通用解决方案.
提前致谢。
我终于能够修复它。
我构建了一个相当简单的函数,成功地解决了这个需求。
SQL函数:
DELIMITER ;;
DROP FUNCTION IF EXISTS strTemplateReplace;;
CREATE FUNCTION strTemplateReplace(templateText text, replacementJSON text) RETURNS text CHARSET utf8
BEGIN
DECLARE replacementKeys TEXT;
DECLARE replacementQty INT UNSIGNED DEFAULT 0;
DECLARE resultText TEXT;
DECLARE counterVar INT UNSIGNED DEFAULT 0;
DECLARE currentKey TEXT;
DECLARE currentValue TEXT;
SET replacementKeys = JSON_KEYS(replacementJSON);
SET replacementQty = JSON_LENGTH(replacementJSON);
SET resultText = templateText;
WHILE counterVar < replacementQty DO
SET currentKey = JSON_UNQUOTE(
JSON_EXTRACT(
replacementKeys,
CONCAT('$[', counterVar, ']')
)
);
SET currentValue = JSON_UNQUOTE(
JSON_EXTRACT(
replacementJSON,
CONCAT('$.', currentKey)
)
);
SET resultText = REPLACE(
resultText,
currentKey,
currentValue
);
SET counterVar = counterVar + 1;
END WHILE;
RETURN ( resultText );
END;;
DELIMITER ;
结果符合预期:
MariaDB [test_db]> SELECT id, textMessage, textMessageVariables, strTemplateReplace(textMessage, textMessageVariables) AS replacementResult FROM events_log LIMIT 3;
+----+-------------------------------+----------------------+------------------------+
| id | textMessage | textMessageVariables | replacementResult |
+----+-------------------------------+----------------------+------------------------+
| 1 | Data added (#%referenceCode%) | {"%referenceCode%":1} | Data added (#1) |
| 2 | Data added (#%referenceCode%) | {"%referenceCode%":2} | Data added (#2) |
| 3 | Data added (#%referenceCode%) | {"%referenceCode%":3} | Data added (#3) |
+----+-------------------------------+----------------------+------------------------+
3 rows in set (0.002 sec)
注意:在 10.5.13-MariaDB-1:10.5.13+maria~focal 环境中完美运行。
我尝试了一种方法,但未成功,即使用包含 JSON 的列的值来替换仅使用 SQL 查询功能的字符串段。
下面是一些示例数据:
MariaDB [test_db]> SELECT * FROM events_log LIMIT 3;
+----+-------------------------------+----------------------+-----------------+----------------+-----------------+-----------+---------------------+------+
| id | textMessage | textMessageVariables | referenceColumn | referenceValue | referenceSource | createdBy | createdAt | meta |
+----+-------------------------------+----------------------+-----------------+----------------+-----------------+-----------+---------------------+------+
| 1 | Data added (#%referenceCode%) | {"%referenceCode%":254} | id | 1 | surveys | 1 | 2022-02-14 15:41:58 | {} |
| 2 | Data added (#%referenceCode%) | {"%referenceCode%":354} | id | 2 | surveys | 1 | 2022-02-14 15:42:09 | {} |
| 3 | Data added (#%referenceCode%) | {"%referenceCode%":687} | id | 3 | surveys | 5 | 2022-02-15 09:42:36 | {} |
+----+-------------------------------+----------------------+-----------------+----------------+-----------------+-----------+---------------------+------+
期望的结果是能够使用 textMessageVariables 列中相应的 JSON 值替换 %referenceCode% 值,而不必专门声明每个替换,以便为 N 个变量保留通用解决方案.
提前致谢。
我终于能够修复它。 我构建了一个相当简单的函数,成功地解决了这个需求。
SQL函数:
DELIMITER ;;
DROP FUNCTION IF EXISTS strTemplateReplace;;
CREATE FUNCTION strTemplateReplace(templateText text, replacementJSON text) RETURNS text CHARSET utf8
BEGIN
DECLARE replacementKeys TEXT;
DECLARE replacementQty INT UNSIGNED DEFAULT 0;
DECLARE resultText TEXT;
DECLARE counterVar INT UNSIGNED DEFAULT 0;
DECLARE currentKey TEXT;
DECLARE currentValue TEXT;
SET replacementKeys = JSON_KEYS(replacementJSON);
SET replacementQty = JSON_LENGTH(replacementJSON);
SET resultText = templateText;
WHILE counterVar < replacementQty DO
SET currentKey = JSON_UNQUOTE(
JSON_EXTRACT(
replacementKeys,
CONCAT('$[', counterVar, ']')
)
);
SET currentValue = JSON_UNQUOTE(
JSON_EXTRACT(
replacementJSON,
CONCAT('$.', currentKey)
)
);
SET resultText = REPLACE(
resultText,
currentKey,
currentValue
);
SET counterVar = counterVar + 1;
END WHILE;
RETURN ( resultText );
END;;
DELIMITER ;
结果符合预期:
MariaDB [test_db]> SELECT id, textMessage, textMessageVariables, strTemplateReplace(textMessage, textMessageVariables) AS replacementResult FROM events_log LIMIT 3;
+----+-------------------------------+----------------------+------------------------+
| id | textMessage | textMessageVariables | replacementResult |
+----+-------------------------------+----------------------+------------------------+
| 1 | Data added (#%referenceCode%) | {"%referenceCode%":1} | Data added (#1) |
| 2 | Data added (#%referenceCode%) | {"%referenceCode%":2} | Data added (#2) |
| 3 | Data added (#%referenceCode%) | {"%referenceCode%":3} | Data added (#3) |
+----+-------------------------------+----------------------+------------------------+
3 rows in set (0.002 sec)
注意:在 10.5.13-MariaDB-1:10.5.13+maria~focal 环境中完美运行。