265

Usually I use manual find to replace text in a MySQL database using phpmyadmin. I'm tired of it now, how can I run a query to find and replace a text with new text in the entire table in phpmyadmin?

Example: find keyword domain.com, replace with www.domain.com.

kqw
  • 17,649
  • 11
  • 61
  • 92
alyasabrina
  • 2,697
  • 3
  • 14
  • 7
  • Possible duplicate of http://stackoverflow.com/questions/639531/mysql-search-in-all-fields-from-every-table-from-a-database – sel Aug 07 '12 at 04:05
  • 1
    You can do some thing like [this][1]. [1]: http://stackoverflow.com/questions/562457/search-for-all-occurrences-of-a-string-in-a-mysql-database/10182498#10182498 – Pramod Apr 16 '13 at 06:50
  • 2
    [This](https://github.com/interconnectit/Search-Replace-DB) will help you achieve what you need. – Dom Aug 25 '14 at 20:07
  • Possible duplicate of [MySQL string replace](http://stackoverflow.com/questions/5956993/mysql-string-replace) – Steve Chambers Aug 02 '16 at 14:02

13 Answers13

605

For a single table update

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

From multiple tables-

If you want to edit from all tables, best way is to take the dump and then find/replace and upload it back.

swapnesh
  • 24,280
  • 22
  • 88
  • 122
  • 4
    Does this replace an entire field, or with it do a substring match within a field? – Randy Greencorn Nov 14 '13 at 21:09
  • 3
    It will replace a substring within the field @RandyGreencorn . It's also case-sensitive. – Andrew Aug 15 '16 at 20:34
  • 12
    and it will replace 'domain.com' with 'www.domain.com' and 'www.domain.com' with 'www.www.domain.com' – michelek Dec 16 '16 at 00:59
  • 1
    Worked for me when I dropped the single quotes – cdmo May 30 '17 at 12:28
  • 2
    More on this: `If you want to edit from all tables, best way is to take the dump and then find/replace and upload it back.` Use sed on the dump for the find/replace: `sed "s:unwanted_text:wanted_text:g" dump.sql` – kakoma Sep 02 '17 at 13:01
  • 1. Export to sql file 2. Find and replace 3. Import – Chicken Suop Oct 02 '17 at 11:55
  • 2
    Works great. As others have stated, sometimes I have to mess with the quotes to get it to work in phpMyAdmin. I used it to replace only the text "http:" with "https:" in a column containing full web addresses. The rest of the web addresses were untouched. – Heres2u Mar 20 '18 at 14:34
  • 1
    That's an awesome and super-fast solution! it has changed about 500 records in less than a second :) – Jodyshop Aug 27 '19 at 13:04
51

The easiest way I have found is to dump the database to a text file, run a sed command to do the replace, and reload the database back into MySQL.

All commands below are bash on Linux.

Dump database to text file

mysqldump -u user -p databasename > ./db.sql

Run sed command to find/replace target string

sed -i 's/oldString/newString/g' ./db.sql

Reload the database into MySQL

mysql -u user -p databasename < ./db.sql

Easy peasy.

siliconrockstar
  • 3,069
  • 33
  • 32
  • 3
    This works amazingly fast. I love this solution. I had to do some url replacements and instead of using slashes as my delimiters I used pipes instead (read this up http://www.grymoire.com/Unix/Sed.html). Example: sed -i 's|http://olddomain.com|http://newdomain.com|g' ./db.sql – Mike Kormendy Feb 09 '15 at 04:49
  • 1
    It was so fast i thought it didn't work. But it did! Also, you can just escape slashes like this: `\/\/domain.com` – m.cichacz Aug 25 '16 at 08:52
  • 2
    Just a reminder that in OS X, the `sed -i` command may throw out `unterminated substitute pattern` error. You can use `sed -i '' -e 's/oldString/newString/g' ./db.sql` instead. – afterglowlee Jan 31 '17 at 22:05
  • That's just great. I had one little backup, because we never know, just after the mysqldump : cp dl.sql db.sqlBACK – David N Nov 19 '20 at 15:46
27

Put this in a php file and run it and it should do what you want it to do.

// Connect to your MySQL database.
$hostname = "localhost";
$username = "db_username";
$password = "db_password";
$database = "db_name";

mysql_connect($hostname, $username, $password);

// The find and replace strings.
$find = "find_this_text";
$replace = "replace_with_this_text";

$loop = mysql_query("
    SELECT
        concat('UPDATE ',table_schema,'.',table_name, ' SET ',column_name, '=replace(',column_name,', ''{$find}'', ''{$replace}'');') AS s
    FROM
        information_schema.columns
    WHERE
        table_schema = '{$database}'")
or die ('Cant loop through dbfields: ' . mysql_error());

while ($query = mysql_fetch_assoc($loop))
{
        mysql_query($query['s']);
}
Lee Woodman
  • 1,279
  • 2
  • 16
  • 29
26

Running an SQL query in PHPmyadmin to find and replace text in all wordpress blog posts, such as finding mysite.com/wordpress and replacing that with mysite.com/news Table in this example is tj_posts

UPDATE `tj_posts`
SET `post_content` = replace(post_content, 'mysite.com/wordpress', 'mysite.com/news')
Hooked
  • 70,732
  • 35
  • 167
  • 242
guest
  • 261
  • 3
  • 2
  • 2
    Thanks for the query. For my WordPress site the column name is `wp_posts` so the query looks ``UPDATE `wp_posts` SET `post_content` = replace(post_content, 'mysite.com/wordpress', 'mysite.com/news')`` – Maris B. Jul 25 '18 at 12:39
10

Another option is to generate the statements for each column in the database:

SELECT CONCAT(
    'update ', table_name , 
    ' set ', column_name, ' = replace(', column_name,', ''www.oldDomain.com'', ''www.newDomain.com'');'
) AS statement
FROM information_schema.columns
WHERE table_schema = 'mySchema' AND table_name LIKE 'yourPrefix_%';

This should generate a list of update statements that you can then execute.

Kariem
  • 3,366
  • 2
  • 38
  • 57
Farid.O
  • 263
  • 3
  • 7
8
 UPDATE table SET field = replace(field, text_needs_to_be_replaced, text_required);

Like for example, if I want to replace all occurrences of John by Mark I will use below,

UPDATE student SET student_name = replace(student_name, 'John', 'Mark');
Umesh Patil
  • 3,595
  • 28
  • 22
5

phpMyAdmin includes a neat find-and-replace tool.

Select the table, then hit Search > Find and replace

This query took about a minute and successfully replaced several thousand instances of oldurl.ext with the newurl.ext within Column post_content

screenshot of the find-and-replace feature in phpMyAdmin

Best thing about this method : You get to check every match before committing.

N.B. I am using phpMyAdmin 4.9.0.1

youtag
  • 127
  • 2
  • 3
4

If you are positive that none of the fields to be updated are serialized, the solutions above will work well.

However, if any of the fields that need updating contain serialized data, an SQL Query or a simple search/replace on a dump file, will break serialization (unless the replaced string has exactly the same number of characters as the searched string).

To be sure, a "serialized" field looks like this:

a:1:{s:13:"administrator";b:1;}  

The number of characters in the relevant data is encoded as part of the data.
Serialization is a way to convert "objects" into a format easily stored in a database, or to easily transport object data between different languages.
Here is an explanation of different methods used to serialize object data, and why you might want to do so, and here is a WordPress-centric post: Serialized Data, What Does That Mean And Why is it so Important? in plain language.

It would be amazing if MySQL had some built in tool to handle serialized data automatically, but it does not, and since there are different serialization formats, it would not even make sense for it to do so.

wp-cli
Some of the answers above seemed specific to WordPress databases, which serializes much of its data. WordPress offers a command line tool, wp search-replace, that does handle serialization.
A basic command would be:

    wp search-replace 'an-old-string' 'a-new-string' --dry-run

However, WordPress emphasizes that the guid should never be changed, so it recommends skipping that column.
It also suggests that often times you'll want to skip the wp_users table.
Here's what that would look like:

wp search-replace 'https://old-domain.com' 'https://shiney-new-domain.com' --skip-columns=guid --skip-tables=wp_users --dry-run

Note: I added the --dry-run flag so a copy-paste won't automatically ruin anyone's database. After you're sure the script does what you want, run it again without that flag.

Plugins
If you are using WordPress, there are also many free and commercial plugins available that offer a gui interface to do the same, packaged with many additional features.

Interconnect/it php script
Interconnect/it offers a php script to handle serialized data: Safe Search and Replace tool. It was created for use on WordPress sites, but it looks like it can be used on any database serialized by PHP.
Many companies, including WordPress itself, recommends this tool. Instructions here, about 3/4 down the page.

SherylHohman
  • 12,507
  • 16
  • 70
  • 78
  • 1
    I just wanted to add that I hadn't come across the wp-cli before but thanks to your post, I've managed to migrate my site and access it successfully affter replacing the old url strings. – Huskie69 Jan 14 '21 at 11:23
2

I believe "swapnesh" answer to be the best ! Unfortunately I couldn't execute it in phpMyAdmin (4.5.0.2) who although illogical (and tried several things) it kept saying that a new statement was found and that no delimiter was found…

Thus I came with the following solution that might be usefull if you exeprience the same issue and have no other access to the database than PMA…

UPDATE `wp_posts` AS `toUpdate`,
(SELECT `ID`,REPLACE(`guid`,'http://old.tld','http://new.tld') AS `guid` 
 FROM `wp_posts` WHERE `guid` LIKE 'http://old.tld%') AS `updated`
SET `toUpdate`.`guid`=`updated`.`guid`
WHERE `toUpdate`.`ID`=`updated`.`ID`;

To test the expected result you may want to use :

SELECT `toUpdate`.`guid` AS `old guid`,`updated`.`guid` AS `new guid`
FROM `wp_posts` AS `toUpdate`,
(SELECT `ID`,REPLACE(`guid`,'http://old.tld','http://new.tld') AS `guid`
 FROM `wp_posts` WHERE `guid` LIKE 'http://old.tld%') AS `updated`
WHERE `toUpdate`.`ID`=`updated`.`ID`;
llange
  • 677
  • 1
  • 10
  • 14
1

the best you export it as sql file and open it with editor such as visual studio code and find and repalace your words. i replace in 1 gig file sql in 1 minutes for 16 word that total is 14600 word. its the best way. and after replace it save and import it again. do not forget compress it with zip for import.

Omid Ahmadyani
  • 1,012
  • 9
  • 13
1
UPDATE  `MySQL_Table` 
SET  `MySQL_Table_Column` = REPLACE(`MySQL_Table_Column`, 'oldString', 'newString')
WHERE  `MySQL_Table_Column` LIKE 'oldString%';
kheengz
  • 637
  • 6
  • 7
  • Worth noting that this will only work where the oldString is at the start of the value, so "1oldString2" would not be replaced, but "oldString2" would - to replace all instances you'll need LIKE '%oldString%' (note the additional %) – Aphire May 16 '21 at 13:26
0

Generate change SQL queries (FAST)

mysql -e "SELECT CONCAT( 'update ', table_name , ' set ', column_name, ' = replace(', column_name,', ''www.oldsite.com'', ''www.newsite.com'');' ) AS statement FROM information_schema.columns WHERE table_name LIKE 'wp_%'" -u root -p your_db_name_here > upgrade_script.sql

Remove any garbage at the start of the file. I had some.

nano upgrade_script.sql

Run generated script with --force options to skip errors. (SLOW - grab a coffee if big DB)

mysql -u root -p your_db_name_here --force < upgrade_script.sql

Community
  • 1
  • 1
Andy
  • 868
  • 10
  • 16
0

In the case of sentences with uppercase - lowercase letters, We can use BINARY REPACE

UPDATE `table_1`  SET  `field_1` =  BINARY REPLACE(`field_1`, 'find_string', 'replace_string')
Hoàng Vũ Tgtt
  • 1,318
  • 18
  • 6