mysql, Create Column with a default value - mysql

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');

Related

modify enum values in migrations scripts

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.

Change the field with UUID_Short failed?

I'm trying to alter current id field in organization table to UUID_SHORT but failed?
ALTER TABLE `organization` CHANGE `id` `id` BIGINT(16) UNSIGNED
NOT NULL DEFAULT uuid_short();
I don't see any error message?!
I don't think you can set the default value for id like this
Rather you can create a trigger to do this:
CREATE TRIGGER before_insert_organization
BEFORE INSERT ON organization
FOR EACH ROW
SET new.id = uuid_short();

MySQL - Remove default value for Datetime field

An existing MySQL table has a DateTime field which is not null and having a Default Value set as '0001-00-00 00:00:00'. Is it possible to Alter this table to remove the default value for the DateTime field ?
Yes, you can drop the default using an ALTER TABLE statement like this:
alter table your_table
alter column your_column drop default;
To drop the default from multiple datetime columns in a table:
ALTER TABLE your_table
ALTER COLUMN columnname1 DROP DEFAULT,
ALTER COLUMN columnname2 DROP DEFAULT,
ALTER COLUMN columnname3 DROP DEFAULT,
....
You can simply change the column and exclude default clause using following query. Here T1 is table containing default value for column updated and subject. You can simply remove default value as given below:
ALTER TABLE `T1`
CHANGE `updated` `updated` DATETIME NOT NULL,
CHANGE `subject` `subject` VARCHAR(100)

Alter mysql table default value and NULLvalue?

How can i make a table field with default value "none" and null value "no"?
When i create a table with following code it always add default value NULL and null to yes
ALTER TABLE `table_name` ADD `test` INT(11) AFTER `test1`
ALTER TABLE `table_name` ADD `test` INT NOT NULL AFTER `test1`;
ALTER TABLE myTable
ALTER column SET DEFAULT 'none'.
For replacing NULL with NO you don't have to alter the table just do it in your query :
SELECT COALESCE(columnWhichisNull,'no'))
FROM myTable ;
COALESCE checks if a value from a column is null and replaces it with your desired character

Two MySQL timestamp columns in one table

I would like to create a table that has both a column for "created" and another for "updated". The column "created" will be set at insert and never change. The column "updated" will change every time a row is updated. I don't want to mess with either of these columns in the subsequent INSERT or UPDATE statements. So what should my CREATE TABLE statement look like if I start with something like this?
CREATE TABLE IF NOT EXISTS `mydb`.`mytable` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`updated` TIMESTAMP,
`created` TIMESTAMP,
`deleted` TINYINT DEFAULT 0,
`notes` TEXT DEFAULT '',
`description` VARCHAR(100)
) TYPE=innodb;
I seem to be having trouble creating a table with two TIMESTAMP columns. I don't care if the columns are TIMESTAMP or DATETIME or whatever, I just want them to be populated by MySQL without explicit instructions from the insert or update statements.
I would like to be able to do inserts like this:
INSERT INTO `mydb`.`mytable` (notes,description) VALUES ('some note','some description');
and updates like this:
UPDATE `mydb`.`mytable` SET notes=CONCAT(notes,'some more notes') WHERE id=1;
both without having to explicitly set the "created" column or set (or reset) the "updated" column in the insert or update statement.
Try this one to create your table:
CREATE TABLE IF NOT EXISTS db.test_table
(
Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
created DATETIME DEFAULT NULL,
updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted TINYINT DEFAULT 0,
notes TEXT DEFAULT NULL,
description VARCHAR(100)
)
Note that
updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
will allow to update this field automatically.
And set this one for a trigger before inserting records:
DELIMITER $$
CREATE
/*[DEFINER = { user | CURRENT_USER }]*/
TRIGGER `db`.`on_before_insert` BEFORE INSERT
ON `db`.`test_table`
FOR EACH ROW BEGIN
SET new.created = NOW();
END$$
DELIMITER ;
Then you can use this to insert:
INSERT INTO db.test_table(description) VALUES ("Description")
and to update your record
UPDATE db.test_table SET description = "Description 2" where Id=1
And your created and updated fields will be set appropiately.
News flash: In mysql, TIMESTAMP columns are always updated with now() every time any other column in the row is updated - this is a deliberate feature of this datatype.
DATETIME on the other hand does not have this weird behaviour - it's completely normal.
The answer: created must be DATETIME, but due to this bug, you also need a trigger, like this:
CREATE TABLE IF NOT EXISTS mytable (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`updated` TIMESTAMP, -- This will be updated to now(), if you don't set it or set it to null
`created` DATETIME NOT NULL, -- This will never be magically updated once written
`deleted` TINYINT DEFAULT 0,
`notes` TEXT DEFAULT '',
`description` VARCHAR(100)
) TYPE=innodb;
DELIMITER ~
CREATE TRIGGER mytable_insert_trigger
BEFORE INSERT ON mytable
FOR EACH ROW BEGIN
SET NEW.created = CURRENT_TIMESTAMP;
END;~
DELIMITER ;
insert into mytable (notes) values ('test');
select * from mytable;
+----+---------------------+---------------------+---------+-------+-------------+
| id | updated | created | deleted | notes | description |
+----+---------------------+---------------------+---------+-------+-------------+
| 1 | 2011-07-05 11:48:02 | 2011-07-05 11:48:02 | 0 | test | NULL |
+----+---------------------+---------------------+---------+-------+-------------+
Try this:
CREATE TABLE IF NOT EXISTS mydb.mytable
(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
updated DATETIME,
created TIMESTAMP,
deleted TINYINT DEFAULT 0,
notes TEXT DEFAULT '',
description VARCHAR(100)
) TYPE=innodb;
Edit: Use a trigger.
CREATE TRIGGER mytable_update
BEFORE UPDATE ON mydb.mytable
FOR EACH ROW SET NEW.updated = NOW();
alternative is to change the order of timestamp column
OR
set first column DEFAULT value like this
ALTER TABLE `tblname` CHANGE `first_timestamp_column`
`first_timestamp_column` TIMESTAMP NOT NULL DEFAULT 0;
Reference
Unfortunately MySQL doesn't let you have two TIMESTAMP columns in one table. I would use ON UPDATE CURRENT_TIMESTAMP for the updated column and set created manually using the NOW() function.