using REPLACE in MySQL Query just isn't working - mysql

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");

Related

MYSQL Update part of String if that piece is not in the string and do nothing if it's there

I have got a string like this
****1****2****22****111****3****34****21****33****23****213****213****222****55****152****36
Let's say I have a new number to add to this string like ****44,
I want to UPDATE the string and add that number ****44 Only if it is not already in there.
If a number is already there i.e. Suppose I want to add ****22, the UPDATE should not happen because ****22 is already in the string.....
However, if I have ****22222, the UPDATE should Proceed.
How can this possibly be done:
So far I have this great thoughts from this SO Link: MySQL string replace
However, using this code (got from the SO Link as the Accepted answer there):
UPDATE your_table
SET your_field = REPLACE(your_field, 'articles/updates/', 'articles/news/')
WHERE your_field LIKE '%articles/updates/%'
I dont get how the checking of if the piece already exists will be done cause, this seems to be a direct change from one string to another.
Any Suggestion is honored.
Assuming the column you want to add data to is of a character type this should work:
update your_table
set your_column = concat(your_column, '****22')
where your_column not like '%****22*%'
and your_column not like '%****22';
The first where condition filters out cases where****22would match a longer similar sequence like****222in the middle of the string by checking that the match is followed by a*and the second condition filters out matching rows that end with****22and thus are not followed by any*.
This will append****22at the end ofyour_column
Sample SQL Fiddle
The following statement will update all rows and tack on a '22' to the end of 'myval' if it doesn't have '22' in the value somewhere. If you're literally dealing with *** characters, you have to escape them in the regexp.
update foo set myval= if(myval regexp '22',myval,concat(myval,'22'));

mysql to update a database using UPDATE SET and TRIM(LEADING wildcard prefix in record

In my database I have a table called 'content' and a field called 'link' and there are almost 300,000 records in that table.
In the field called 'link' there are a number of records that look like this :
http://www.example.com/blah/blah/123456789/url=http://www.destination.com
Unfortunately the prefix part of the records are individually unique where the numbered portion is constant changing from 90 to 150 alpha-numeric characters
I would like to remove the prefix up to and/or including the url=
So that the only thing left in the record is :
http://www.destination.com OR
I could even work with
url=http://www.destination.com
and simply do a replace command against the "url=" part as a second mysql command.
If there was a wildcard command, this job would be much easier and I would just wildcard everything showing up in the link record between :
http://www.example.com/blah/blah/ wildcard url=
But as everyone knows... there is no such wildcard available
So it had me looking at the UPDATE, SET and TRIM(LEADING commands
UPDATE content
SET link =
TRIM(LEADING 'url=' FROM link)
But this DID NOT generate the changes I wanted
And so I took the labor intensive method of downloading the database and using a Search and Replace program to make the changes to the 44 thousand records that contained these parameters.
But I would love to find a command that I could simply pass to the database to make this simpler in the future.
Any thoughts on how to accomplish this change in the future would be greatly appreciated.
Thanks in advance ;
You can use the SUBSTRING_INDEX function:
UPDATE content SET link=SUBSTRING_INDEX( `link` , 'url=', -1 )
I have not tested it, so I would recommend you check that substring_index returns the desired string first.
Assuming that the part you want to keep always begins with 'http://' you could get the desired result string with the help of the SUBSTRING_INDEX function:
SELECT CONCAT('http://', SUBSTRING_INDEX(link, 'http://', -1)) FROM content;
and fix your table with the simple statement
UPDATE
content
SET
link = CONCAT('http://', SUBSTRING_INDEX(link, 'http://', -1));
Explanation:
SUBSTRING_INDEX with third parameter negative returns the substring from the last occurence of the needle in the second parameter to the end. Because 'http://' isn't included in the return value, we add it again.
Remark:
If you've got https:// urls too, you should be able to adapt my solution.

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/

Creating variables and reusing within a mysql update query? possible?

I am struggling with this query and want to know if I am wasting my time and need to write a php script or is something like the following actually possible?
UPDATE my_table
SET #userid = user_id
AND SET filename('http://pathto/newfilename_'#userid'.jpg')
FROM my_table
WHERE filename
LIKE '%_%' AND filename
LIKE '%jpg'AND filename
NOT LIKE 'http%';
Basically I have 700 odd files that need renaming in the database as they do not match the filenames as I am changing system, they are called in the database.
The format is 2_gfhgfhf.jpg which translates to userid_randomjumble.jpg
But not all files in the database are in this format only about 700 out of thousands. So I want to identify names that contain _ but don't contain http (thats the correct format that I don't want to touch).
I can do that fine but now comes the tricky bit!!
I want to replace that file name userid_randomjumble.jpg with http://pathto/filename_userid.jpg So I want to set the column user_id in that row to a variable and insert it into my new filename.
The above doesn't work for obvious reasons but I am not sure if there is a way round what I'm trying to do. I have no idea if it's possible? Am I wasting my time with this and should I turn to PHP with mysql and stop being lazy? Or is there a way to get this to work?
Yes it is possible without the php. Here is a simple example
SET #a:=0;
SELECT * FROM table WHERE field_name = #a;
Yes you can do it using straightforward SQL:
UPDATE my_table
SET filename = CONCAT('http://pathto/newfilename_', userid, '.jpg')
WHERE filename LIKE '%\_%jpg'
AND filename NOT LIKE 'http%';
Notes:
No need for variables. Any columns of rows being updated may be referenced
In mysql, use CONCAT() to add text values together
With LIKE, an underscore (_) has a special meaning - it means "any single character". If you want to match a literal underscore, you must escape it with a backslash (\)
Your two LIKE predicates may be safely merged into one for a simpler query

MySQL: REGEXP to remove part of a record

I have a table "locales" with a column named "name". The records in name always begin with a number of characters folowed by an underscore (ie "foo_", "bar_"...). The record can have more then one underscore and the pattern before the underscore may be repeated (ie "foo_bar_", "foo_foo_").
How, with a simple query, can I get rid of everything before the first underscore including the first underscore itself?
I know how to do this in PHP, but I cannot understand how to do it in MySQL.
SELECT LOCATE('_', 'foo_bar_') ... will give you the location of the first underscore and SUBSTR('foo_bar_', LOCATE('_', 'foo_bar_')) will give you the substring starting from the first underscore. If you want to get rid of that one, too, increment the locate-value by one.
If you now want to replace the values in the tables itself, you can do this with an update-statement like UPDATE table SET column = SUBSTR(column, LOCATE('_', column)).
select substring('foo_bar_text' from locate('_','foo_bar_text'))
MySQL REGEXs can only match data, they can't do replacements. You'd need to do the replacing client-side in your PHP script, or use standard string operations in MySQL to do the changes.
UPDATE sometable SET somefield=RIGHT(LENGTH(somefield) - LOCATE('_', somefield));
Probably got some off-by-one errors in there, but that's the basic way of going about it.