【问题标题】:Find and replace entire mysql database查找和替换整个mysql数据库
【发布时间】:2011-06-16 21:31:02
【问题描述】:

我想在整个数据库中进行查找和替换,而不仅仅是一个表。

我怎样才能改变下面的脚本来工作?

 update [table_name] set [field_name] = replace([field_name],'[string_to_find]','[string_to_replace]');

我只使用星号吗?

 update * set [field_name] = replace([field_name],'[string_to_find]','[string_to_replace]');

【问题讨论】:

  • 我不确定 MySQL 是否允许这样做,但我非常怀疑它是否会像一场重大的安全风暴一样等待发生。
  • 呵呵,好吧,问题是我不知道哪个表有信息,而且有一大堆表。
  • 要找出哪些表有数据,您可以运行整个数据库搜索,这将显示哪些表的数据符合您的搜索条件。在 phpmyadmin 中也去 /phpmyadmin/db_search.php

标签: mysql


【解决方案1】:

我在 MySQL 上遇到了同样的问题。我从 symcbean 获取程序,并根据我的需要调整了她。

我的只是替换文本值(或您在 SELECT FROM information_schema 中输入的任何类型),因此如果您有日期字段,则执行时不会出错。

注意 SET @stmt 中的排序规则,它必须与您的数据库排序规则相匹配。

我在具有多个替换的变量中使用了模板请求,但如果你有动力,你可以用一个 CONCAT() 来完成。

无论如何,如果您的数据库中有序列化数据,请不要使用它。除非您将字符串替换为具有相同长度的字符串,否则它将不起作用。

希望对某人有所帮助。

DELIMITER $$

DROP PROCEDURE IF EXISTS replace_all_occurences_in_database$$
CREATE PROCEDURE replace_all_occurences_in_database (find_string varchar(255), replace_string varchar(255))
BEGIN
  DECLARE loop_done integer DEFAULT 0;
  DECLARE current_table varchar(255);
  DECLARE current_column varchar(255);
  DECLARE all_columns CURSOR FOR
  SELECT
    t.table_name,
    c.column_name
  FROM information_schema.tables t,
       information_schema.columns c
  WHERE t.table_schema = DATABASE()
  AND c.table_schema = DATABASE()
  AND t.table_name = c.table_name
  AND c.DATA_TYPE IN('varchar', 'text', 'longtext');

  DECLARE CONTINUE HANDLER FOR NOT FOUND
  SET loop_done = 1;

  OPEN all_columns;

table_loop:
LOOP
  FETCH all_columns INTO current_table, current_column;
  IF (loop_done > 0) THEN
    LEAVE table_loop;
  END IF;
  SET @stmt = 'UPDATE `|table|` SET `|column|` = REPLACE(`|column|`, "|find|", "|replace|") WHERE `|column|` LIKE "%|find|%"' COLLATE `utf8mb4_unicode_ci`;
  SET @stmt = REPLACE(@stmt, '|table|', current_table);
  SET @stmt = REPLACE(@stmt, '|column|', current_column);
  SET @stmt = REPLACE(@stmt, '|find|', find_string);
  SET @stmt = REPLACE(@stmt, '|replace|', replace_string);
  PREPARE s1 FROM @stmt;
  EXECUTE s1;
  DEALLOCATE PREPARE s1;
END LOOP;
END
$$

DELIMITER ;

【讨论】:

    【解决方案2】:

    使用 REPLACE 命令替换时要小心!

    为什么?

    因为您的数据库很有可能包含序列化数据(尤其是 wp_options 表),因此仅使用“替换”可能会破坏数据。

    使用推荐的序列化:https://puvox.software/tools/wordpress-migrator

    【讨论】:

    • 不是一个糟糕的答案,你省了我一些头疼。
    • 我强烈建议避免使用此类工具来解决信任问题。但是,我用一个虚拟数据库对其进行了测试,但每次都失败了。
    【解决方案3】:

    这强烈暗示您的数据一开始就没有标准化。

    这样的东西应该可以工作(注意你没有提到你使用任何其他语言 - 所以它被写成 MySQL 存储过程)

     create procedure replace_all(find varchar(255), 
            replce varchar(255), 
            indb varcv=char(255))
     DECLARE loopdone INTEGER DEFAULT 0;
     DECLARE currtable varchar(100);
     DECLARE alltables CURSOR FOR SELECT t.tablename, c.column_name 
        FROM information_schema.tables t,
        information_schema.columns c
        WHERE t.table_schema=indb
        AND c.table_schema=indb
        AND t.table_name=c.table_name;
    
     DECLARE CONTINUE HANDLER FOR NOT FOUND
         SET loopdone = 1;
    
     OPEN alltables;
    
     tableloop: LOOP
        FETCH alltables INTO currtable, currcol; 
        IF (loopdone>0) THEN LEAVE LOOP;
        END IF;
             SET stmt=CONCAT('UPDATE ', 
                      indb, '.', currtable, ' SET ',
                      currcol, ' = word_sub(\'', find, 
                      '\','\'', replce, '\') WHERE ',
                      currcol, ' LIKE \'%', find, '%\'');
             PREPARE s1 FROM stmt;
             EXECUTE s1;
             DEALLOCATE PREPARE s1;
         END LOOP;
     END //
    

    我会留给你解决如何声明 word_sub 函数。

    【讨论】:

      【解决方案4】:

      在 word-press mysql Query 中将旧 URL 更新为新 URL:

      UPDATE wp_options SET option_value = replace(option_value, 'http://olddomain.com', 'http://newdomain.com') WHERE option_name = 'home' OR option_name = 'siteurl';
      
      UPDATE wp_posts SET guid = replace(guid, 'http://olddomain.com','http://newdomain.com');
      
      UPDATE wp_posts SET post_content = replace(post_content, 'http://olddomain.com', 'http://newdomain.com');
      
      UPDATE wp_posts SET post_excerpt = replace(post_excerpt, 'http://olddomain.com', 'http://newdomain.com');
      
      UPDATE wp_postmeta SET meta_value = replace(meta_value, 'http://olddomain.com', 'http://newdomain.com');
      

      【讨论】:

      • 不要忘记 wp_posts 表下的 post_excerpt 列:UPDATE wp_posts SET post_excerpt = replace(post_excerpt, 'http://olddomain.com', 'http://newdomain.com');
      【解决方案5】:

      如果您在 phpMyAdmin 中并且只有很小的更改,您可以轻松地做到这一点。

      • 登录到您的 phpMyAdmin
      • 选择您需要执行更改的数据库
      • 点击搜索选项

      您始终可以选择所有表格或任何表格。记得给搜索关键字,它将用作通配符(%)。

      • 现在点击开始。
      • 这将为您提供包含您拥有的项目的所有表格 搜索。

      • 现在您可以一一打开每个表并执行更新 生成的示例查询可能如下所示。

        SELECT * FROM sibeecst_passion.wp_ewwwio_images WHERE (CONVERT(id USING utf8) LIKE '%sibee%' OR CONVERT(path USING utf8) LIKE '%sibee%' OR CONVERT(image_md5 USING utf8) LIKE '%sibee%' OR CONVERT(results USING utf8) LIKE '%sibee%' OR CONVERT(gallery USING utf8) LIKE '%sibee%' OR CONVERT(image_size USING utf8) LIKE ' %sibee%' OR CONVERT(orig_size USING utf8) LIKE '%sibee%' OR CONVERT(updates USING utf8) LIKE '%sibee%' OR CONVERT(updated USING utf8) LIKE '%sibee%' 或CONVERT(trace USING utf8) LIKE '%sibee%' OR CONVERT(attachment_id USING utf8) LIKE '%sibee%' OR CONVERT(resize USING utf8) LIKE '%sibee%' OR CONVERT(converted USING utf8) LIKE '%sibee%' OR CONVERT(level USING utf8) LIKE '%sibee%' OR CONVERT(pending USING utf8) LIKE '%sibee%' OR CONVERT(backup USING utf8) LIKE ' %sibee%')

      【讨论】:

        【解决方案6】:

        sqldump 到文本文件,查找/替换,重新导入 sqldump。

        将数据库转储到文本文件
        mysqldump -u root -p[root_password] [database_name] > dumpfilename.sql

        对数据库进行更改后恢复它。
        mysql -u root -p[root_password] [database_name] < dumpfilename.sql

        【讨论】:

        • 是的,这对我也有用。我可以在此处添加执行此操作的命令吗: 备份:# mysqldump -u root -p[root_password] [database_name] > dumpfilename.sql restore:# mysql -u root -p[root_password] [database_name] ...的方向还有,-p 和密码之间没有空格
        • 除非你有一个无法在普通文本编辑器上打开的沉重数据库。
        • 如果你在 linux 上,你可以使用 sed 来进行搜索替换(或者可能是 awk...这些不关心你的文件有多大。)
        • 但如果数据库大小为 2.04 GB,这将无用
        • 这是可以的过程除非你有一些序列化的数据 - 例如WordPress 小部件 :) 计数检查存在问题 :)
        【解决方案7】:

        我只是想分享一下我是如何使用 sql 数据库进行查找/替换的,因为我需要替换 Chrome 的 sessionbuddy db 文件中的链接。

        • 所以我使用 SQLite 将 sql 数据库文件导出为 .txt 文件 数据库浏览器 2.0 b1
        • 在记事本++中查找/替换
        • 将 .txt 文件重新导入到 SQLite Database Browser 2.0 b1

        【讨论】:

          【解决方案8】:

          另一种选择(取决于用例)是使用 DataMystic 的 TextPipeDataPipe 产品。我过去使用过它们,它们在复杂的替换场景中表现出色,并且无需从数据库中导出数据以进行查找和替换。

          【讨论】:

          • Snobby 管理员(那些会在旧 UNIX 论坛上告诉用户“RTFM”的人)投票否决可行的答案。对于无法转储/恢复整个数据库并且搜索/替换操作足够复杂以至于无法通过简单的 SQL 完成(或者所需的 SQL 超出用户能力的情况)的特定用例,这是一个完美的解决方案)。如果您投反对票,请至少发布您的投诉并给出答案!
          【解决方案9】:

          MySQL Search & Replace Tool

          用 PHP 编写的非常有用的基于 Web 的工具,可以轻松搜索和替换 MySQL 数据库中的文本字符串。

          【讨论】:

            【解决方案10】:

            简单的解决方案

            UPDATE `table_name`
             SET `field_name` = replace(same_field_name, 'unwanted_text', 'wanted_text')
            

            【讨论】:

              【解决方案11】:

              这是不可能的 - 您需要为每个表单独执行更新。

              警告:可疑,但它会工作(可能)解决方案如下

              或者,您可以通过mysqldump 转储数据库,然后简单地对生成的 SQL 文件执行搜索/替换。 (我建议在此过程中脱机任何可能触及数据库的内容,以及使用 --add-drop-table 和 --extended-insert 标志。)但是,您需要确保搜索/替换文本不会改变数据本身以外的任何内容(即:您要换出的文本可能不会作为 SQL 语法的一部分出现)并且 我真的会尝试重新- 首先插入一个空的测试数据库。)

              【讨论】:

                【解决方案12】:

                简短的回答:你不能。

                长答案:您可以使用INFORMATION_SCHEMA 来获取表定义并使用它来动态生成必要的 UPDATE 语句。例如你可以从这个开始:

                SELECT TABLE_NAME, COLUMN_NAME
                FROM INFORMATION_SCHEMA.COLUMNS
                WHERE TABLE_SCHEMA = 'your_schema'
                

                如果可能的话,我会尽量避免这样做。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2013-06-18
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-12-08
                  • 2021-02-07
                  相关资源
                  最近更新 更多