Update multiple database/tables on one server - mysql

I'm using Workbench, I'm not an expert at SQL but always open to learning.
My goal is to Update multiple tables at once and have the Replace happen on all found results.
Something like:
SELECT * FROM *.*;
UPDATE *.* SET post_content = REPLACE(post_content,'data-exclude="direct"','');
But the syntax is wrong. I have 100+ databases that need to be updated so I'd rather not have to list each one out.
Also, if it helps, I'm editing the same table in each database, so if there's another way to go about this, awesome. The table has a different prefix in each database but always ends in: _posts
Thanks ahead of time!

As I noted in the comments, you will have to dynamically write out each UPDATE statement and then execute each dynamically generated statement. You can write a script or procedure to do that, or you can just write some SQL to identify databases/tables that contain the column name you are after and write out the UPDATE statements that way:
SELECT DISTINCT CONCAT('UPDATE `', TABLE_SCHEMA, '`.`', TABLE_NAME, '` SET post_content = REPLACE(post_content,''data-exclude="direct"'','''');') as statement
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME = 'post_content';
Or something like that... (haven't tested)
Then just copy/paste the results back into your sql client and execute.

Related

Run an ALTER TABLE across all like tables (containing the same schema) in MySQL database

I have a database that contains a table per client, each table has the same columns in them. We're talking a few thousand client tables.
I need to add new columns to each of these tables for new development but cannot find a way to recurse all the tables in the database to add the columns. I know MS SQL has something sp_MSforeachtable which does maybe what I'm asking but I don't know if MySQL has anything similar?
As per this previous answer in SO you could do something like this :
select concat('ALTER TABLE `',table_name,'` ADD `test` INT NOT NULL AFTER `column_x`;')
from information_schema.tables
where table_schema = 'your_db_name'
Then remove the few tables not about client (here's hoping client is the only entity to have "private table") or if possible add a condition on the table_name (like AND table_name LIKE "client_%"), and execute the whole batch.
The 2nd solution, to use procedure, is too complex (for me) for this use case, but maybe someone more skilled than me in PLSQL won't agree.

Delete Table Across Multiple Databases

Is there a way to delete a table across multiple databases using MYSQL? I am using Sequel Pro but don't see any option within the GUI to do this so I am wondering if there is some sort of command that can do this?
The table name is the same across all the databases, and removing them one by one is time consuming. This would really help with cleaning up databases as we have hundreds and they all share the same tables. However, some tables are no longer needed and need to be deleted.
Hoping someone can help with a query for doing this.
You would need to run an individual DROP statement for each table.
We can query information_schema.tables to get a list of tables...
SELECT t.table_schema, t.table_name
FROM information_schema.tables t
WHERE t.table_name = 'tablename_i_want_to_drop'
AND t.table_schema NOT IN ('mysql','information_schema','performance_schema')
ORDER BY t.table_schema, t.table_name
And we can use an expression instead of the columns ...
SELECT CONCAT('DROP TABLE `',t.table_schema,'`.`',t.table_name,'` ;') AS `-- stmt`
FROM ...
Then we can take that resultset and save it, and execute the statements from a script. The MySQL command line client allows us to source a script...
https://dev.mysql.com/doc/refman/5.7/en/mysql-batch-commands.html
The client you are using may have a similar feature, to execute a script. Or somehow copy the resultset and paste that into a query window.
In a MySQL stored program, we could run that same query (to get a list of tables), and then loop those (using a CURSOR), and PREPARE, EXECUTE and DEALLOCATE PREPARE to execute "drop table" statements. That's an option, but for a one time shot, creating the script would be easier.
This is the spencer7593's "Drop query" slightly adaptated under Mysql 5.6.20 and Phpmyadmin :
select concat ('DROP TABLE ',table_schema,'.',table_name,';') FROM information_schema.tables where table_name like '%searched_pattern%' limit 0,500
Limit to 500 because Phpmyadmin displays only the 25 firsts results and I wanted to copy-paste all the results in a new SQL window.

Can I check if a table exists before join?

I have the following problem. I have Table A and would like to join to table B if table B exists. Can this be done? I am only writing SQL in WorkBench to try achieve it.
I am aware I cannot use the EXISTS option as I have tried typing it out but it prompts for an error.
Any suggestions would be greatly appreciated.
Thanks.
I managed to do this using EXECUTE, so using a query that is only prepared at runtime:
SET #sqlCommand = IF(
EXISTS (SELECT column_name FROM information_schema.columns WHERE table_schema = '{{yourschemaname}}' AND table_name = '{{yourtablename}}' AND column_name = '{{yourcolumnname}}'),
'SELECT \'Yes! Good to go!\' as ColumnExists',
'SELECT \'Nope!\' as ColumnExists');
PREPARE executable FROM #sqlCommand;
EXECUTE executable;
Note that the two selects at the center (Yes!/No!) are the custom statements that are to be executed conditionally. So if the column exists, the first command is executed (select 'yes!'), otherwise the second one (select 'nope').
I got the hint from this discussion here.. have a look if you're looking for the MSSQL equivalent: https://ask.sqlservercentral.com/questions/97579/check-if-table-exists-in-join.html
Data manipulation language statements are typically written for a specific schema; you are assumed to know what the schema looks like when you issue the statement. So you don't generally have the capacity to ask whether a particular schema object exists or has a particular structure. You could however write a stored procedure that did different things depending upon the schema. You have the ability in a stored procedure to use conditional statements and to look in INFORMATION_SCHEMA.

Manipulating tables in mysql by command line

I need to manipulate tables in my databases. I found this tutorial on w3schools.com which is great but it deals with only manipulating data inside one table, but what I need is tutorial for manipulating tables and not data inside them.
Here is what I mean by manipulating tables:
Delete all tables that begin with certain prefix
Move all tables that begins with certain prefix from one database to another
You can edit this list (and accordingly the list in accepted answer) so we can make this good learning resource.
Note: I did do research job before posting this question, and by seeing how we lack on these tutorials I decided to post it.
I usually use SQL to write the next query for example
SELECT
CONCAT('DROP ', GROUP_CONCAT(table_name))
FROM
information_schema.tables
WHERE table_schema = 'database'
AND table_name LIKE 'prefix%'
That should generate a correct drop table string.
You can do a similar thing with rename table.
SELECT
CONCAT('RENAME TABLE ', GROUP_CONCAT(CONCAT('database.',table_name, ' TO new.', table_name)))
FROM
information_schema.tables
WHERE table_schema = 'database'
AND table_name LIKE 'prefix%'
Older versions of MySQL may need you to run this first
SET SESSION group_concat_max_len=9999999999;
or some other large number

How can I replace a string in a MySQL database for all tables in all fields in all rows?

I have a Moodle installation that I migrated to another server and I need to change several references to the old domain.
How can I replace a string for another string in MySQL for a given database searching all tables, all fields, and all rows?
I don't need to change the field names, just the values.
Related: How can I use mySQL replace() to replace strings in multiple records?
But the marked as answer solution implies I strongly type the table name and I need to fire this into an entire database, not manually work on each table running the script N times.
This may seem a bit ... ugly. But maybe simply dump the database to a sql/txt file, replace all strings and recreate the database using the modified dump.
You could run the following code to create all the udpate statements you would need to run to do your updates. It would update every field in every table within your database. You would need to run this code, and copy the results and run them.
WARNING - Be sure to test this in a test environment. You don't want any unpleasant surprises. Modify as needed.
SELECT concat('UPDATE ', TABLE_NAME, ' SET ', COLUMN_NAME, ' = REPLACE(', COLUMN_NAME, ', ''STRING_TO_REPLACE'', ''REPLACE_STRING'')')
FROM INFORMATION_SCHEMA.COLUMNS c
WHERE TABLE_SCHEMA = 'YOUR_DATABASE_NAME'
AND DATA_TYPE IN ('char', 'varchar')
;
I limited this to only char and varchar fields. You may need to add additional data types.
I would consider querying INFORMATION_SCHEMA.COLUMNS and dynamically searching the columns and tables. Try something like creating a cursor of all the columns and tables in the db:
DECLARE col_names CURSOR FOR
SELECT column_name, table_name
FROM INFORMATION_SCHEMA.COLUMNS
Then iterate through each of the columns in each of the tables and run dynamic/prepared sql to update where the string exists.
Here are a couple of good posts to get you in the right direction:
https://stackoverflow.com/a/4951354/1073631
https://stackoverflow.com/a/5728155/1073631