Is there a case insensitive
Replace for MySQL?
I'm trying to replace a user's old username with their new one within a paragraph text.
$targetuserold = "@".$mynewusername; $targetusernew = "@".$newusername; $sql = " UPDATE timeline SET message = Replace(message,'".$targetuserold."', '".$targetusernew."') "; $result = mysql_query($sql);
This is missing the instances where the old username is a different case. Example: replacing "Hank" with "Jack" in all the rows in my database will leave behind instances of "hank".
Here it is:
DELIMITER $$ DROP FUNCTION IF EXISTS `replace_ci`$$ CREATE FUNCTION `replace_ci` ( str TEXT,needle CHAR(255),str_rep CHAR(255)) RETURNS TEXT DETERMINISTIC BEGIN DECLARE return_str TEXT DEFAULT ''; DECLARE lower_str TEXT; DECLARE lower_needle TEXT; DECLARE pos INT DEFAULT 1; DECLARE old_pos INT DEFAULT 1; SELECT lower(str) INTO lower_str; SELECT lower(needle) INTO lower_needle; SELECT locate(lower_needle, lower_str, pos) INTO pos; WHILE pos > 0 DO SELECT concat(return_str, substr(str, old_pos, pos-old_pos), str_rep) INTO return_str; SELECT pos + char_length(needle) INTO pos; SELECT pos INTO old_pos; SELECT locate(lower_needle, lower_str, pos) INTO pos; END WHILE; SELECT concat(return_str, substr(str, old_pos, char_length(str))) INTO return_str; RETURN return_str; END$$ DELIMITER ;
$sql = " UPDATE timeline SET message = replace_ci(message,'".$targetuserold."', '".$targetusernew."') ";
An easier way that works without any stored function:
SELECT message, substring(comments,position(lower('".$targetuserold."') in message) ) AS oldval FROM timeline WHERE message LIKE '%".$targetuserold."%'
gives you the exact, case sensitive spellings of the username in all messages. As you seem to run that from a PHP script, you could use that to collect the spellings together with the corresponding IDs, and then run a simple
REPLACE(message,'".$oldval.",'".$targetusernew."') on that. Or use the above as sub-select:
UPDATE timeline SET message = REPLACE( message, (SELECT substring(comments,position(lower('".$targetuserold."') in message))), '".$targetusernew."' )
Works like a charm here.
Credits given to this article, where I got the idea from.
My solution ultimately was that I cannot do a case insensitive
However, I did find a workaround.
I was trying to have a feature where a user can change their username. The system would then need to update wherever
@oldusername was found in all the messages in the database.
The problem was... people wouldn't type other people's usernames in the correct case that it is found in the
members table. So when the user would change their username, it wouldn't catch those instances of
@oldSeRNAmE because of it not matching the case of the real format of the
I don't have permission with my GoDaddy shared server to do this with a customized SQL function, so I had to find a different way.
My solution: Upon inserting new messages into the database, whenever a username is found in the new message, I have an
UPDATE statement at that point to replace the username they typed with the correct formatted case that is found in the
members table. That way, if that person ever wants to change their username in the future, all the instances of that username in the database will all be the same exact formatted case. Problem solved.