modify enum values in migrations scripts - mysql

Is there a correct and safe way to modify enum column type values? Add new or remove old.
E.g.: I have ENUM ("apple", "banana")
I have 2 tasks that need to add value to the ENUM. 1 needs to add orange and second needs to add peach.
If I get migrations scripts, I will have:
ALTER TABLE example MODIFY COLUMN fruit ENUM("apple", "banana", "orange) NOT NULL
ALTER TABLE example MODIFY COLUMN fruit ENUM("apple", "banana", "peach) NOT NULL
I will end up only with values from the last executed SQL. Is there a way to just add value to existing values?

You can use the show or description command.
show create table dl_stats
produces this on my system if I use print_r to show the row fetched from the database.
Array
(
[Table] => dl_stats
[Create Table] => CREATE TABLE `dl_stats` (
`Ref` bigint(20) NOT NULL AUTO_INCREMENT,
`Area` varchar(10) NOT NULL,
`Name` varchar(80) NOT NULL,
`WIN` bigint(20) NOT NULL DEFAULT 0,
`AND` bigint(20) NOT NULL DEFAULT 0,
`LNX` bigint(20) NOT NULL DEFAULT 0,
`IOS` bigint(20) NOT NULL DEFAULT 0,
`MOS` bigint(20) NOT NULL DEFAULT 0,
`MSC` bigint(20) NOT NULL DEFAULT 0,
PRIMARY KEY (`Ref`),
UNIQUE KEY `By_Name` (`Area`,`Name`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4
)
Once you have this in a variable in your language, you can parse it.
13.7.7.10 SHOW CREATE TABLE Statement
SHOW CREATE TABLE tbl_name
Shows the CREATE TABLE statement that creates the named table. To use this
statement, you must have some privilege for the table. This statement
also works with views.
From dev.mysql.com
More examples are at tutorialspoint.com
EDIT
If you want it all sql then you need to write a procedure to do it which you call from your script. This can fetch the enum value from the information_schema.
I added a column test just for testing type enum with values 'a','b','c','d' to one of my tables.
Here's a function to demo the concept. To check what is returned by the select statement. Replace the TABLE_SCHEMA, TABLE_NAME and COLUMN_NAME values to suit.
CREATE DEFINER=`root`#`localhost`
FUNCTION `Get_Def`(`New_Value` VARCHAR(40)) RETURNS LONGTEXT
CHARSET utf8mb4 NOT DETERMINISTIC CONTAINS SQL SQL SECURITY DEFINER
return (select COLUMN_TYPE
from information_schema.`COLUMNS`
where TABLE_SCHEMA = 'aklcity_directory'
and TABLE_NAME = 'entries'
and COLUMN_NAME = 'Test')
This returns
enum('a','b','c','d')
In your procedure you can get this value as a string (more accurately longtext). You can check if the new value exists. If not, you can add it in.
To add the value 'e' to it requires
ALTER TABLE `entries` CHANGE `Test` `Test`
ENUM('a','b','c','d','e')
CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL;
Please alter to suit.

Related

mysql, Create Column with a default value

I've a table item that has some columns that are nullable.
To one of them type, I'd like to automatically insert a default value (instead of a NULL) whenever a new record in inserted in the table and do not specify a value for that column.
Can it be done without affecting the existing data?
The type column is a varchar.
I can update the current nulls.
You can try to ALTER column set a default value.
ALTER TABLE `T` MODIFY `type` varchar(50) DEFAULT 'default';
then insert by DEFAULT keyword:
INSERT INTO T (type) VALUES (DEFAULT);
Results:
This query will work for you.
For update table.
ALTER TABLE `column_name` CHANGE `tab` `my_id` INT(11) NOT NULL DEFAULT '0';
For insert table
CREATE TABLE `db_name`.`Tbale_name` ( `demo` INT NOT NULL DEFAULT '0');

Hash of two columns in mysql

I have a MYSQL table, with 5 columns in it:
id bigint
name varchar
description varchar
slug
Can I get MySQL to automatically generate the value of slug as a 256 Bit Hash of name+description?
I am now using PHP to generate an SHA256 value of the slug prior to saving it.
Edit:
By automatic, I mean see if it's possible to change the default value of the slug field, to be a computed field that's the sha256 of name+description.
I already know how to create it as part of an insert operation.
MySQL 5.7 supports generated columns so you can define an expression, and it will be updated automatically for every row you insert or update.
CREATE TABLE IF NOT EXISTS MyTable (
id int NOT NULL AUTO_INCREMENT,
name varchar(50) NOT NULL,
description varchar(50) NOT NULL,
slug varchar(64) AS (SHA2(CONCAT(name, description), 256)) STORED NOT NULL,
PRIMARY KEY (id)
) DEFAULT CHARSET=utf8;
If you use an earlier version of MySQL, you could do this with TRIGGERs:
CREATE TRIGGER MySlugIns BEFORE INSERT ON MyTable
FOR EACH ROW SET slug = SHA2(CONCAT(name, description));
CREATE TRIGGER MySlugUpd BEFORE UPDATE ON MyTable
FOR EACH ROW SET slug = SHA2(CONCAT(name, description), 256);
Beware that concat returns NULL if any one column in the input is NULL. So, to hash in a null-safe way, use concat_ws. For example:
select md5(concat_ws('', col_1, .. , col_n));
Use MySQL's CONCAT() to combine the two values and SHA2() to generate a 256 bit hash.
CREATE TABLE IF NOT EXISTS `mytable` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`description` varchar(50) NOT NULL,
`slug` varchar(64) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `mytable` (`name`,`description`,`slug`)
VALUES ('Fred','A Person',SHA2(CONCAT(`name`,`description`),256));
SELECT * FROM `mytable`
OUTPUT:
COLUMN VALUE
id 1
name Fred
description A Person
slug ea76b5b09b0e004781b569f88fc8434fe25ae3ad17807904cfb975a3be71bd89
Try it on SQLfiddle.

Unable to add Column to table in mysql

I am trying to add a column to a table.To do so I am trying
ALTER TABLE requirements Modify COLUMN parent_id int(11);
but when I try to execute this query mysql does not respond for long.So each time I have to kill the query.
I have created the table using
CREATE TABLE requirements (requirement_id smallint(6) NOT NULL AUTO_INCREMENT,
product_id smallint(6) NOT NULL,
name varchar(255) CHARACTERSET latin1 NOT NULL DEFAULT '',
PRIMARY KEY (requirement_id),
UNIQUE KEY requirement_product_id_name_idx (product_id,name),
UNIQUE KEY requirement_product_idx (requirement_id,product_id),
KEY requirement_name_idx_v2 (name) )
ENGINE=InnoDB
AUTO_INCREMENT=7365
DEFAULT CHARSET=utf8;
Please help me know why I am not able to execute the Alter table query.I am new to database is there something wrong with my alter table query.
According to your table defintion parent_id seems to be a new column which you want to add so your query should be to add the column not modify.
Try this:
alter table requirements add column parent_id int(11);
SQL FIDDLE DEMO
On a side note:
There needs to be a space between CHARACTERSET here
name varchar(255) CHARACTERSET latin1 NOT NULL DEFAULT '',
should be
name varchar(255) CHARACTER SET latin1 NOT NULL DEFAULT '',

mysql procedure, loop tables, set default value

I have created a small stored procedure to set some defaults before inserting data (I use PhpMyAdmin) in some tables
BEGIN
ALTER TABLE capacitors MODIFY COLUMN `Part Type` VARCHAR(50) NULL DEFAULT 'Ceramic Multilayer MLCC';
ALTER TABLE capacitors MODIFY COLUMN `Package` VARCHAR(50) NULL DEFAULT '0603';
END
How can I create a procedure to make defaults in many tables for 'Distributor' and 'Distributor Currency' fields?
Pseudo:
FOR EACH table in database
IF field 'Distributor' exists -> set default to 'Mouser'
IF filed 'Distributor Currency' exists -> set default to 'USD'

create a column with default value as null in mysql database

I want to create a column with default value as null and when any operation is performed it should change to 0. How do i do this in mysql database?
Here example how to add colum in existing table with default value
ALTER TABLE `test1` ADD `no` INT NULL DEFAULT NULL ;
When you call function then you have to write following query
UPDATE test1 SET `no` = '0' WHERE `test1`.`id` =your_id;
CREATE TABLE test
(
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY(id),
test_id INT,
cost FLOAT(5,2) DEFAULT NULL,
);
each time when you do some operation on that you need to update it as #Sadikhasan
or write a trigger that will update it to zero automatically.
if the operation you want to perform is read then write trigger on ON SELECT
if the operation you want to perform is update then write trigger on ON UPDATE
like wise for others.