3

我有两个表,即 ds_message 和 ds_params,第一个表包含模板,第二个表包含键值对

表结构: ds_message

_____________________________________________
id  template                                  
_____________________________________________
1  'Dear {a}, the price of {b} is {c}'       
2  'Dear {i}, you selected the product {j}'  

架构:

CREATE TABLE `ds_message` (
  `id` int NOT NULL,
  `template` varchar(500) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='';

ALTER TABLE `ds_message`
  ADD PRIMARY KEY (`id`);

INSERT INTO `ds_message` (`id`, `template`) VALUES
(1, 'Dear {a}, the price of {b} is {c}');

INSERT INTO `ds_message` (`id`, `template`) VALUES
(2, 'Dear {i}, you selected the product {j}');

表结构: ds_params

_________________________________________________
id   message_id    json_key    json_value
_________________________________________________
1    1             a         John
2    1             b         bat
3    1             c         $10
4    2             i         Emma
5    2             j         Jam

架构:

CREATE TABLE `ds_params` (
  `id` int NOT NULL,
  `message_id` int NOT NULL,
  `json_key` varchar(500) NOT NULL,
  `json_value` varchar(500) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COMMENT='';

ALTER TABLE `ds_params`
  ADD PRIMARY KEY (`id`);

INSERT INTO `ds_params` (`id`, `message_id`, `json_key`, `json_value`) VALUES
(1, 1, 'a', 'John');

INSERT INTO `ds_params` (`id`, `message_id`, `json_key`, `json_value`) VALUES
(2, 1, 'b', 'bat');

INSERT INTO `ds_params` (`id`, `message_id`, `json_key`, `json_value`) VALUES
(3, 1, 'c', '$10');

INSERT INTO `ds_params` (`id`, `message_id`, `json_key`, `json_value`) VALUES
(4, 2, 'i', 'Emma');

INSERT INTO `ds_params` (`id`, `message_id`, `json_key`, `json_value`) VALUES
(5, 2, 'j', 'Jam');

我需要替换表中的键(例如{a} => Johnds_message

我尝试了以下代码,

UPDATE ds_message AS t
INNER JOIN ds_params m ON m.message_id = t.id
    SET t.template = REPLACE(t.template, CONCAT('{', m.json_key , '}'), m.json_value);

一旦我执行了代码,我就会得到这样的输出,只有第一个键被替换,其余键不会更新。

_____________________________________________
id  template                                  
_____________________________________________
1   Dear John, the price of {b} is {c}
2   Dear Emma, you selected the product {j}

请帮助我如何做到这一点。

4

2 回答 2

1

我们有 2 个选项。

首先是使用while循环。

SET @n = 0;
SELECT COUNT(*) FROM ds_params INTO @n;
SET @i=0;
WHILE @i<@n DO 
    UPDATE ds_message AS t
    INNER JOIN ds_params m ON m.message_id = t.id AND m.id = @i 
    SET t.template = REPLACE(t.template, CONCAT('{', m.json_key , '}'), m.json_value)
    SET @i = @i + 1;
END WHILE;

第二个选项是这个。如果你有一个修复 json_key

UPDATE ds_message AS t
LEFT JOIN ds_params a ON a.message_id = t.id  and a.json_key='a'
LEFT JOIN ds_params b ON b.message_id = t.id  and b.json_key='b'
LEFT JOIN ds_params c ON c.message_id = t.id  and c.json_key='c'
LEFT JOIN ds_params i ON i.message_id = t.id  and i.json_key='i'
LEFT JOIN ds_params j ON j.message_id = t.id  and j.json_key='j'
SET t.template = REPLACE(REPLACE(REPLACE(
            REPLACE(REPLACE(t.template, CONCAT('{', IFNULL(a.json_key, '') , '}')
                         , IFNULL(a.json_value, '')),
              CONCAT('{', IFNULL(b.json_key, '') , '}'), IFNULL(b.json_value, '')),
              CONCAT('{', IFNULL(c.json_key, '') , '}'), IFNULL(c.json_value, '')),
              CONCAT('{', IFNULL(i.json_key, '') , '}') ,IFNULL(i.json_value, '')),
              CONCAT('{', IFNULL(j.json_key, '') , '}') ,IFNULL(j.json_value, ''));
于 2019-08-22T06:30:45.923 回答
1

您需要在此更新中执行循环。由于没有固定的键值对,所以最好找到最大的键值对来执行循环。

之后循环遍历每条记录,CURSOR以执行更新以将您的键替换为相应的值。由于您已经找到了密钥对的最大值,因此它只会执行到查询的最大循环限制。作为参考,您可以找到此链接以获取有关CURSOR的详细信息。


DECLARE  a, b VARCHAR(10);
  DECLARE cur1 CURSOR FOR SELECT DISTINCT json_key,json_value 
  FROM ds_params.t1;

  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    IF done THEN
      LEAVE read_loop;
    END IF;

UPDATE ds_message AS t
INNER JOIN ds_params m ON m.message_id = t.id
    SET t.template = REPLACE(t.template, CONCAT('{', m.json_key , '}'), m.json_value)
WHERE M.JSON_KEY = b  ;

  END LOOP;

  CLOSE cur1;


我不确定语法,但您可能会想到实现相同的方法。如果语法中的任何内容不正确,请更新相同的内容。

于 2019-08-22T07:07:33.967 回答