How to change multiple meta value in wordpress mysql database - mysql

I have a meta value "XXxSAZTm-dU" in table wp postmeta. Its same meta value for many posts like 50 posts use it becasuse its a part of video url. Now I want to update this meta value to new url so I need to change that "XXxSAZTm-dU" to "CCjddjXX-mY" in all that 50 posts. Can you please tell me how can I do that with mysql?

MySQL has a REPLACE function exactly for this purpose. It performs case-sensitive search and replace within strings (so, not only exact value in column, the haystack may be an URL or a full text, the needle will be found within the string and replaced with new value:
UPDATE wp_postmeta
SET meta_value = REPLACE(
meta_value,
'XXxSAZTm-dU',
'CCjddjXX-mY'
);

Related

MySQL find and update based on results from 2 tables

First off, please note that this is not answered in the question here:
MySQL update table based on another tables value
or indeed any other Stack question or answer that I could find!
I converted a forum on a website and now just need to repair the internal URL links on a few hundred of the posts.
Posts are found in the column post_content within the table xyz_posts
ID post_content
1467 This is great https://example.com/index.php?topic=1234 I really like it
1468 Hello world
1469 Take a look https://example.com/index.php?topic=5678.0
You can see the URLs are mostly buried in the post text.
Note that the example above can sometimes be written with topic=1234.0 at the end, although it is actually stored in the database as a value of 1234. I don't want to rewrite the url and accidentally keep the .0
Here's an example of how I need that table to look:
ID post_content
1467 This is great https://example.com/finished-page/ I really like it
1468 Hello world
1469 Take a look https://example.com/another-page/
So, the table xyz_converter maps the old topic number to the new post ID like this:
meta_key meta_value value_id
_bbp_old_topic_id 1234 15675
_bbp_old_reply_id 1234 17439
Caveat here, the number 1234 also exists in this table for forum replies which we don't want, but the meta_key and value_id are different for those as shown. This SQL query works to get to the right one:
SELECT * FROM `xyz_converter` WHERE meta_key LIKE '_bbp_old_topic_id' AND `meta_value` LIKE '1234'
Also in table xyz_posts we map the value_id mentioned above to the post's URL suffix like this:
ID post_name
15675 finished-page
15676 another-page
How do I construct a SQL query that will detect the meta_value in one table and then replace it with the correct final URL as mentioned?
PROCESS SUMMARY
Detect the URL in xyz_posts post_content
Extract the topic number from the URL (eg 1234). If it's 1234.0 then take just 1234
Convert it to a post number in found in xyz_converter value_id (eg 15675) ensuring it is found alongside _bbp_old_topic_id
Take the suffix of the URL in xyz_posts post_name (eg 'finished-page')
Rewrite the original URL to include the suffix (not forgetting the trailing slashes).
I'm using MySQL 5.7.29 and PHPMyAdmin.
I'm fairly new to SQL queries and a Regex noob, but willing to learn more!
A solution that uses only MySQL commands and works in MySQL 5.7 could be like this.
If .0 is present only in the urls you could use a query like this to remove all occurences of .0 from post_content in xyz_posts.
UPDATE `xyz_posts` SET post_content=REPLACE(post_content,'.0 ',' ') WHERE post_content LIKE '%topic=%.0 %';
Then you can use
CREATE TABLE temp_tbl
SELECT CONCAT('index.php?topic=',c.meta_value) as `find_value` ,p.post_name as `replace_value`
FROM `xyz_converter` c
INNER JOIN `xyz_posts` p ON c.value_id=p.id AND `meta_key`='_bbp_old_topic_id'
ORDER BY meta_value DESC;
UPDATE `xyz_posts` p
INNER JOIN `temp_tbl` t ON p.post_content LIKE CONCAT('%',t.find_value,'%')
SET p.`post_content`=REPLACE(p.`post_content`,t.find_value,t.replace_value);
The first command will create a temporary table where the first column will be the value that you want to find and replace like index.php?topic=1234 and the second column will be the value you want to be replace with like finished-page
The second command will replace posts_content in xyz_posts taking the first column from temp_tbl and replacing it with the second column.
Below an sql fiddle where you can see the solution in action
http://sqlfiddle.com/#!9/7bce8c
Of course you should first create a copy of your database and try these commands to ensure everything works fine before trying it in your production database.

Search & replace 'http' to 'https' in database

Using phpmyadmin, I want to run a query that will search my entire database for:
http://example.com
And replace with:
https://example.com
My SQL knowledge is limited, maybe something like:
UPDATE ?? = REPLACE(??, 'http://example.com', 'https://example.com');
The database is over 1gb, so what can I run that will not crash the server.
Update: Note that while there are other answers posted here on SO that deals with search and replace, they don't seem to cover the entire database.
use REPLACE. and if there is a index on the field then the UPDATE can use them
UPDATE t
set url = REPLACE(url, 'http:', 'https:')
WHERE url LIKE '%http:%';
only change example.com
this will only find row with 'http://example.com'
UPDATE t
set url = REPLACE(url, 'http:', 'https:')
WHERE url LIKE '%http://example.com%';
or this will find all rows with http:// but only change only this http://example.com to https://example.com
UPDATE t
set url = REPLACE(url, 'http://example.com', 'https://example.com')
WHERE url LIKE '%http:%';
Warning, the answers given so far will mess up serialized data!
For example, say your site stores serialized data in a row with the URL in it, like this:
a:1:{i:0;s:19:”http://example.com”;}
Notice that the value of this item has 19 characters, and is denoted by s:19 in the array.
If you replace content using a SQL query, the same row on your new environment would end up like this:
a:1:{i:0;s:19:”https://example.com”;}
But after this change, the value is now 20 characters long meaning s:19 is incorrect. This invalidates the array and the entire row.
So either you make sure your SQL statements deal with serialized data, or if you happen to be using WordPress then there are a few options to search using PHP so as to not break the serialized rows:
The Better Search Replace plugin automatically handles serialized
data
The Search and Replace plugin offers an option which handles
serialized data
Taken and adapted from: https://wpengine.com/support/wordpress-serialized-data/
I would use insert:
update t
set url = insert(url, 5, 0, 's')
where url like 'http:%';

WordPress query for a single value inside a multiple values column, with serialized string format

I'm been looking for a while how to achieve this, no luck so far, what I have is a meta value which has multiple values in it and is serialized string format, and looks like this:
a:2:{s:15:"s2member_level2";b:1;s:26:"access_s2member_ccap_one_m";b:1;}
And this meta value varies from user to user, what i need to do is, get all of the values the includes the s2member_level2 in it, this is what i came out with:
$wpdb->get_results("SELECT * from $wpdb->usermeta WHERE meta_key = 'wp_capabilities' AND meta_value = 's2member_level2' ");
I really need to get it directly from the data base, so can not use wordpress functions
Any ideas? Thanks in advance.
Here's a workaround that you can try which basically does the filtering outside the query.
1) Get all the the pairs user_id,meta_value from wp_usermeta
select user_id,meta_value from wp_usermeta where meta_key="wp_capabilities
2) Inside the result array you can search for "s2member_level2" meta_values and get the corresponding user_id.
3) Once you have all the user_ids that you need, you can just retrieve each "wp_capabilities" value and unserialize it.
select meta_value from wp_usermeta where meta_key="wp_capabilities" AND user_id="..."
Take a look at the unserialize function: http://php.net/manual/en/function.unserialize.php

using REPLACE in MySQL Query just isn't working

Quick background, I have a small database with a table named 'songs'. This table holds the title, artist and URL of music I have on my machine. Several of the single quotes have been dropped from the track title (for example, the don't is stored as dont) and I'm attempting to replace them. I just cannot get this query to affect any rows:
UPDATE Songs
SET Title = REPLACE (Title, 'dont', 'don\'t')
No love. Isn't this correct syntax? It tells me that 0 rows were updated.
If it helps, I'm running version 5.5.27. I know there are a couple hundred rows with improper donts in there... I'm about to dump the results into Notepad and do a find/replace on don't and just run an update statement that way, but it's kinda hacky. Any ideas friends?
A couple of sample rows:
"51","Dont Stay Home","311","311 Greatest Hits","Rap","E:\Music\311\311GreatestHits\dontstayhome.mp3"
"229","Dont Turn Around","Ace Of Base","The Very Best Of","Dance","E:\Music\AceofBase\VeryBestOf\03-ace_of_base-dont_turn_around.mp3"
The Fields in order are id, title, artist, album, genre, path
You have to do it like this
UPDATE Songs
SET Title = REPLACE(Title, 'Dont', 'Don\'t');
^ ^
The reason for that is
REPLACE(str,from_str,to_str)
Returns the string str with all occurrences of the string from_str
replaced by the string to_str. REPLACE() performs a case-sensitive
match when searching for from_str.
If you want to replace either case you can do
UPDATE Songs
SET Title = REPLACE(REPLACE(Title, 'Dont', 'Don\'t'), 'dont', 'don\'t')
WHERE Title LIKE '%dont%' -- it makes sense to limit update to only those rows that have dont in it no matter case
Here is SQLFiddle demo
The first thought is that there might be some invisible characters. What does the following return?
select *
from songs
where title like '%dont%';
EDIT:
I didn't notice this at first. The problem is the space after the function name. Try this:
UPDATE Songs
SET Title = REPLACE(Title, 'dont', 'don\'t');
This is explained in the documentation:
Note
By default, there must be no whitespace between a function name and
the parenthesis following it. This helps the MySQL parser distinguish
between function calls and references to tables or columns that happen
to have the same name as a function. However, spaces around function
arguments are permitted.
EDIT II:
I don't know if the collation has an effect. But you can also try using double quotes as the string delimiter:
UPDATE Songs
SET Title = REPLACE(Title, 'dont', "don't");

How to Bulk Update post titles wordpress through mySQL

All my post titles have a static word in front of them. I have over 9000 published posts with two different static words in my post titles. I am trying to remove this word from all my posts.
Essentially, I am looking for a way to remove that constant word. I tried using export through wordpress and editing the post titles that way, but the file was 100mb + and simply won't open.
I looked towards SQL/phpmyadmin but I am not very well versed with SQL queries and don't want to mess up my database.
The "Constant" is always the first word of the title. What could I do
to instead have mysql detect the first space and remove everything
before it as well as including the space. Essentially, removing the
first word. Basically I have more than one constant, so it would be
better if I could just find the first space in the string and then
remove it and everything before it. I'm assuming we'd use sub_string
or something.
This is the title structure
Constant other stuff here
so if there is a search query where it finds "Constant " and a space and replaces it with "" nothing, that way I could have it completely removed. It'd be great if it could be a search and replace query, so I could utilize it later.
Information on the Database / Table / Column
the table is called: wp_posts and it needs to be restricted to the value of the table post_type when it's value is post and the title is in the post_title column
Any help would be greatly appreciated.
MySQL doesn't have exactly what you're looking for -- yes, there is a REPLACE() string function, but you can't limit it to a single substitution. As such, you might inadvertently replace other occurrences of this constant that could conceivably appear in your title string.
IMHO, the easiest way is to find all titles starting with your constant, and just replace the first one (i.e. at the start of the string):
UPDATE wp_posts
SET post_title =
MID( post_title, LENGTH('Constant ')+1 )
WHERE post_title LIKE 'Constant %'
AND post_type = 'post';
You need the +1 because MySQL string offsets start at 1, not zero.
Personally, I always prefer to run the equivalent SELECT first, just to be certain (too many years of MyISAM without BEGIN WORK):
SELECT post_title,
MID( post_title, LENGTH('Constant ')+1 ) AS replacedTitle
FROM wp_posts
WHERE post_title LIKE 'Constant %'
AND post_type = 'post';
Alternatively, if you're certain that you always want to remove the first word (i.e. up to and including the first space), then the following statement should work:
UPDATE wp_posts
SET post_title =
MID( post_title, POSITION( ' ' IN post_title )+1 )
WHERE post_type = 'post';
Since POSITION() will return zero if no space is found, this statement will be a no-op (i.e. non-destructive) in the general case.
Search RegEx is a great plugin to be able to search and replace - with grep or plain text - through all post and page content, post titles, post meta, etc. Does not search custom post types.
Back up your DB before making any changes, either with this plugin or direct query in the database.
Docs: http://urbangiraffe.com/plugins/search-regex/