a MYSQL script to convert the column names to lowercase - mysql

I am looking for a single MYSQL script to convert ALL column names in a database to lowercase in one go...
I have inherited a MYSQL database that has a lot of mixed case column names (150 tables with a strange naming convention) and I don't want to go through manually each table by table to do this.
Has anyone got such a script?
Thanks

In case anybody else wants this below is an example of the completed query, please test before you use.....
EDIT COMPLETED SOLUTION AS REQUESTED
SELECT CONCAT(
'ALTER TABLE ', table_name,
' CHANGE ', column_name, ' ',
LOWER(column_name), ' ', column_type, ' ', extra,
CASE WHEN IS_NULLABLE = 'YES' THEN ' NULL' ELSE ' NOT NULL' END, ';') AS line
FROM information_schema.columns
WHERE table_schema = '<DBNAME>'
AND data_type IN ('char', 'varchar','INT', 'TINYINT', 'datetime','text','double','decimal')
ORDER BY line;
HTH somebody in the future...
BTW views are also scripted here so you may need to take them out of your final SQL code

You can rename all table and column names to lowercase by applying the following regular expression to a SQL dump (for example, the dump generated by mysqldump):
s/`\(\w\+\)`/\L&/g
This works because all table and column names are wrapped by `` (backticks). It is better to do this on the schema only, separate from the data (work with table structures only and then do the inserts).
To do this in Vim, open the SQL dump and enter the following command:
:%s/`\(\w\+\)`/\L&/g
Or do it from the command line using sed:
sed 's/`\(\w\+\)`/\L&/g' input.sql > output.sql
If you need to do it repeatedly, store the expression in a text file, and invoke it as follows:
sed -f regex.txt input.sql > output.sql

The solution proposed by lepe is really the only safe way to go. The scripting methods are too dangerous, easy to export or process the wrong data definition. All of the example scripts above leave out several data types, so they are incomplete.
I did a sqldump which places backticks around the table and column names, then used Notepad++ to Search on (`.*`) and Replace With \L\1. That rendered all of my table and column names to lower case.
Then I backed up my database, wiped out all of the tables and then executed my .sql file to rebuild. I did not worry about doing structure separate from data as I found no occurances of the backtick symbol in any of my data.
In my case, I need my column names all lower case because my development environment automatically converts first_name to First Name: as my field label for data entry. If I left them as caps (which I inherited), they would convert to FIRST NAME which is not what I want, I'd have to alter all of my field labels.

You can solve this task by building a script, starting with the output from this statement:
SELECT table_name, column_name, data_type
FROM information_schema.columns
WHERE table_schema = 'dbname';
ORDER BY table_name
Details about this feature can be found here "MYSQL::The INFORMATION_SCHEMA COLUMNS Table"
Then you can use the ALTER TABLE .. CHANGE feature to change the name of the columns
e.g.
ALTER TABLE mytable CHANGE old_name new_name varchar(5);
See also "MYSQL::ALTER TABLE Syntax"
Different datatype have different requirements so you need the UNIONs:
SELECT 'ALTER TABLE '||table_name||' CHANGE '|| column_name||' '||lower(column_name)||' '||datatype||'('||CHAR(character_maximum_length)||');' AS Line
FROM information_schema.columns
WHERE table_schema = dbname and datatype in ( 'CHAR', 'VARCHAR' )
ORDER BY table_name
UNION
SELECT 'ALTER TABLE '||table_name||' CHANGE '|| column_name||' '||lower(column_name)||' '||datatype||'('||CHAR(numeric_precision)||');' AS Line
FROM information_schema.columns
WHERE table_schema = dbname and datatype in ( 'INTEGER' )
ORDER BY table_name
UNION
SELECT 'ALTER TABLE '||table_name||' CHANGE '|| column_name||' '||lower(column_name)||' '||datatype||'('||CHAR(numeric_precision)||','||CHAR(numeric_scale)|');' AS Line
FROM information_schema.columns
WHERE table_schema = dbname and datatype in ( 'FLOAT' )
ORDER BY table_name
UNION
SELECT 'ALTER TABLE '||table_name||' CHANGE '|| column_name||' '||lower(column_name)||' '||datatype||');' AS Line
FROM information_schema.columns
WHERE table_schema = dbname and datatype in ( 'DATE' )
ORDER BY table_name

Related

MariaDB set row_format to dynamic to all tables in one command

i want to change the row_format to dynamic on all tables in my database. When the datebase is selected i could do "ALTER TABLE tablename ROW_FORMAT=DYNAMIC;" to do it manually. Unfortunately there are around 100 tables to be changed.
How can i change the row format to dynamic on every tables in a specific DB that has something different to DYNAMIC?
I've been trying it but i cant find a working solution.
You can't ALTER TABLE more than one table at a time, but you can generate all the necessary ALTER TABLE statements this way:
SELECT CONCAT(
'ALTER TABLE `', TABLE_SCHEMA, '`.`', TABLE_NAME, '` ',
'ROW_FORMAT=DYNAMIC;'
) AS _alter
FROM INFORMATION_SCHEMA.TABLES
WHERE ENGINE='InnoDB' AND ROW_FORMAT <> 'DYNAMIC';
Capture the output of that and run it as an SQL script.

How to remove a prefix name from every table name in specific MySQL database

All tables in specific MySQL database, for example my_db, start with a prefix which its length is 17 character. I want to remove prefix from name of all tables. How I can do this?
improved hasanghaforian's answer...
removed extra concat functions.. still produces same output
select concat('RENAME TABLE ', table_name, ' TO ' , substr(table_name,18) , ' ; ' ) from information_schema.tables where table_schema = 'my_db';
I added where table_schema = 'my_db' to the statement that is described here to get statements for renaming all tables in my_db database, instead of renaming all tables of all databases in MySQL server instance:
select concat('RENAME TABLE ', concat(table_name, concat(' TO ', concat(substr(table_name, 18), ';')))) from information_schema.tables where table_schema = 'my_db';
Pay attention that the length of prefix was 17 and I used 18 in substr command.

How to delete all MySQL tables beginning with a certain prefix?

I've found another thread on this question, but I wasn't able to use its solutions, so I thought I'd ask with more clarity and detail.
I have a large MySQL database representing a vBulletin forum. For several years, this forum has had an error generated on each view, each time creating a new table named aagregate_temp_1251634200, aagregate_temp_1251734400, etc etc. There are about 20,000 of these tables in the database, and I wish to delete them all.
I want to issue a command that says the equivalent of DROP TABLE WHERE TABLE_NAME LIKE 'aggregate_temp%';.
Unfortunately this command doesn't work, and the Google results for this problem are full of elaborate stored procedures beyond my understanding and all seemingly tailored to the more complex problems of different posters.
Is it possible to write a simple statement that drops multiple tables based on a name like match?
There's no single statement to do that.
The simplest approach is to generate a set of statements, and execute them individually.
We can write a simple query that will generate the statements for us:
SELECT CONCAT('DROP TABLE `',t.table_schema,'`.`',t.table_name,'`;') AS stmt
FROM information_schema.tables t
WHERE t.table_schema = 'mydatabase'
AND t.table_name LIKE 'aggregate\_temp%' ESCAPE '\\'
ORDER BY t.table_name
The SELECT statement returns a rowset, but each row conveniently contains the exact SQL statement we need to execute to drop a table. (Note that information_schema is a builtin database that contains metadata. We'd need to replace mydatabase with the name of the database we want to drop tables from.
We can save the resultset from this query as a plain text file, remove any heading line, and voila, we've got a script we can execute in our SQL client.
There's no need for an elaborate stored procedure.
A little googling found this:
SELECT 'DROP TABLE "' + TABLE_NAME + '"'
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE 'prefix%'
This should generate a script.
Source: Drop all tables whose names begin with a certain string
From memory you have to use prepared statements, for example: plenty of samples on stack exchange
I would recommend this example:
SQL: deleting tables with prefix
The SQL from above, this one includes the specific databasename - it builds it for you
SELECT CONCAT( 'DROP TABLE ', GROUP_CONCAT(table_name) , ';' )
AS statement FROM information_schema.tables
WHERE table_schema = 'database_name' AND table_name LIKE 'myprefix_%';
Here is a different way to do it:
MySQL bulk drop table where table like?
This will delete all tables with prefix "mg_"
No need to copy and paste rowsets and in phpadmin copying and pasting is problematic as it will cut off long table names and replace them with '...' ruining set of sql commands.
Also note that '_' is a special character so thats why 'mg_' should be encoded as 'mg\_'
(and FOREIGN_KEY_CHECKS needs to be disabled in order to avoid error messages)
SET FOREIGN_KEY_CHECKS = 0;
SET GROUP_CONCAT_MAX_LEN=32768;
SET #tables = NULL;
SELECT GROUP_CONCAT('`', table_name, '`') INTO #tables
FROM information_schema.tables
WHERE table_schema = (SELECT DATABASE()) and table_name like 'mg\_%';
SELECT IFNULL(#tables,'dummy') INTO #tables;
SET #tables = CONCAT('DROP TABLE IF EXISTS ', #tables);
PREPARE stmt FROM #tables;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET FOREIGN_KEY_CHECKS = 1;

Delete all whitespace in MySQL column names from a table?

I am migrating a database from Access to MySQL, using Xataface as a frontend. Alas, Xataface is unable to modify a record if the column name contains a space and the people who made the Access database have tons of spaces in the column name.
The database is, alas, rather large, and thus manually modifying it seems rather problematic. I have looked through the MySQL manual and have only found things on how to remove whitespace from individual rows.
Perhaps modifying the INFORMATION_SCHEMA table would be the way to do this?
You could create a statement where each output is an ALTER TABLE statement and run those statements afterwards.
SQL Statement
SELECT 'ALTER TABLE '
+ Table_Name
+ ' CHANGE COLUMN `'
+ Column_Name
+ '` `'
+ REPLACE(Column_Name, ' ', '')
+ '`'
FROM INFORMATION_SCHEMA_COLUMNS
WHERE Column_Name LIKE '% %'
Output
ALTER TABLE tableX CHANGE COLUMN [column with spaces] [columnwithspaces]

Select something with location unkown from all tables in database in mysql

I have a varchar with the value of say Foo somewhere in my database and I don't know where exactly.
Is it possible to create a query that will search all tables and all columns for this content? Similar to grep
There isn't an easy way to do this, but you could use the information schema to find all your varchar columns.
SELECT table_name, column_name
FROM information_schema.columns
WHERE data_type = 'varchar';
You could then write a query to produce a list of queries that you would need to run to search for your term.
SELECT CONCAT(
'select ', column_name,
' from ', table_name,
' where ', column_name, ' like \'%foo%\''
) AS stmt
FROM information_schema.columns
WHERE data_type = 'varchar';
A more advanced example might insert matches into a results table along with the table and column names.
There is a stored procedure here (http://forge.mysql.com/tools/tool.php?id=232) for MySQL which will create a table for storing output, then loop through information_schema database's COLUMNS table to obtain all database's table and column names. Next execute a count() query on database.table for each column with appropriate search string in where condition. If count() > 0, that perticular column has the search term, so it will insert that triplet (database name, table name, column name) into a table. Last Select * from table to view respective database table and column names having the search term.
I found a very very simple way of doing it.
mysqldump -u user -p mydatabase | grep foo