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]
Related
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.
Is there a SQL command to copy many tables with specific prefix (ie yot_) between two MYSQL databases? The DB user has access to both of the DB
There's no SQL statement of any kind that operates on tables using wildcards. You must name tables explicitly.
You can, however, generate the statements by querying the INFORMATION_SCHEMA:
SELECT CONCAT(
'RENAME TABLE my_old_schema.`', TABLE_NAME, '` '
' TO my_new_schema.`', TABLE_NAME, '`;'
) AS _stmt
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE 'yot\_%'
AND TABLE_SCHEMA='my_old_schema';
That's an example of generating a series of RENAME TABLE statements, which will move the tables from one schema to another. But it demonstrates the technique
You can try to make table-copy instead of move, with CREATE TABLE new_table LIKE old_table; followed by INSERT INTO new_table SELECT * FROM old_table;
I'm trying to convert PostgreSQL database to MySQL with MySQL Workbench tool. It seems that schema migration works fine - there are no errors, but when I'm trying to migrate data - I get huge list of errors and it looks like they all about the same thing - Postgres boolean field is fetched as extremely big integer number that can't be saved as TINYINT in MySQL:
ERROR: `mydb`.`my_table`:Range error fetching field 9 (value 140406775873536, target is MYSQL_TYPE_TINY)
Is there any way to fix that?
OK, I have a solution now.
Reason:
By default when migrate data from Postgres to MySQL using the wizard in MySQL Workbench, if the Postgres field is boolean, it will create TINYINT(1) column in MySQL, that's why we meet this error.
Solution:
alter the boolean field to INT
ALTER TABLEtargetdb.sample_tableCHANGE COLUMNfieldfieldINT NULL DEFAULT '1' COMMENT '' ;
use MySQL Migration wizard will succeed.
alter the field back to TINYINT(1).
If one of you guys has to do it on a large scale i suggest you take a look at this answer in order to generate a bulk script:
bulk changing column types in MySQL
or just check the script below :
SELECT
CONCAT('ALTER TABLE ',
TABLE_NAME,
' CHANGE COLUMN ',
COLUMN_NAME,
' ',
column_name,
' TARGET_TYPE ',
CASE
WHEN IS_NULLABLE = 'NO' THEN ' NOT '
ELSE ''
END,
' NULL;') AS que
FROM
information_schema.columns
WHERE
table_schema = 'MY DB'
AND data_type = 'SOURCE_TYPE';
hIs there any way to update all the columns of a mysql table for a particular record in one go to a particular value.
For e.g. I have a table that has around 70 columns , and they are by default set to 0 at the time of creating the table,when I add a new record via PHPmyadmin by just filling in one or two values and submitting it all the other fields are set to 0 , but I want to set all the fields to 1
many times ,so I need to set all the columns to 1 individually via PHPmyadmin
To speed-en up the process and
I tried
UPDATE tablename SET * = '1' WHERE id = '2' , but it does not work.
If anyone can provide a solution on similar lines , it would be great.
EDIT:
Is there a way without specifying all the 70 columns in the SQL statement? that what I am looking for. I do know how to update normally specifying columns in the SQL statement. Thank you.
If you are looking for a way to update all 70 columns to a single value with a short, simple statement, then I recommend that you write a stored procedure to do the update. That way you only need to write out the full update syntax once, and can re-use it over and over by calling the stored procedure.
CREATE PROCEDURE update_all_columns (p_new_value SMALLINT, p_id INT) ...
CALL update_all_columns(1,2);
Another trick is to use the information_schema.columns table to generate the update statement, making it less tedious to code the stored procedure.
Something like this:
SELECT concat('UPDATE ',
table_name,
' SET ',
group_concat(column_name separator ' = p_new_value, '),
' = p_new_value',
' WHERE id = p_id;') as sql_stmt
FROM information_schema.columns
WHERE table_schema = 'your_schema'
AND table_name = 'tablename'
AND column_name != 'id'
You have to name each column in an update statement.
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