Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MariaDB/MySql: Setting CURRENT_TIMESTAMP on CREATE and changing noting on UPDATE

Tags:

mysql

mariadb

I have not used MySQL in a few years and when I created a new table it did something I was not expecting. I am using MariaDB v5.5.60-MariaDB

I need to create a table that has both a created column and an updated column.

I need the created column to only be set to CURRENT_TIMESTAMP when the row is created and then never change unless I change it explicitly.

I need the updated column to be set to CURRENT_TIMESTAMP both when the row is created and when the row is changed.

If I do the following:

CREATE TABLE user_prefs (
  id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
  user VARCHAR(255) NOT NULL,
  provider VARCHAR(255) NOT NULL,
  pref VARCHAR(128) NOT NULL,
  jsondata LONGTEXT,
  created timestamp NOT NULL,
  modified timestamp NOT NULL,
  PRIMARY KEY (id),
  UNIQUE INDEX id_UNIQUE (id ASC));

Then the created column is set to:
DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

and the modified column is set to:
DEFAULT '0000-00-00 00:00:00'

If I try this:

CREATE TABLE user_prefs (
  id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
  user VARCHAR(255) NOT NULL,
  provider VARCHAR(255) NOT NULL,
  pref VARCHAR(128) NOT NULL,
  jsondata LONGTEXT,
  created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  modified timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (id),
  UNIQUE INDEX id_UNIQUE (id ASC));

Then I get the error **Error Code: 1293. Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause **

So is there a way to automate setting both created and modified on creation of a row and then to change modified every time the row is change?

Thanks in advance.

like image 225
Intervalia Avatar asked Jan 24 '19 15:01

Intervalia


2 Answers

A table might have automatic initialization of date in only one column in old versions of MySQL. But its behavior fixed in version 5.6.5. It means you have several ways to avoid this error:

1.You can upgrade your MySQL to the latest version;


Advantages:

  • native clear implementation of modification dates management in a database side
  • there aren't excess triggers

Вrawback:

  • if the current version of MySQL is used in exists projects then upgrading might make some problems.

2.You can create triggers for updating and the creation of a record, as @Simonare said

Advantages:

  • implementation of modification dates management in a database side

Вrawback:

  • there are many excess triggers. You'll create two triggers for each table. It means you'll create N*2 triggers for N tables.

3.You can set default value of created column to 0000-00-00 00:00:00 and set default value of updated column to CURRENT_TIMESTAMP(). In this case date of updating will be generated automatically. Also if you write null to created column MySQL will generate current date automatically and set it to the column. For example:

CREATE TABLE example_table (
  created TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00',
  updated_at TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP
);

If you execute the following query:

INSERT INTO example_table (created) VALUES (null);

created column will have current date value. MySQL will fill it automatically.

Advantages:

  • there aren't excess triggers

Вrawback:

  • implementation of modification dates management in a database side and client application side

4.You can use automatic initialization of date in updated column and use trigger to fill created column. For example:

CREATE TABLE example_table (
  created TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00',
  updated_at TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP
);

DELIMITER //
CREATE TRIGGER example_table_set_created_date
BEFORE INSERT
   ON example_table FOR EACH ROW
BEGIN
   SET NEW.created = CURRENT_TIMESTAMP();
END; //    
DELIMITER;

Advantages:

  • implementation of modification dates management in a database side

Вrawback:

  • there are many excess triggers. You'll create N triggers for N tables.
like image 146
Maksym Fedorov Avatar answered Oct 19 '22 20:10

Maksym Fedorov


you can create trigger for this

DELIMITER //

CREATE TRIGGER user_prefs_before_insert
BEFORE INSERT
   ON user_prefs FOR EACH ROW

BEGIN
   SET NEW.updated = new.created;
END; //

DELIMITER ;

then another trigger for update

DELIMITER //

CREATE TRIGGER user_prefs_before_update
BEFORE UPDATE
   ON user_prefs FOR EACH ROW

BEGIN
   SET NEW.updated = CURRENT_TIMESTAMP();
END; //

DELIMITER ;
like image 41
Derviş Kayımbaşıoğlu Avatar answered Oct 19 '22 22:10

Derviş Kayımbaşıoğlu