2017-04-03 41 views
0

我有一組關鍵字,我想在表中任何一個列的表中進行更改。所以有一個主表和關鍵字表,它有兩列:要找到的關鍵字和要改變的關鍵字。因此,例如,有一排REGEXP基礎替換不在MySQL中工作過程

findtxt repltxt 有限公司$ 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,',?,','?) 

替換隻是不工作。在表

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 
+0

我懷疑你根本問題在於您將關鍵字存儲爲分隔列表,而不是將每個關鍵字排成一行。 –

+0

它在一張桌子上:我已編輯添加屏幕截圖。 – user1729972

+0

你認爲會發生一個像'BEAUTI SLIM'這樣的名字嗎?也許'BEAUTI SLIMITED'? –

回答

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) 
+0

謝謝,我會試一試,但我看到一個明顯的誤解。 'to_replace'表不會逐字地包含這些值。 sanecol專欄的公司名稱以不一致的方式編寫,例如記錄可能有MYCOMPANY LTD,HISCOMPANY LIMITED,THEIRCOMPANY LIM。正則表達式中的$是爲了隔離LIM和LTD出現在字段的末尾。這個過程因此應該從'關鍵字'表的'findtxt'列中取出一個通用的REGEX描述,並用相應的'repltxt'列取代統一的拼寫。在col – user1729972

+0

@ user1729972中將不會有$:Can你添加一些真實的樣本數據,你如何期待最終結果? – wchiquito

+0

HI我通過編輯原始文章添加了示例數據。它在底部。 – user1729972