View Full Version : Query MySQL database to globally search/replace
the_pm
April 20th, 2006, 16:17
Hey everyone,
How would you create a query that searches for and replaces all instances of a string in a MySQL database? I have some characters from a document I used for a database that were created in Word, and will not display properly. I need to replace them with proper HTML equivalents.
Help please :)
Christopher Lee
April 20th, 2006, 17:42
I know there is a REPLACE function in MySQL. I'm going to mess with it to see what I can come up with
jos
April 20th, 2006, 18:25
I don't know how your database looks like but you can solve it several ways, with some PHP...
using str_replace(). Is your complete database full with these characters or just one cell? (or a few)?
the_pm
April 20th, 2006, 19:33
I dunno. There are a few different characters, and they are spread out throughout the entire database. I'm not entirely sure where they all reside. So, it's just a few cells, but I'll be damned if I know which few cells they are!
Christopher Lee
April 20th, 2006, 19:49
This code assumes that you have one column in your table that you need cleaned.
Here are two alternate solutions.
$pairs = array('link'=>'hypershooter', 'another'=>'Batooter');
foreach($pairs as $original=>$replacement){
$strSQL = "
UPDATE jbo SET linktext =
REPLACE(linktext, '$original', '$replacement')
";
$rs = @mysql_query($strSQL, $c) or die("<p>Couldn't run query</p>
<p><strong>$strSQL</strong></p> <p>". mysql_error() . "</p>");
echo $strSQL . '<br>';
}
or, via PHP:
$original = array('link', 'another'); //note the diff
$replacement = array('hypershooter', 'batooter'); //note the diff
$strSQL = "SELECT id, linktext FROM jbo";
$rs = @mysql_query($strSQL, $c) or die("<p>Couldn't run query</p> <p><strong>$strSQL</strong></p> <p>". mysql_error() . "</p>");
if(0 == mysql_num_rows($rs)){
echo 'Nothing to replace!';
}else{
while($line = mysql_fetch_array($rs)){
$tmp = $line['linktext'];
$tmp = str_replace($original, $replacement, $tmp);
$child_sql = "UPDATE jbo SET linktext='$tmp' WHERE id=".$line['id'];
$child_rs = @mysql_query($child_sql, $c) or die("<p>Couldn't run query</p> <p><strong>$strSQL</strong></p> <p>". mysql_error() . "</p>"); //child_rs is here if you want rows affected.
echo $child_sql . '<br>';
}
}
The table structure is from an earlier post on this board (not sure if the number I jotted down was topic or post: 43169).
CREATE TABLE `jbo` (
`id` bigint(20) NOT NULL auto_increment,
`title` varchar(255) NOT NULL default '',
`date` date NOT NULL default '0000-00-00',
`intro` text NOT NULL,
`image` varchar(255) NOT NULL default '',
`link` varchar(255) NOT NULL default '',
`linktext` varchar(255) NOT NULL default '',
PRIMARY KEY (`id`)
) TYPE=MyISAM AUTO_INCREMENT=12 ;
--
-- Dumping data for table `jbo`
--
INSERT INTO `jbo` VALUES (1, 'Article 1', '2006-03-21', 'This is the intro to article one', 'http://example.com/cl/templates/c/bg.gif', 'index.php', 'Go to index');
INSERT INTO `jbo` VALUES (2, 'Article 2', '2006-03-22', 'This is article two. How do you like it.', 'http://example.com/cl/templates/c/bg.gif', 'index.php', 'another link to the homepage');
INSERT INTO `jbo` VALUES (3, 'Article 3', '2006-03-22', 'Yet the 3rd', 'http://example.com/cl/templates/c/bg.gif', 'sitemap.php', 'Hah, a link to the sitemap');
INSERT INTO `jbo` VALUES (4, 'Fourth', '2006-03-22', 'adfbl;kfnb;lknwergv', 'image_missing.gif', 'oldskool.asp', 'A link to old skool');
INSERT INTO `jbo` VALUES (5, 'Fifth Article', '2006-03-22', 'Woo, the 5th', 'http://example.com/cl/templates/c/bg.gif', 'index.php', 'another link to the homepage');
INSERT INTO `jbo` VALUES (6, 'Sixth', '2006-03-22', 'This is where it should start messing up?', 'http://example.com/cl/templates/c/bg.gif', 'sitemap.pl', 'A perl sitemap!!!');
INSERT INTO `jbo` VALUES (7, 'Seventh', '2006-03-22', 'Blarg', 'http://example.com/cl/templates/c/bg.gif', 'index.php', 'another link to the homepage');
INSERT INTO `jbo` VALUES (8, 'eight 888', '2006-03-22', 'Sigh, almost done', 'http://example.com/cl/templates/c/bg.gif', 'sitemap.pl', 'A perl sitemap!!!');
INSERT INTO `jbo` VALUES (9, 'nine', '2006-03-22', 'Ninty', 'http://example.com/cl/templates/c/bg.gif', 'index.php', 'another link to the homepage');
INSERT INTO `jbo` VALUES (10, 'tenth', '2006-03-22', 'almost done', 'http://example.com/cl/templates/c/bg.gif', 'sitemap.pl', 'A perl sitemap!!!');
INSERT INTO `jbo` VALUES (11, 'eleventh', '2006-03-22', 'Does this work, PLZ!>?', 'http://example.com/cl/templates/c/bg.gif', 'index.php', 'another link to the homepage');
I like the first one: more compact, but YMMV :)
Christopher Lee
April 20th, 2006, 19:57
Oh, I forgot to mention that both solutions are case sensitive, although PHP5 offers str_ireplace. I also think you could use a regular expression in the mix both in PHP & MySQL, but I wanted to get something quick -n- dirty if you needed it fast.
the_pm
April 20th, 2006, 20:06
The actual strings to be replaced are special characters that Word generates. I wonder if this will be a problem...
Christopher Lee
April 20th, 2006, 20:34
Hmm, I'm not sure I understand the question correctly. Could you provide an example?
Christopher Lee
April 20th, 2006, 20:59
I'm going to pre-emptively answer: There might be some control characters that you can't strip. Since .doc is a proprietary system, those codes don't appear to be readily available. Some resources
http://en.wikipedia.org/wiki/.doc
Proprietary DOC files often contain more text formatting information (as well as scripts and undo information) than files using other document file formats...
Its use in document exchange is also a bone of contention for some folks:
http://www.goldmark.org/netrants/no-word/attach.html
There are command-line converters for Linux that can convert it to plain text:
http://www.linux.com/article.pl?sid=06/02/22/201247
Although, if you are a windows user, you can 'Save As' and change the document to plain text, html (messy as it is), or rdf.
Does the app require that you directly save from word to the dB?
jos
April 20th, 2006, 21:06
next time make sure you copy/paste it into a .txt first :D
the_pm
April 20th, 2006, 21:09
Yeah, yeah, I know. But now that I have about four thousands entries into a database, I was kind of hoping I wouldn't have to go and edit them one at a time :(
Christopher Lee
April 20th, 2006, 21:16
Well...you could put all of the characters that you want to preserve into an array, then loop through each character and if it isnt in the array, replace it with nothing.
Dan
April 20th, 2006, 21:25
At worst, I could write a script that selects every row, does the replacements on it, and then inserts each one back into the db, but if anyone knows of a simple query that could do it, that would probably be better.
the_pm
April 20th, 2006, 21:26
That might work if it was just one offending character, but there are four I've identified at this point, left quote, right quote, apostrophe and long dash :(
Dan
April 20th, 2006, 21:47
Doing more than one is completely possible.
Christopher Lee
April 20th, 2006, 22:13
$pairs = array(chr(146)=>"'", chr(147)=>'"', chr(148)=>'"', chr(151)=>'-');
You could try this in my first solution. I think that should take care of those 4 for you.
Christopher Lee
April 20th, 2006, 22:15
Oh, and always make a backup, if you're running this on production code.
vBulletin® v3.6.8, Copyright ©2000-2012, Jelsoft Enterprises Ltd.