REGEXP Bases替换不在MySQL过程中工作

时间:2017-04-03 10:51:57

标签: mysql regex stored-procedures replace prepared-statement

我想在一个表的列中更改一组关键字,无论它们出现在哪里。所以有一个主表和关键字表有2列:要查找的关键字和要更改的内容。例如,

有一行

findtxt repltxt  LTD $ LIMITED

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

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不会变成有限的。)

我做错了什么?

我已通过

测试来隔离问题
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

1 个答案:

答案 0 :(得分:1)

尝试类似:

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)