搜索表格中的所有列

时间:2014-05-22 23:41:33

标签: mysql stored-procedures

我想要一个程序,搜索所有列中的非键盘ascii字符(12月16日至12月31日或DLE到美国),并通过用空格' '或空格''替换它来更新列

我有一个SELECT语句,它找到了我需要更新的行,但我必须自己手动更改所有列。

SELECT column_name
FROM table_name
WHERE column_name REGEXP '[[.DLE.]-[.US.]]'

以下是用于修改列值的UPDATE脚本

UPDATE table
SET
column = replace(column,char(16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31), '')

我希望将这两者融合到一个函数或存储过程中,但我不知道如何,因为我刚开始学习MySQL。

1 个答案:

答案 0 :(得分:1)

<强>声明

在使用REGEXPCURSOR循环遍历每个表和列之间,这些示例不会是闪电般快速的。速度显然会根据您的环境而有所不同,我建议在开发前对其进行测试

一个表格中的一列

要搜索单个表格中的单个列,您根本需要UPDATE

UPDATE t1
SET
column_name = replace(column_name, 
  char(16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31), '')
WHERE column_name REGEXP '[[.DLE.]-[.US.]]'

一个表格中的所有列

要执行表格中的所有列,您需要识别表格,然后循环遍历列using a cursor

DELIMITER $$
CREATE PROCEDURE table_regexp_replace(in_table VARCHAR(128))
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE search_column VARCHAR(64);

  DECLARE cur1 CURSOR FOR
    SELECT DISTINCT `COLUMN_NAME` FROM `information_schema`.`COLUMNS`
      WHERE `TABLE_NAME` = in_table ORDER BY `ORDINAL_POSITION` ;

  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;

  read_loop: LOOP
    -- Process the next column
    FETCH cur1 INTO search_column;

    -- If we're done, stop the loop
    IF done THEN
      LEAVE read_loop;
    END IF;

    -- Replace everything in this column matching the regexp
    SET @new_query := CONCAT ('UPDATE ', in_table, 
        ' SET `', search_column, '` = replace(', search_column, 
          ', char(16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31), \'\')
        WHERE ', search_column, ' REGEXP \'[[.DLE.]-[.US.]]\'') ;

    PREPARE stmt FROM @new_query;
    EXECUTE stmt ;
  END LOOP;

  CLOSE cur1;
END$$

DELIMITER ;

然后使用

CALL table_regexp_replace('my_table');

工作原理

看起来很复杂,实际上很直接。

  1. 我们使用一个参数in_table创建一个过程,用于指定要使用的表。
  2. 设置一个游标,以正确的顺序从information_schema表中提取列名称
  3. 遍历每个列,对每个列执行手动创建的UPDATE语句。
  4. 您会在UPDATE查询中的任何地方发现需要引号的内容,但必须使用\对其进行转义。

    \'[[.DLE.]-[.US.]]\'
    

    所有表格中的所有列

    然后,您可以使用与上面类似的方法在所有表的循环中使用此过程。以下是您从information_schema

    中提取所有表名的方法

    information_schema选择DISTINCT TABLE_NAME。TABLES   在TABLE_SCHEMA =&#39; your_database_name&#39;;