查找和替换整个mysql数据库
Posted
技术标签:
【中文标题】查找和替换整个mysql数据库【英文标题】:Find and replace entire mysql database 【发布时间】: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 How to search and replace all instances of a string within a database?的可能重复 【参考方案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 查询中将旧 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%' OR 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 的 TextPipe 和 DataPipe 产品。我过去使用过它们,它们在复杂的替换场景中表现出色,并且无需从数据库中导出数据以进行查找和替换。
【讨论】:
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'
如果可能的话,我会尽量避免这样做。
【讨论】:
以上是关于查找和替换整个mysql数据库的主要内容,如果未能解决你的问题,请参考以下文章