MySQL modify all field lengths - mysql

Is there any way you can update the length of all fields in MySQL? I tried:
ALTER TABLE mytable MODIFY * VARCHAR(150);
But no joy. Any suggestions?

You can use info from information_schema database to generate query for you.
If you need to change all varchar(100) columns to varchar(150) in your table myTable use query:
SELECT CONCAT( 'ALTER TABLE `myTable`',
GROUP_CONCAT(
CONCAT( '\nMODIFY ', COLUMN_NAME, ' VARCHAR(150) ' ),
'' )
) AS query
FROM information_schema.COLUMNS
WHERE DATA_TYPE = 'varchar'
AND CHARACTER_MAXIMUM_LENGTH = 100
AND TABLE_SCHEMA = 'myDatabase'
GROUP BY TABLE_NAME
and then copy/paste output as another query to do the actual job.

You have to modify each column specifically.
ALTER TABLE mytable
MODIFY col_1 VARCHAR(150),
MODIFY col_2 VARCHAR(150),
MODIFY col_3 VARCHAR(150);
Note that all modifications can be done in a single "pass", so this is more efficient than running n individual ALTER TABLE calls.

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.

How to change datatype for many columns at once in MYSQL?

We started with ID as int(11). Then we switched to Hibernate column auto generation and the ID became bigint(20). So, many foreign keys stopped working unless I change the join column definition from bigint(20) to int (11). Is it possible to write a script that changes all int(11) to bigint (20) for all columns?
The query to find all columns to change is as follows:
select table_name, column_name, column_type
from information_schema.columns
where table_schema = 'rentoptimum'
and column_type='int(11)'
order by table_name, ordinal_position;
Can I update data in the information_schema.columns or I should write the alter script for every table?
You can query INFORMATION_SCHEMA to dynamically generate a script with the ALTER TABLE statements needed to modify these column data types.
You need to be very careful to only modify the data type, and not any other attributes of the column (nullability, auto_increment, signed/unsigned, etc).
Here is an example to get you started. This will generate one ALTER TABLE statement per table in a given schema, even if it has multiple columns to modify. It will replace int(11) with bigint(11), which is slightly different than what you asked for, but the (11) doesn't affect the actual data type. You can tweak that if you want.
select concat('alter table `',t.table_schema,'`.`',t.table_name,'`',
group_concat(' modify column `',c.column_name,'` ',replace(c.column_type,'int','bigint'),
if(c.is_nullable='yes',' null',' not null '),c.extra),';') as the_ddl
into outfile '/tmp/so42114820.sql'
from information_schema.columns c
inner join information_schema.tables t on t.table_schema = c.table_schema and t.table_name = c.table_name
where t.table_schema = 'your_schema'
and t.table_type = 'BASE TABLE'
and c.data_type = 'int'
group by t.table_schema,t.table_name;
set #foreign_key_checks = ##foreign_key_checks;
set foreign_key_checks = 0;
\. /tmp/so42114820.sql
set foreign_key_checks = #foreign_key_checks;

Add a column if it doesn't exist in mysql, need a little help debugging

I have the following query that I want to use to check whether if a column exists and then insert it if it doesn't.
$new_field ="IF NOT EXISTS
(SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_SCHEMA = 'dashboard'
AND TABLE_NAME = '".$this->table_name."'
AND COLUMN_NAME = 'timestamp')
BEGIN
ALTER TABLE `".$this->table_name."`
ADD mytimestamp DATETIME NOT NULL AFTER day_chan3";
I am not sure where my mistake is as I am not that good at sql queries and I would really aprpeciate the help. I know this looks very n00b and i am one.
I made the changes mentioned in the comment and I echoed the output of my query,
IF NOT EXISTS
(SELECT * FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'dashboard'
AND TABLE_NAME = 'admin_tmp' AND COLUMN_NAME = 'timestamp')
BEGIN ALTER TABLE `admin_tmp` ADD mytimestamp DATETIME NOT NULL AFTER day_chan3
Your if statement is mixing up backticks with single quotes. Use backticks only when necessary and only for identifiers (column names and table names). Use single quotes only for string and date constant values. So, try this:
(SELECT *
FROM information_schema.COLUMNS
WHERE
TABLE_SCHEMA = 'dashboard'
-----------------------------^ --------^
AND TABLE_NAME = '".$this->table_name."'
---------------------------^ --------------------^
AND COLUMN_NAME = 'timestamp')
----------------------------^ --------^

MySQL update default value of column in multiple tables from an inner select statement

I need to update the default value of all Synced fields in a database tables.
I've looked at several other posts and put together the following, which I'm missing something, any ideas?
ALTER TABLE (
SELECT
DISTINCT
TABLE_NAME
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_SCHEMA != 'mysql'
AND TABLE_SCHEMA != 'information_schema'
AND COLUMN_NAME = 'Synced'
ORDER BY
TABLE_NAME ASC)
CHANGE `Synced` `Synced` TINYINT DEFAULT 0;
I've referenced the following to put it together:
MySQL, update multiple tables with one query
How do I alter a mysql table column defaults?
I think you want some dynamic SQL. Like this:
SELECT
DISTINCT
CONCAT('ALTER TABLE ', TABLE_NAME, ' CHANGE `Synced` `Synced` TINYINT DEFAULT 0;')
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
TABLE_SCHEMA != 'mysql'
AND TABLE_SCHEMA != 'information_schema'
AND COLUMN_NAME = 'Synced'
ORDER BY
TABLE_NAME ASC

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};