mysql - 基于 REGEX 的替换在 MySQL 过程中不起作用

标签 mysql regex stored-procedures replace prepared-statement

我有一组关键字,我想在表格的列中更改它们出现的位置。因此,有一个主表和关键字表,其中有 2 列:要查找的关键字以及将其更改为的内容。例如,有一行用于

findtxt repltxt 有限公司$ 有限公司

然后我有一个过程,其中重要部分引用如下:

DECLARE cur1 CURSOR FOR SELECT findtxt,repltxt FROM keywords ;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;
SET done = 0;
OPEN cur1;

myLoop: LOOP
    FETCH cur1 INTO ftxt,rtxt;      
    IF done = 1 THEN 
        LEAVE igmLoop; 
    END IF;
    SET @t1 = CONCAT('UPDATE ',tbl,' SET ',sanecol,' = REPLACE(',sanecol,',?,','?) WHERE ',sanecol,' REGEXP ?'); 

    PREPARE stmt FROM @t1;

    SET @ftxt = ftxt;
    SET @rtxt = rtxt;
    EXECUTE stmt USING @ftxt,@rtxt,@ftxt; 
    DEALLOCATE PREPARE stmt;
END LOOP myLoop;
CLOSE cur1;

sanecol 和 tbl 作为参数传递到代表要更改的列和具有该列的表的过程中。

此过程循环遍历所有记录(我知道,因为这需要一段时间),但最终没有错误。但关键字并未更改(例如 LTD 不会变为 LIMITED。)

我做错了什么?

我已经测试过通过

来隔离问题
SET @t2 = CONCAT('UPDATE ',tbl,' SET idd = 1 WHERE ',sanecol,' REGEXP ?'); 

其中 idd 只是创建的一个测试标志,以确保 REGEXP 正常工作。它确实是通过将 LIM 或 LTD 的每个记录的 idd 列设置为 1。

所以问题确实出在这部分代码上:

CONCAT('UPDATE ',tbl,' SET ',sanecol,' = REPLACE(',sanecol,',?,','?)

REPLACE 不起作用。

enter image description here

要替换的表中的示例数据

id        replacecol
1         FOREVER UNITED LTD
2         APPLE DEVICES LIMITED
3         QUICKFIX DESIGNS LIM
4         FINANCIAL TIMES LTD

这应该更改为:

id        replacecol
1         FOREVER UNITED LIMITED
2         APPLE DEVICES LIMITED
3         QUICKFIX DESIGNS LIMITED
4         FINANCIAL TIMES LIMITED

最佳答案

尝试如下:

mysql> DROP PROCEDURE IF EXISTS `sp_test`;
Query OK, 0 rows affected (0.00 sec)

mysql> DROP TABLE IF EXISTS `keywords`, `to_replace`;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE IF NOT EXISTS `to_replace` (
    ->  `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    ->  `text` VARCHAR(255) NOT NULL
    -> );
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE TABLE IF NOT EXISTS `keywords` (
    ->  `id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    ->  `regexptxt` VARCHAR(255) NOT NULL,
    ->  `findtxt` VARCHAR(255) NOT NULL,
    ->  `repltxt` VARCHAR(255) NOT NULL
    -> );
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO `to_replace` (`text`)
    ->  VALUES ('LTD$ AAAA'),
    ->         ('BBBB LIM$'),
    ->         ('AAAA LTD$ LIM$ BBBB'),
    ->         ('FOREVER UNITED LTD'),
    ->         ('APPLE DEVICES LIMITED'),
    ->         ('QUICKFIX DESIGNS LIM'),
    ->         ('FINANCIAL TIMES LTD'),
    ->         ('BEAUTI SLIM'),
    ->         ('FINANCIAL TIMES LTD & FOREVER UNITED LTD'),
    ->         ('FOREVER UNITED LTD & QUICKFIX DESIGNS LIM');
Query OK, 10 rows affected (0.00 sec)
Records: 10  Duplicates: 0  Warnings: 0

mysql> INSERT INTO `keywords`
    ->    (`regexptxt`, `findtxt`, repltxt)
    ->  VALUES
    ->    (' LTD$', 'LTD', 'LIMITED'),
    ->    (' LIM$', 'LIM', 'LIMITED');
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> DELIMITER //

mysql> CREATE PROCEDURE `sp_test`(`tbl` VARCHAR(64), `sanecol` VARCHAR(64))
    ->  BEGIN
    ->    DECLARE `done` BOOL DEFAULT FALSE;
    ->    DECLARE `retxt`, `ftxt`, `rtxt` VARCHAR(255) DEFAULT '';
    ->  
    ->    DECLARE `cur1` CURSOR FOR
    ->    SELECT `regexptxt`, `findtxt`, `repltxt`
    ->    FROM `keywords`;
    ->  
    ->    DECLARE CONTINUE HANDLER FOR NOT FOUND SET `done` := TRUE;
    ->  
    ->    OPEN `cur1`;
    ->  
    ->    `myLoop`: LOOP
    ->      FETCH `cur1` INTO `retxt`, `ftxt`, `rtxt`;
    ->      IF `done` THEN
    ->        CLOSE `cur1`;
    ->        LEAVE `myLoop`;
    ->      END IF;
    ->  
    ->      SET @`t1` = CONCAT('UPDATE `', `tbl`,'`
    '>                          SET `', `sanecol`, '` = REPLACE(`', `sanecol`, '`, ?, ?)
    '>                          WHERE `', `sanecol`, '` REGEXP ?');
    ->      PREPARE `stmt` FROM @`t1`;
    ->      SET @`ftxt` = `ftxt`,
    ->          @`rtxt` = `rtxt`,
    ->          @`retxt` = `retxt`;
    ->      EXECUTE `stmt` USING @`ftxt`, @`rtxt`, @`retxt`;
    ->      DEALLOCATE PREPARE `stmt`;
    ->    END LOOP `myLoop`;
    ->  END//
Query OK, 0 rows affected (0.00 sec)

mysql> DELIMITER ;

mysql> SELECT `id`, `text`
    ->  FROM `to_replace`;
+----+-------------------------------------------+
| id | text                                      |
+----+-------------------------------------------+
|  1 | LTD$ AAAA                                 |
|  2 | BBBB LIM$                                 |
|  3 | AAAA LTD$ LIM$ BBBB                       |
|  4 | FOREVER UNITED LTD                        |
|  5 | APPLE DEVICES LIMITED                     |
|  6 | QUICKFIX DESIGNS LIM                      |
|  7 | FINANCIAL TIMES LTD                       |
|  8 | BEAUTI SLIM                               |
|  9 | FINANCIAL TIMES LTD & FOREVER UNITED LTD  |
| 10 | FOREVER UNITED LTD & QUICKFIX DESIGNS LIM |
+----+-------------------------------------------+
10 rows in set (0.00 sec)

mysql> CALL `sp_test`('to_replace', 'text');
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT `id`, `text`
    ->  FROM `to_replace`;
+----+--------------------------------------------------+
| id | text                                             |
+----+--------------------------------------------------+
|  1 | LTD$ AAAA                                        |
|  2 | BBBB LIM$                                        |
|  3 | AAAA LTD$ LIM$ BBBB                              |
|  4 | FOREVER UNITED LIMITED                           |
|  5 | APPLE DEVICES LIMITED                            |
|  6 | QUICKFIX DESIGNS LIMITED                         |
|  7 | FINANCIAL TIMES LIMITED                          |
|  8 | BEAUTI SLIM                                      |
|  9 | FINANCIAL TIMES LIMITED & FOREVER UNITED LIMITED |
| 10 | FOREVER UNITED LTD & QUICKFIX DESIGNS LIMITED    |
+----+--------------------------------------------------+
10 rows in set (0.00 sec)

关于mysql - 基于 REGEX 的替换在 MySQL 过程中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43182710/

相关文章:

sql - 使用循环 Oracle 为每个 ID 遍历的完整路径

java - AWS rds - 如何从 Java 应用程序内的只读副本读取?

javascript - 在 Javascript 中使用正则表达式仅检索匹配字符串的一部分

sql-server - 甲骨文数据库 : Return second query if first query is empty

regex - =~ 函数参数按相反顺序排列

regex - $regex 与 find() 和 update() mongoose 的工作方式不同

c# - 在 LINQ to SQL 中将枚举值作为存储过程(数据函数)参数传递

php - 如何在 Laravel 中修复 "Database (database.sqlite) does not exist."?

MySQL 错误 "Unknown column in ' 字段列表'"

mysql - 为什么分组依据和排序依据给出 0 响应