MySQL: Why aren't url's matching when using REPLACE? - mysql

My Situation:
I have url's in a field containing blog posts. The url's are being stored in my database with escape characters. My task at the moment is to replace some already inserted 'http' url's with 'https' url's, but REPLACE will match neither the original url nor the escaped url. I can't just replace every instance of 'http:', because I only want to affect certain links in each post, not every link.
I am very familiar with SQL, as well as REPLACE, so I'm not just asking how REPLACE works and how to use it. Another user here has tested my queries in his environment and they work. So, there must be something in my configuration that is preventing the queries from functioning as expected.
I have searched this site and google extensively for several hours and have found nothing specifically addressing my issue. Everything I have tried is included below and if there is something else I should try, I don't know what that is and I haven't found any suggestions/posts/comments that suggest doing anything differently.
Example URL:
http://test01.mysite.com
As Stored in DB:
http:\/\/test01.mysite.com
Code to Re-Create Situation:
DROP TABLE IF EXISTS test_posts;
CREATE TABLE IF NOT EXISTS test_posts (
id int NOT NULL AUTO_INCREMENT,
post_content longtext NOT NULL,
PRIMARY KEY (id)
)
INSERT INTO
test_posts
(post_content)
VALUES
('content content content Link I want to change content content content Link I don\'t want to change content content content Link I want to change content content content Link I don\'t want to change');
If I run
UPDATE
test_posts
SET
post_content = REPLACE(post_content, 'http://test01.mysite.com', 'https://test01.mysite.com');
or
UPDATE
test_posts
SET
post_content = REPLACE(post_content, 'http:\/\/test01.mysite.com', 'https://test01.mysite.com');
zero records are affected.
For testing purposes, I ran the following query which returns 0 rows.
SELECT
*
FROM
test_posts
WHERE
post_content LIKE '%http://test01.mysite.com%'
OR
post_content LIKE '%http:\/\/test01.mysite.com%'
OR
post_content LIKE '%http:\\/\\/test01.mysite.com%'
OR
post_content LIKE 'http:%/%/test01.mysite.com%';
If I run:
SELECT
*
FROM
test_posts
WHERE
post_content LIKE '%http:_/_/test01.mysite.com%'
It does return matches, but that doesn't solve the real problem of how to match when using UPDATE/REPLACE.
I have tried on two different servers and I get the same results on both.
I have tried the following Engine/Collation combinations and all return the same 0 records results:
MyISAM/latin1_swedish_ci
MyISAM/utf8mb4_unicode_ci
InnoDB/latin1_swedish_ci
InnoDB/utf8mb4_unicode_ci
Anybody know how I can write these queries so that REPLACE will find matches to those url's or what settings in my database or PhpMyAdmin may be causing the queries to return/affect 0 rows?

I think the backslash must be escaped in MySQL
field_name LIKE 'http:\\/\\/test01.mysite.com%'
Of course one could go for sure and use the single char wildcard __
field_name LIKE 'http:_/_/test01.mysite.com%'
or for your both cases: an optional backslash:
field_name LIKE 'http:%/%/test01.mysite.com%'

I'm still baffled as to why the queries with LIKE won't work, but, sadly, using those to narrow down the problem clouded my judgement and I didn't try all the same combinations in the REPLACE functions.
The following works:
UPDATE
test_posts
SET
post_content = REPLACE(post_content, 'http:\\/\\/test01.mysite.com', 'https://test01.mysite.com');
If anyone can explain to me why these combinations work with REPLACE, but not with LIKE, I'd really love to know. Thanks!

There is no reason, your query won't work if you have run properly, there is something else, you may be missing here.
UPDATE
test1
SET
name_1 = REPLACE(name_1, 'http:\/\/test01.mysite.com', 'https://test01.mysite.com')
works well and does the job of repalcing the \/ with /.
See screen-shot attached,
You may have some other problem, please check and update the question, if so.
Edit after comments
If you have more data points in URL, change query like below.
UPDATE
test1
SET
name_1 = REPLACE(name_1, '\/', '/')
Above will replace all the occurrence of \/ with /.

As \\ did not work to represent/escape a backslash, use regular expression functions:
REGEXP_LIKE('.*http:\\/\\/test01\.mysite.com.*')
REGEXP_REPLACE(field, 'http:\\/\\/', 'http://')
Here \\ should work.

Related

Replacing a string that start with and end with in phpmyadmin

I'm trying to update a particular url in wordpress post_content table. I have over 5000 differents urls to update for a single same one.
So in clear I have 5000 urls that all starts with :
domain.com/params.php?....
AND always ends with :
?e=
I want all those url to be replace with a single one without parameters in so they will all send to domain.com/page.html
So is there a way to replace all the urls without having to manually doing it ?
Thanks
Is this what you are looking for?
update post_content
set url = 'domain.com/page.html'
where url like 'domain.com/params?%?e=0'
This phrases as : replace all urls that start with 'domain.com/params?' and end with '?e=0' with 'domain.com/page.html'.
No it is not working. It's being written as it :
Update `wp_posts`
set post_content = 'domaine.com/newpage.php'
where post_content like 'domaine.com/ads.php?city=%e='
so it should take all the queries starting with domaine.com/ads.php?city= until e= but it is not and returning 0 value.
Some knows what is wrong ?

Need SQL Query Help: How to Search and Replace Specific Text LIKE x AND NOT LIKE xx

and thanks in advance for any help. I'm working on fixing all broken links in a massive WordPress multisite database and need some help writing an SQL query to run via PHP MyAdmin. I've searched, but can't the perfect solution...
PROBLEM: We have more than a thousand broken links that start with http:/ instead of http://
CHALLENGE: The following would result in numerous links starting with http:///
UPDATE wp_1_posts
SET post_content = replace (post_content,
'http:/',
'http://');
PROCESS: I want to write a query to SELECT all these links first, so I can review them to ensure I don't do any damage when replacing the text string. Downloading a db dump and doing a manual S&R is not an option since we're talking about a multi-gigabyte database.
I thought something like this would work...
SELECT * FROM wp_1_posts
WHERE post_content LIKE '%http:/%'
AND WHERE post_content NOT LIKE '%http://%'
But that just throws a syntax error. Am I even close?
QUESTION #1: How can I find all instances of "http:/" without returning all "http://" instances in the query results.
QUESTION #2: How might I safely fix all instances of "http:/" without affecting any "http://" strings.
FYI: I'll admit I know just enough about this to be dangerous, and I am not familiar with regular expressions. at. all. That's why I'm turning to you for help. Thanks again!
This should work, in MYSQL:
UPDATE wp_1_posts SET post_content = replace(post_content,'http:/', 'http://')
WHERE post_content REGEXP 'http:/[^/]'

Wordpress database: How to remove a word from all posts

I've a word called "[stink]" in all my wordpress posts (and they're many). I would like to remove it from all at once. I've got access to mysql/phpmyadmin.. any sql command that could make this?
Thank you in advance.
You can try something like this
UPDATE wp_posts
SET post_title = REPLACE(post_title, '[stink]', ''),
post_content = REPLACE(post_content, '[stink]', '')
WHERE post_title LIKE '%[stink]%'
OR post_content LIKE '%[stink]%'
Note: Make sure that you have a solid backup before you do any changes to your database.
Here is SQLFiddle demo
Since you have access to phpMyAdmin, you can take advantage of the graphical search and replace rather than having to use SQL (which was nicely explained by peterm). From within the table (wp_posts in the case of WordPress), click the Search tab then the Find and Replace text near the top of the screen. Enter the text you wish to search for ([stink]) and what you want to replace it with (sounds like nothing), then select the table from the dropdown (you'll have to do it twice to get both post_title and post_content).
However, some WordPress instances seem to serialize their database entries. In that case, you'll need a different set of tools entirely.
As peterm notes, make sure you have a backup before making changes to your database.

UPDATE mysql database replace strings

I have in my db strings like www.domain.com and http://www.domain.com. I want to prepend to all entries the http:// but not affect other urls and as a result have this: http://http://www.domain.com
Can this be done with mysql only? I have used REPLACE(field,'www','http://www'), but this replaces also the http://www with http://http://www
Thanks in advance
EDIT
I forgot to mention that in the field there might be entries which don't contain www or http://www and therefore I don't want to alter or maybe there are entries like <p>domain</p> in which CONCAT() prepends the http:// before <p>
Try adding a WHERE clause to your update to only update fields that do not already have 'http://'. Test it out like this
SELECT CONCAT('http://', field) FROM foo WHERE LOCATE('http://', field)=0
and your UPDATE syntax would be:
UPDATE foo SET field=CONCAT('http://',field) WHERE LOCATE('http://', field)=0
I won't worry about performance as this seems like a one-off kind of script. That said, you can couple LEFT and CONCAT to achieve this:
UPDATE mytable
SET mycolumn = CONCAT('http://',mycolumn)
WHERE LEFT(mycolumn,7) <> 'http://'
Do note that I'm not taking CapItaliZation in to account. You may also want to consider sanitizing the information either before adding it to the database, or maybe make a trigger to do it for you.
Search and Replace Query - mysql replace
Here is the SQL query to replace string in your MySQL database table:
UPDATE table_name SET column_name = REPLACE(column_name,'original_string','replace_string')
Here is what I did to change the path URLs in all my previous posts.
UPDATE `wp_posts` SET `post_content` = REPLACE(`post_content`,'http://localhost/','https://sureshkamal1.wordpress.com/')

Escaping % sign in subquery

I have a query in mySQL that's meant to return search terms that are used on our site. Yes, this is for a tag cloud, and yes, I know it's a mullet :)
We've got an admin page where administrators can view search terms and choose to exclude them from showing up in the cloud. These words go into the "badWords" table. We've gotten some terms like "foo%2525252525252520bar", and we're having trouble getting those excluded.
In pseudocode, the query to get the search terms for the cloud is:
SELECT * FROM `searchTerms` WHERE `word` NOT IN ( SELECT `word` FROM `badWords` )
This works fine, unless one of the terms returned from the subquery has a % in it. Is there a way to escape the entire subquery? I've tried doing a
replace( SELECT `word` FROM `badWords`, '%', '\%' )
... but that's apparently not syntactically correct.
I can do two queries if need be, but wondered if there's a way to get it done as is.
Thanks!
==============================
UPDATE: closing this for now, as I think the error lies elsewhere. Will report back once I know for sure, but don't want folks wasting time answering the question here if it's not the correct question...
Upvoted both of the replies received so far. Thanks, guys.
==============================
UPDATE 2: sigh Nevermind... can't close it :\
==============================
FINAL UPDATE: Well, looks like escaping the value isn't the problem. The admin page passes the value in the URL before it's added to the badWords table. In passing the value via the URL, it changes. So what's added to badWords is actually "foo%25252525252520bar" (there's one less "25" sequence). If I manually update the value in badWords and add back the missing "25" it works as expected. So no need to replace or escape anything. I just need to fix those URL values properly.
==============================
I don't think the % is your problem here. I think that you're trying to use REPLACE() on the subquery itself (SELECT ...), and not on a column value (word). Try this instead:
SELECT * FROM `searchTerms`
WHERE `word` NOT IN (
SELECT REPLACE(`word`, '%', '\%') AS word FROM `badWords`
);
Good luck!
I'm not very good with MySQL syntax, but SQL Server let's you do it this way:
SELECT * FROM `searchTerms` WHERE `word` NOT IN ( SELECT REPLACE(`word`, '%', '\%') FROM `badWords` )
NOTE: Basically all I did was move your REPLACE over some =) Hope this helps.