Alter all columns WHERE datatype - mysql

Is there a way to change all columns that have a specific datatype in a database?
I have some columns that their datatype is datetime(6) and if any is like that I would just want them to be datatime ... without the 6 fractional numbers. Is this possible to do in MySql without having to specify every column? Thanks

You must create text string with necessary statements and save it in somewhere (i don't have columns with datetime(6), but must be like that):
select
concat('ALTER TABLE ',
TABLE_SCHEMA,
'.',
table_name,
' CHANGE COLUMN ',
Column_name,
' ',
Column_name,
' DATETIME NULL DEFAULT NULL')
from
INFORMATION_SCHEMA.COLUMNS
where
table_schema = 'my_schema'
and data_type = 'datetime'
and character_maximum_length = 6 #may be numeric_precision, i don't know
after use exec statement, like this:
PREPARE stmt1 FROM 'ALTER TABLE ....';
EXECUTE stmt1

Related

Replace space with underscore in all table names in database

I'm trying to replace all space (' ') with a underscore in all the table names in a database using PhpMyAdmin.
Ex:
Table 1 --> Table_1
I was wondering if this is possible. I know it's possible to do this for columns but I was wondering if someone could write me something for tables. I don't use PhpMyAdmin very often, but I installed it in this case becuase it works easily.
I'm not sure if you could do this in a stored procedure, but it is easy enough to have a query generate a script for you:
SELECT CONCAT('RENAME TABLE `'
, table_name
, '` TO `'
, REPLACE(table_name, ' ', '_')
, '`;'
) AS renameQuery
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'mySchema' AND TABLE_NAME LIKE '% %'
;
You could run a query like this to generate the SQL that will perform a rename:
SELECT CONCAT('RENAME TABLE ', table_name, ' TO ' , REPLACE(table_name, ' ', '_') , ';')
FROM information_schema.tables
WHERE table_schema = 'your_schema_name';
Remember to substitute your_schema_name for whatever your database is called.
To run the query in phpMyAdmin you can click the SQL tab at the top of the window, then paste the SQL into the box. The result of the above query will be SQL generated based off of the existing table names. Just copy this resulting SQL back into the textbox and run it again to perform the renames.
You can also rename all table with one command:
SELECT
CONCAT('RENAME TABLE '
,GROUP_CONCAT(
CONCAT('`',TABLE_NAME,'` TO ', REPLACE(TABLE_NAME,' ','_'))
SEPARATOR ', '),';') AS query
FROM information_schema.Tables
WHERE TABLE_SCHEMA = 'yourschema'
AND TABLE_NAME LIKE '% %';
sample
MariaDB [yourschema]> SELECT CONCAT('RENAME TABLE ' ,GROUP_CONCAT( CONCAT('`',TABLE_NAME,'` TO ', REPLACE(TABLE_NAME,' ','_')) SEPARATOR ', '),';') AS query FROM information_schema.Tables WHERE TABLE_SCHEMA = 'yourschema' AND TABLE_NAME LIKE '% %';
+--------------------------------------------------------------------------------------+
| query |
+--------------------------------------------------------------------------------------+
| RENAME TABLE `esercizio 1` TO esercizio_1, `my_table 1` TO my_table_1, `t 1` TO t_1; |
+--------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
MariaDB [yourschema]>

Change the Datatype of a Column in the entire Database - MySQL

I am new to MySQL. I have designed few tables with Char datatype. Now I want to change all the char datatype columns to Varchar with respective size mentioned in Char.
For example.
Existing - Phone Char(10)
Expected - Phone Varchar(10)
There are around 50 Plus tables. I know how to alter the datatype for each and every table and column but is there any better way to change the datatype in a single shot.
If you can't write a script to do the job, write a script that writes a script to do the job!
You want a bunch of ALTER TABLE statements:
SET SESSION group_concat_max_len = 1000000; -- Bumps the limit of 1028
SELECT GROUP_CONCAT(
CONCAT(
'ALTER TABLE `',
table_name,
'` MODIFY COLUMN `',
column_name,
'` VARCHAR(',
character_maximum_length,
')'
)
SEPARATOR ';\n') your_alter_statements
FROM information_schema.columns
WHERE table_schema = 'concrete'
AND data_type = 'char';
This'll result in:
ALTER TABLE `table1` MODIFY COLUMN `col1` VARCHAR(10);
ALTER TABLE `table1` MODIFY COLUMN `col2` VARCHAR(10);
ALTER TABLE `table2` MODIFY COLUMN `col1` VARCHAR(10);
ALTER TABLE `table3` MODIFY COLUMN `col1` VARCHAR(10);
ALTER TABLE `table3` MODIFY COLUMN `col2` VARCHAR(10);
Run that and you can go home early!
UPDATE: Stopped the truncation by adding group_concat_max_len. Made the length dynamic based on the columns length.
MySQL only one liner solution:
SELECT 'ALTER TABLE ',TABLE_NAME, ' MODIFY COLUMN ',COLUMN_NAME, CONCAT(' VARCHAR(', CHARACTER_MAXIMUM_LENGTH, ');')
FROM INFORMATION_SCHEMA.COLUMNS where DATA_TYPE = 'char' AND TABLE_SCHEMA='concrete'
Above query will return all ALTER TABLE statements, example shown below:
ALTER TABLE tablename1 MODIFY COLUMN col_name1 VARCHAR(17);
ALTER TABLE tablename2 MODIFY COLUMN col_name2 VARCHAR(17);
ALTER TABLE tablename3 MODIFY COLUMN col_name3 VARCHAR(60);
Copy the resulting rows and execute, so you can go home even more early.
Additionally, below is PHP/MySQL solution:
// Initialise Connection
define('DB_HOST', 'HOST_NAME_HERE');
define('DB_NAME', 'DB_NAME_HERE');
define('DB_USER_NAME', 'DB_USER_NAME_HERE');
define('DB_PASSWORD', 'DB_PASSWORD_HERE');
$pdo = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME, DB_USER_NAME, DB_PASSWORD, [
PDO::ATTR_PERSISTENT => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"
]);
// Get a list of CHAR columns
$sql = "SELECT TABLE_NAME, COLUMN_NAME, CHARACTER_MAXIMUM_LENGTH, IS_NULLABLE, COLUMN_DEFAULT
FROM INFORMATION_SCHEMA.COLUMNS where DATA_TYPE = 'char' AND TABLE_SCHEMA='" . DB_NAME . "'";
$stmt = $pdo->prepare($sql);
$stmt->execute();
$data = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Change CHAR to VARCHAR
foreach ($data as $rec) {
$ddq = 'ALTER TABLE ' . $rec['TABLE_NAME'] . ' CHANGE ' . $rec['COLUMN_NAME'] . ' ' . $rec['COLUMN_NAME'] . ' VARCHAR(' .
$rec['CHARACTER_MAXIMUM_LENGTH'] . ') ' . ($rec['IS_NULLABLE'] == 'YES' ? 'NULL' : 'NOT NULL') . (isset($rec['COLUMN_DEFAULT']) ? " DEFAULT '{$rec['COLUMN_DEFAULT']}'" : '');
$pdo->query($ddq);
}
After analyzing the web, I got the answer and changed the datatype using this query.
select
concat('ALTER TABLE ', table_name,' MODIFY COLUMN ', column_name,' ', REPLACE (column_type, 'char', 'varchar'),';')
from information_schema.columns
where
data_type='char'
and table_schema='DBName';
If your field is PK ('id' smallint unsigned for example) and some other tables have constraints with foreign keys for this PK use this query.
note: for modern mysql servers remove ONLY_FULL_GROUP_BY from Variables -> sql mode, by default it contains:
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
Then insert and execute this query:
SET group_concat_max_len = 10000;
SET #database_name = "database1";
SET #table_name = "table1";
SET #change = "mediumint unsigned";
SELECT DISTINCT
`table_name`,
`column_name`,
`constraint_name`,
`referenced_table_name`,
`referenced_column_name`,
CONCAT(
GROUP_CONCAT('ALTER TABLE `',table_name,'` DROP FOREIGN KEY `',constraint_name, '`' SEPARATOR ';'),
';',
GROUP_CONCAT('ALTER TABLE `',table_name,'` CHANGE `',column_name,'` `',column_name,'` ',#change SEPARATOR ';'),
';',
CONCAT('ALTER TABLE `',#table_name,'` CHANGE `',referenced_column_name,'` `',referenced_column_name,'` ',#change, ' NOT NULL AUTO_INCREMENT'),
';',
GROUP_CONCAT('ALTER TABLE `',table_name,'` ADD CONSTRAINT `',constraint_name,'` FOREIGN KEY(',column_name,') REFERENCES ',referenced_table_name,'(',referenced_column_name,')' SEPARATOR ';'),
';'
) AS query
FROM `information_schema`.`key_column_usage`
WHERE `referenced_table_name` IS NOT NULL
AND `referenced_column_name` IS NOT NULL
AND `constraint_schema` = #database_name
AND `referenced_table_name` = #table_name
GROUP BY `referenced_table_name`;
note: check EXTRA OPTIONS to show full text for fields in result.
Then copy and execute all generated queries.
Restore ONLY_FULL_GROUP_BY in Variables.
Enjoy!

Making All Column Name Lower Case MySQL

I have inherited a large MySQL database.
Its a mess: half the column names are upper case, other mixed case, other lower case.
I wish to standardize them
Is there a query I can run to alter each one so that they are all lower case?
Try this for rename all tables and columns to lower case:-
SELECT CONCAT('ALTER TABLE ', TABLE_NAME, ' CHANGE `', COLUMN_NAME, '` `',
LOWER(COLUMN_NAME), '` ', COLUMN_TYPE, ';')
FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = '{your schema name}'
Yes. You will be able to compose a query that will
1. Enumerate the tables in the database.
2. Enumerate the columns for each database.
3. If the column name is not equal to LCASE of its name, rename it to LCASE of its name.
When you post an example of what you've tried, I may be able to update this answer to be more helpful.
By this
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;
its not quite perfect but close enough.

How to change all table prefix in a single query

I am pretty amateur in mysql..can you please tell me how can I change table prefixes of my whole database in a single query... I can do it manually, but its quite time consuming to change all the tables prefixes. Please help me out. Like isc_administrator_log to cus_administrator_log means isc_ to cus_
I found these two solutions but do not understand either of them.
SELECT
GROUP_CONCAT('RENAME TABLE `', TABLE_SCHEMA, '`.`', TABLE_NAME, '` TO `',
TABLE_SCHEMA, '`.`prefix_', TABLE_NAME, '`;' SEPARATOR ' ')
FROM `TABLES` WHERE `TABLE_SCHEMA` = "test";
and
SELECT
CONCAT('RENAME TABLE ', GROUP_CONCAT('`', TABLE_SCHEMA, '`.`', TABLE_NAME,
'` TO `', TABLE_SCHEMA, '`.`prefix_', TABLE_NAME, '`')) AS q
FROM
`information_schema`.`Tables` WHERE TABLE_SCHEMA='test';
Both statements generate strings which happen to be SQL statements that you can then copy/paste at your prompt to rename your tables.
Just replace the following two strings with the actual values your need:
prefix_ : the prefix you want to add
'test' : the name of the database containing the tables you want to rename
Both statements are almost identical, the only difference is that information_schema is not explicitely mentioned in the first statement. Therefore the first statement must be run from the information_schema database (issue USE information_schema beforehands).
phpmyadmin : select database ; tab structure => Check all => (with selected list) select add prefix to table .
(is not query but it works)
You can do Dynamic SQL Query For MySQL 5.0.13
delimiter //
CREATE PROCEDURE dynamic(IN tbl CHAR(64), IN col CHAR(64))
BEGIN
SET #s = CONCAT('SELECT 'RENAME TABLE ',
GROUP_CONCAT('', TABLE_SCHEMA, ''.'', TABLE_NAME,
' TO ', TABLE_SCHEMA, ''='.prefix_''', TABLE_NAME, '')) AS q
FROM
information_schema.Tables WHERE TABLE_SCHEMA='test'';;'
PREPARE stmt FROM #s;
EXECUTE stmt;
END
//
delimiter ;
Got the Reference from here

Build column definition from INFORMATION_SCHEMA COLUMNS table

I want to rename columns in database programmatically and MySQL enforces me to specify column definition in CHANGE statement.
ALTER TABLE table_name CHANGE old_name new_name column_definition
So, I want to build column definition from INFORMATION_SCHEMA.COLUMNS table. I've read answers which adjust me to parse output of SHOW CREATE TABLE table_name, but I do not want to do that in some reasons.
I want to get column definition as result of single SQL script if it is possible.
Try this:
select COLUMN_TYPE from INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = '{database name}' AND TABLE_NAME = '{table name}' AND COLUMN_NAME = '{column name}';
You'll need to fill in the right values, but it should give you the precise string you'll need to fill into the ALTER statement. You will need to do some additional work to deal with default statements and NULL settings.
The complete sample:
SELECT CONCAT(
CAST(COLUMN_NAME AS CHAR),
' ',
CAST(COLUMN_TYPE AS CHAR),
IF(ISNULL(CHARACTER_SET_NAME),
'',
CONCAT(' CHARACTER SET ', CHARACTER_SET_NAME)),
IF(ISNULL(COLLATION_NAME), '', CONCAT(' COLLATE ', COLLATION_NAME)),
' ',
IF(IS_NULLABLE = 'NO', 'NOT NULL ', ''),
IF(IS_NULLABLE = 'NO' AND ISNULL(COLUMN_DEFAULT),
'',
CONCAT('DEFAULT ', QUOTE(COLUMN_DEFAULT), ' ')),
UPPER(extra))
AS column_definition
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'table_schema'
AND TABLE_NAME = 'table_name'
AND COLUMN_NAME = 'column_name';
EDIT Added quoting of default value, collation and charset.