Replacing All Column and Table Names in MySQL Database - mysql

I have about 20 tables in my database where I use the word 'car' in many of the table names and the column names.
Is there a script or tool that will allow me to replace every instance of 'car' with 'vehicle'? I do not want to replace any of the table data itself.

You could generate the RENAME TABLE statements with a query, then simply copy and execute them.
select concat('rename table ', table_name, ' to ', substring_index(table_name, 'car', 1), 'vehicle', substring_index(table_name, 'car', -1), ';')
from information_schema.tables
where table_schema = 'your_schema'
and table_name like '%car%';
The substring-index will return what is before the first occurence of 'car' when given 1.
It will return what is after when given -1.

Related

select column from multiple unknown tables

I have a lot of dynamically created nearly similar looking tables according to the scheme "prefix + number", eg "t1", "t2", "t343" etc. All those tables have a cross-table unique row named identifier that I like to select within one query:
SELECT
`identifier`
FROM
(
SELECT
`TABLE_NAME`
FROM
information_schema.TABLES
WHERE
`TABLE_NAME` LIKE 't%'
);
But this returns: ERROR 1248 (42000): Every derived table must have its own alias
EDIT: according to the comments I modified my query like this:
SELECT
A.identifier
FROM
(
SELECT
`TABLE_NAME` AS identifier
FROM
information_schema.TABLES
WHERE
`TABLE_NAME` LIKE 't%'
) A;
But this selects only the table names from the subquery but not the column identifier from these tables.
When you create the table dynamically, and you want to query all of them, you can create an SQL statement dynamically like:
select
group_concat(
concat(
'SELECT ',
'''',TABLE_SCHEMA,'.',TABLE_NAME,''',',
TABLE_SCHEMA,'.',TABLE_NAME,'.', COLUMN_NAME,
' FROM ',
TABLE_SCHEMA,'.',TABLE_NAME)
separator ' union all ')
from information_schema.`COLUMNS` c
where table_schema='test' -- the schema name where your tables are
and table_name regexp '^t[0-9]+$' -- table name starts with t and ends with number
and COLUMN_NAME = 'i' -- i choose `i` as the column to be selected
;
This will produce a SQL statement like:
select
'test.t1',
test.t1.i
from
test.t1
union all
select
'test.t2',
test.t2.i
from
test.t2
union all
select
'test.t3',
test.t3.i
from
test.t3
When putting all of this in a stored procedure, you can use PREPARE and EXECUTE to execute this created statement.
Above is just an example of an SQL statement, you should change it to your needs.

Normalizing table data in mySQL procedurally

I have a large data set in a denormalized format. Here is an example of the column names:
foreign_key_ID, P1, P2, P3, P4, P5.... D1, D2, D3.... etc..
These fields all contain similar type of data.
I need to normalize this into my existing table structure:
insert into new_table (id, name, index)
select foreign_key_id, P1, 1
from denormalized_table;
But that means that I need to run separate queries for each field in my denormalized table, just changing a few things:
insert into new_table (id, name, index)
select foreign_key_id, P2, 2
from denormalized_table;
This is getting tedious considering how many of these fields I have.
Is there a way this can be automated into a single operation? I.e.: iterate through the fields (I don't mind creating a list of eligible fields once, somewhere), pull off the last digit of that field name (ie "1" in "P1" and "2" for "P2") use the field name and the extracted index # in the sub-select.
Here's a start:
SELECT column_name, substr(column_name,2) AS `index`
FROM information_schema.columns
WHERE table_schema = 'mydatabasename'
AND table_name = 'denormalized_table'
AND column_name REGEXP '^[PD][0-9]+$'
ORDER BY column_name
You can modify the select list in that statement, to have MySQL generate statements for you:
SELECT CONCAT('INSERT INTO new_table (id, name, `index`) SELECT foreign_key_id, '
,column_name,', ',substr(column_name,2)
,' FROM denormalized_table ;') AS stmt
FROM information_schema.columns
WHERE table_schema = 'mydatabasename'
AND table_name = 'denormalized_table'
AND column_name REGEXP '^[PD][0-9]+$'
ORDER BY column_name
The output from that would be a set of MySQL INSERT statements that you could then execute.
If the number of rows and total size of the data to be inserted is not too large, you could and you want to get the whole conversion done in "one operation", then you could generate a single INSERT INTO ... SELECT statement, using the UNION ALL operator. I would get the majority of the statement like this:
SELECT CONCAT('UNION ALL SELECT foreign_key_id, '
,column_name,', ',substr(column_name,2)
,' FROM denormalized_table ') AS stmt
FROM information_schema.columns
WHERE table_schema = 'mydatabasename'
AND table_name = 'denormalized_table'
AND column_name REGEXP '^[PD][0-9]+$'
ORDER BY column_name
I would take the output from that, and replace the very first UNION ALL with an INSERT INTO .... That would give me a single statement to run to get the whole conversion done.
hat you're looking for is Dynamic SQL. This is where you execute SQL statements that you can assemble programmatically. You can run any arbitrary SQL code that's in a string, as long as you're in a Stored Procedure. See this link: How To have Dynamic SQL in MySQL Stored Procedure
Basically, you can build a string using mySQL statements by iterating over a set of columns. You can use the SHOW COLUMNS syntax (see http://dev.mysql.com/doc/refman/5.0/en/show-columns.html) to return a collection then loop over that resultset and build your dynamic query string and execute that way.
SHOW COLUMNS FROM myTable WHERE Field NOT IN (pkey, otherFieldIDontWantToInclude)

Delete column where name contains '_nd', rename column where name contains '_er'?

I have a large group of columns in a table (50+) which contain some statistics about a game.
We are simplifying our statistics, so now we want to do two things.
Drop any columns where the name contains '%_nd%'
Remove the string '_er' from any column names.
Is there an easy way to do this automatically, or do I need to enter all the column names manually?
Well you can do the first by running the following and using the SQL it produces:
select distinct concat('alter table ',table_name,' drop column ',column_name) someSql
from information_schema.columns
where column_name like '%_nd%'
You could do the second with a similar query:
select distinct concat('alter table ',table_name,' change ',column_name, ' ', replace(column_name, '_er', ''), ' ', data_type, case when CHARACTER_MAXIMUM_LENGTH is not null then concat('(', CHARACTER_MAXIMUM_LENGTH, ')') end) someSql
from information_schema.columns
where column_name like '%_er%'

Rename column names in MySQL

I have a bunch of columns in MySQL Table T1 with names like
A/B
C/D
E/F etc
I want to remove the '/' so that the names are AB, CD, EF (etc)
Is there a way(query) to rename all of them together rather than doing it one by one through alter table
Thanks
The easy way is to write a query that outputs the SQL, then copy-paste the output back into the command line.
Something like this:
select concat('alter table ', table_name, ' change ', column_name, ' ', replace(column_name, '/', ''), ' ', column_type, ';')
from information_schema.columns
where table_schema = 'mydbname'
and column_name like '%/%';
I tested this SQL and it works
alter table table_name
change A/B AB varchar(20),
change C/D CD varchar(20),
change E/F EF varchar(20)

Changing multiple column names in a mysql table

I have many columns in a table with a name starting with field_t and I have to change that to field_c
For example, here is the ALTER TABLE statement for changing the name of one of the columns:
ALTER TABLE my_table CHANGE field_t_class field_c_class longtext;
How can I change all the columns that follow this pattern instead of doing it in a one by one basis?
You can generated the ALTERs like this
SELECT
CONCAT(
'ALTER TABLE ', C.TABLE_NAME, ' CHANGE ',
C.COLUMN_NAME, ' ', REPLACE(C.COLUMN_NAME, 'field_t', 'field_c')
)
FROM
INFORMATION_SCHEMA.COLUMNS C
WHERE
C.COLUMN_NAME LIKE 'field[_]t[_]%';
You'll also need to append DATA_TYPE etc and based on this CHARACTER_MAXIMUM_LENGTH,
NUMERIC_PRECISION, NUMERIC_SCALE, CHARACTER_SET_NAME and COLLATION_NAME...
Get 1st column names having name like 'field_t%';
select C.COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS C
WHERE
C.TABLE_NAME='YourTableName' AND C.COLUMN_NAME like 'field_t%';
Then make string of renaming column names like:
Make rename_string as:
rename_string= "RENAME COL1 to ReCol1
RENAME COL2 to ReCol2"
Then do :
ALTER Table YourTableName {rename_string};