Manipulating tables in mysql by command line - mysql

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

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.

Update multiple database/tables on one server

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.

mysql tell difference between table and view

I'm surprised I didn't find this answer out there.
I know very well what the difference between a table and a view is. BUT..how do I DETERMINE whether a db object is a table or view? Since
show tables;
will show both tables and views - and there is no "show views" command.
to determine in my coding (which has to read multiple objects and may not "know" better), I do this:
show create view my_table_or_view
and if I get an error, which I prevent from dying, it's a table. Pretty clumsy, is there a better way?
try this variation instead ...
show full tables;
the Table_type column will give the info you require :)
You can use the following query and if it returns a record it's a table
SELECT *
FROM information_schema.tables
WHERE 'TABLE_TYPE' = 'BASE TABLE'
AND table_name = 'your table name'

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

search simple way to alter multi tables in one time in mysql

i have a lot of tables that start with some prefix ,
and i want to alter this tables
what is the simple way to do this (instead run over all tables)
i mean something like :
ALTER TABLE LIKE tablenameprefix% ADD INDEX `NewIndex1` (`field`);
how can i do this ?
thanks
EDIT :
can i do a kind of loop not in stored procedure ?
by select the names of tables from
SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_NAME LIKE 'tableprefix%'
You can't. What you could do though is write a stored procedure that enumerates all tables looking for your prefix and performs the necessary changes.
Given that ALTER TABLE syntax doesn't allow multiple table names, you cannot do this. You need to go through all tables in turn:
ALTER [IGNORE] TABLE tbl_name
alter_specification [, alter_specification]
Link: http://dev.mysql.com/doc/refman/5.0/en/alter-table.html
When I wanted to change multiple table's engine from MyISAM to InnoDB, instead of writing a loop I just made a full DB dump and opened it in a text editor. In the text editor I just simply changed all MyISAM words to InnoDB.
I know that this ain't proper solution but for me it was easier then writing a routine for this.
You would have to write a loop, according to the documentation you just specify the table name.
I made a stupid mistake of putting all Wordpress tables with my product tables, fortunately all Wordpress tables start with a wp_ prefix and all my other product tables have no this wp_ prefix.
I created another database named wordpress, now I want to move all tables start with wp_ to that database.
Here is what I did:
SELECT CONCAT('ALTER TABLE olddb.', table_name, ' RENAME wordpress.', table_name, ';')
FROM information_schema.tables
WHERE table_schema='olddb' AND table_name LIKE 'wp%'
INTO OUTFILE '/tmp/move_to_wordpress';
SOURCE /tmp/move_to_wordpress;
That's it.