I am trying to look for a way to replace all occurrences of a particular pattern in my database across many tables and columns, for this I need to create some way to do this, it does not need to be done by a script, just some SQL code that will do this.
For example, I want to replace all occurrences of 'v2' with 'www' but have no idea how to do this.
I am not looking for a tutorial, just a bit of guidance on what to do and how to script the SQL needed.
How do I go about doing this?
Just to guide you in a direction. You can use the replace function:
UPDATE MyTable
SET StringColumn = REPLACE (StringColumn, 'SearchForThis', 'ReplaceWithThis')
WHERE SomeOtherColumn LIKE '%PATTERN%';
In an earlier post there is more information:
How can I use mySQL replace() to replace strings in multiple records?
You can use a select CONCAT(...) from information_schema.columns to generate an update query for every table-column combination, where ... is a combination of the strings used in an update query, and column names of the information_schema.columns database.
For example:
select CONCAT("UPDATE ", TABLE_NAME, " SET ", COLUMN_NAME, "=REPLACE(",COLUMN_NAME,"'[string-to-find]'","'[string-that-will-replace-it]'",");") FROM information_schema.columns where table_schema = 'your_db';
COLUMN_NAME and TABLE_NAME are columns in the information_schema.columns table, as documented by MySQL
The above query should make the result set:
UPDATE table1 SET field1 = replace(field1,'[string-to-find]','[string-that-will-replace-it]');
UPDATE table1 SET field2 = replace(field2,'[string-to-find]','[string-that-will-replace-it]');
UPDATE table2 SET field3 = replace(field3,'[string-to-find]','[string-that-will-replace-it]');
...
You could output the results of the SELECT statement to a file, which then becomes a script to execute. Alternatively, if you use phpadmin or any other programming language as an interface, you can cycle through the results set, and execute the value of each row in the results set.
I got the idea from MikeW's answer here, about selecting all rows where a data value exists, and from some other stack overflow answers that I have now lost track of, sadly (sorry to the original writers)
To be honest, I think this question may be a duplicate of this, in addition to this though...
update TABLE_NAME set FIELD_NAME = replace(FIELD_NAME, 'Text to search, 'Text to replace it with');
Related
I have got a question - how do I delete the same pattern (2-3 symbols) that presents in multiple records in the same position.
So far, I have managed to find out this query returns me the required result but it does not actually modify the records in the required way (it does not delete the pattern from the records).
SELECT SUBSTRING(column_name,1,length(column_name)-2)
FROM table_name
WHERE column_name LIKE '%symbols'
Any help will be much appreciated.
I found a solution using the REPLACE statement
UPDATE
table_name
SET
column_name = REPLACE(column_name, 'pattern', '')
WHERE
column_name LIKE '%pattern';
I'm looking to replace a string in a CMS multi-site database across a common set of tables. Here is the initial query to collect the target tables:
SELECT TABLE_NAME as target_table
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE '%_content'
...against the results of which I'd like to run the following:
UPDATE target_table
SET title = replace(title, 'SEARCH_STRING', 'REPLACE_STRING')
WHERE title LIKE ('%SEARCH_STRING%');
Thanks in advance for the assist!
For a one off, a workable approach is to use SQL to generate a set of SQL statements.
Assuming that the table_schem and table_name don't contain backtick characters, and if your SEARCH_STRING and REPLACE_STRING don't contain single quotes (or are properly escaped), we could do something like this:
SELECT CONCAT('UPDATE `',t.table_schema,'`.`',t.table_name,'` c'
,' SET c.title = REPLACE(c.title, ''SEARCH_STRING'', ''REPLACE_STRING'')'
,' WHERE c.title LIKE (''%SEARCH_STRING%'') ;') AS `-- stmt`
FROM INFORMATION_SCHEMA.TABLES t
WHERE t.table_name LIKE '%_content'
AND t.table_schema NOT IN ('information_schema','mysql','performance_schema')
ORDER BY t.table_schema, t.table_name
we can save the results from the query into a file. and then submit the SQL statements in the file to the MySQL server.
(I think I would be using INFORMATION_SCHEMA.COLUMNS, with tables containing column named 'title' as well as the table_name matching a pattern, but the approach is the same.
Note that this cannot be accomplished in a single SQL statement; the query to get the list of tables is going to have to be a separate statement, separated from the execution of the actual UPDATE statement(s).
EDIT I just took a look at the answer linked to in the question; that is totally unrelated. There's nothing there that would apply to the problem we are trying to solve here.
Because of the way SQL is processed (parse, syntax check, semantic check, determine execution plan, then execute) ... identifiers (e.g. table names) must be supplied as tokens in the SQL text. Identifiers cannot be supplied as values at execution time. That's why we need separate statements.
Is it possible to do the following in MySQL
SELECT * FROM 'table name' WHERE 'field name' NOT LIKE '%string%';
I'm working on a database previously set up by somebody else - there are lots of field headings for shoe size based on location - i.e. quantity_size_125_grantham
I want to run a query that will SELECT all columns and rows from the database where the field heading name is NOT LIKE '%grantham%'. There are multiple columns for quantity_size_integer_*location* that I want to rule out.
Is this possible?
Thanks,
No, it's not possible to dynamically create a SQL statement and execute it within a single statement. It can be done in two steps.
It is possible to retrieve column metadata from the information_schema database, from the columns, for example:
SELECT c.*
FROM information_schema.columns c
WHERE c.column_name NOT LIKE '%string%'
AND c.table_schema = 'mydatabase'
AND c.table_name = 'mytable'
ORDER BY c.table_name, c.ordinal_position
Since a MySQL statement has to define the columns to be returned, it's not possible to dynamically include/exclude columns in a query.
You can use the information_schema database to help you create a SQL statement, something like this, as an example:
SELECT CONCAT('SELECT '
,GROUP_CONCAT(CONCAT('t.`',c.column_name,'`') ORDER BY c.ordinal_position)
,' FROM `',c.table_name,'` t'
) AS stmt
FROM information_schema.columns c
WHERE c.table_schema = 'mydatabase'
AND c.table_name = 'mytable'
AND c.column_name NOT LIKE '%string%'
GROUP BY c.table_name
NOTE: The length of the string returned by the GROUP_CONCAT function is limited by the group_concat_max_len and the max_allowed_packet variables.
This query only returns a string; it doesn't actually execute the generated statement. That would need to be done as a separate step.
Yes, it's possible. But don't use single quote around identifiers.
If you need to "quote" identifiers, the MySQL standard is to use backticks around them. (It's also possible to use double quotes if SQL_MODE includes ANSI_QUOTES)
This:
SELECT t.*
FROM `table_name` t
WHERE t.`field_name` NOT LIKE '%string%'
will return all rows from the table where value in the field_name column is not set to NULL and the value does not contain the string string.
I'm needing to do a very important database string correction on 192 rows and am wondering if this is correct syntax:
UPDATE `DATABASE_NAME`.`TABLE_NAME` SET `FIELD_NAME` = REPLACE(`FIELD_NAME`,`REPLACE_THIS_STRING`,`WITH_THIS_STRING`);
Thanks in advance!
The best way to find out is to write it as a SELECT statement first to "preview" the results.
SELECT field_name As before
, Replace(field_name, 'replace this string', 'with this string') As after
FROM table_name
Optional WHERE clause (to only affect the rows that contain our replacement string):
...
WHERE field_name LIKE '%replace this string%'
Well, i would write it like this
UPDATE `DATABASE_NAME`.`TABLE_NAME` SET `FIELD_NAME` =
REPLACE(`FIELD_NAME`,`REPLACE_THIS_VALUE`,`WITH_THIS_VALUE`);
Does the table only contain these 192 rows? Otherwise you must add a WHERE to the syntax. Or it will update all FIELD_NAME rows.
As #gvee suggest, try to select the rows first and see how the result looks like to ensure the update scope is correct
I would like to concatenate column names in a way that the first part of the column name is a string and the second part is a number which is the result of another query.
For example:
SELECT CONCAT('column', mytable.mycolumn) FROM table ...
Can this be done in some way. This way it doesn't give me errors but I don't get the expected result and it seems the concatenation doesn't work.
I previously said that this couldn't be done, but I was wrong. I ended up needing something like this myself so I looked around, and discovered that server-side prepared statements let you build and execute arbitrary SQL statements from strings.
Here is an example I just did to prove the concept:
set #query := (
select concat(
"select",
group_concat(concat("\n 1 as ", column_name) separator ','),
"\nfrom dual")
from information_schema.columns
where table_name = 'columns')
;
prepare s1 from #query
;
execute s1
;
deallocate prepare s1
;
If the number of columns is fixed, then a non-dynamic approach could be:
select
case mytable.mycolumn
when 1 then column1 -- or: when 'a' then columna
when 2 then column2
when ...
else ...
end as my_semi_dynamic_column
from ...
I don't believe you can do this with CONCAT() and CONCAT_WS(). I'd recommend using the langauge you are working with the create the field names. Doing it this way would be pretty scary, depending on where the data in the database came from.
I would suggest looking at information_schema. The following code is untested but should theoretically work. Obviously replace your table name with an appropriate table name or link to information_schema.tables and use the table_type in your where clause
select concat('column', column_name) from information_schema.columns where table_name ='your table name'