MySQL Trigger that calls a procedure for setting a date - mysql

i have a trigger which set a date if the date isnt set in the insert statement like this:
CREATE TRIGGER checkData
BEFORE INSERT ON students
FOR EACH ROW
BEGIN
IF NEW.schoolDate is null THEN
SET NEW.schooldate=date(now());
END IF;
END;
That works well. But now i want to include this in a procedure like this:
create procedure checkdate(setDate date)
begin
if setDate is null then
set setDate = date(now());
end if;
END;
And i changed the trigger to:
CREATE TRIGGER checkData
BEFORE INSERT ON students
FOR EACH ROW
BEGIN
call checkdate(NEW.schoolDate);
END;
But this doesnt work anymore can any1 help?

Use a default value instead of a trigger. Change the table structure to
create table students
(
...
schoolDate datetime not null default current_timestamp,
...
)
Then you can insert data with a date set and if you don't provide a date, then the default will be used.

Related

Trigger compare two datetime mysql

I want a trigger which compare two datetime.
Here my trigger:
EDIT :
create trigger updateRealisee after update on ladi.DSMSreservation for each row
begin
declare mnt datetime;
mnt=(select NOW());
if :new.date < mnt then
:new.realisee = 1;
end if;
end;
The error is that there are several restrictions on an after udpate trigger:
You can not create an AFTER trigger on a view.
You can not update the NEW values.
You can not update the OLD values.
However, you can change it to a before insert trigger.
I have tested the code below and it works. Of course, it only works on those you are newly inserting, not ones that already exist. For the ones that already exit.... simply run:
update TEST.DSMSreservation set realisee = 1 where date < NOW();
Then... the following complete code to create a table, trigger, and add rows provides an example how it works on newly added rows:
create database TEST;
USE TEST;
CREATE TABLE TEST.DSMSreservation
(
date DATETIME NULL DEFAULT NULL,
realisee INT NULL DEFAULT NULL
);
delimiter $$
create trigger updateRealisee before insert on TEST.DSMSreservation
for each row
begin
IF (new.date < NOW()) THEN
SET new.realisee = 1;
end if;
end;
$$
delimiter ;
INSERT INTO DSMSreservation VALUES ('2012-06-08 12:13:14',0);
INSERT INTO DSMSreservation VALUES ('2017-06-08 12:13:14',0);
INSERT INTO DSMSreservation VALUES ('2016-06-08 10:13:14',0);
INSERT INTO DSMSreservation (date) VALUES ('2016-06-08 16:13:14');
Running these two mysql statements will resolve what you were trying to accomplish with your original trigger.
Please mark as answer if this has answered your question.

MySQL ON UPDATE trigger - update the same table with CURRENT_TIMESTAMP and condition

I have a MySQL(5.1.67) table 'tracker' with TIMESTAMP field 'close_time'.
In the same table I have string field 'status'.
I want to update close_time field with CURRENT_TIMESTAMP value when status field updated to specific text value, for example 'Closed'.
Here is sample with INSERT:
How can I write a trigger that updates rows in the same table, before the insert is commited?
I tried something like that:
CREATE TRIGGER `close_time_trigger` BEFORE UPDATE ON `tracker` FOR EACH ROW
BEGIN
IF NEW.status = 'Closed' THEN
SET NEW.close_time = CURRENT_TIMESTAMP;
END IF;
END
But I got error: You have an error in your SQL syntax ... at line 4.
I tried some other variations which I found but none of them works.
Please help to create correct trigger for my case.
Did you set the DELIMITER?
This should work:
DELIMITER $$
CREATE TRIGGER `close_time_trigger` BEFORE UPDATE ON `tracker` FOR EACH ROW
BEGIN
IF NEW.status = 'Closed' THEN
SET NEW.close_time = CURRENT_TIMESTAMP;
END IF;
END $$
DELIMITER ;
you didn't tell it what to update.
CREATE TRIGGER `close_time_trigger` BEFORE UPDATE ON `tracker` FOR EACH ROW
BEGIN
IF NEW.status = 'Closed' THEN
update tracker
SET NEW.close_time = CURRENT_TIMESTAMP;
END IF;
END

MYSQL Trigger set datetime value using case statement

I'm using mysqlimport to do mass table inserts (replacing duplicates primary keys). Several tables have date time columns with records containing values '0000-00-00'. What I would like is a trigger which detects these '0000-00-00' values and replaces with '1950-01-01', otherwise keep the datetime value in the record (i.e. when it's not '0000-00-00').
I have tried the following:
CREATE TRIGGER set_datetime BEFORE INSERT ON tbl
FOR EACH ROW
CASE
WHEN date_col='0000-00-00' THEN SET date_col='1950-01-01';
END CASE
Thank you.
EDIT
Update attempt:
CREATE TRIGGER set_datetime BEFORE INSERT ON tbl
FOR EACH ROW
IF (NEW.date_col='0000-00-00') THEN
SET NEW.date_col='1950-01-01';
END IF;
Still getting an error in the SET portion.
EDIT 2
WORKING:
DELIMITER $$
CREATE TRIGGER insert_check BEFORE INSERT ON ar
FOR EACH ROW
BEGIN
IF NEW.delivery_date='0000-00-00' THEN
SET NEW.delivery_date='1950-01-01';
END IF;
END; $$
DELIMITER ;
Use IF THEN :
IF (NEW.date_col = '0000-00-00') THEN
SET NEW.date_col='1950-01-01';
END IF;
CREATE TRIGGER set_datetime BEFORE INSERT ON tbl
FOR EACH ROW
IF YEAR(NEW.date_col)=0 THEN
SET NEW.date_col='1950-01-01 00:00:00';
END IF;
Give it a Try !!!
If you want, or need, to use 'case' then this should work:
SET NEW.date_col=CASE WHEN NEW.date_col='0000-00-00' THEN ='1950-01-01'
WHEN NEW.date_col='something else' THEN 'whatever'
ELSE 'default'
END CASE;

autofilling column values in stored procedure, called via trigger

Currently, I have bunch of triggers that do the same thing. This is copy-pasted for every table that needs this functionality.
delimiter $$
create trigger user_before_insert before insert on user for each row
begin
set NEW.create_time = CURRENT_TIMESTAMP;
set NEW.create_user_id = #user_id;
set NEW.modify_time = CURRENT_TIMESTAMP;
set NEW.modify_user_id = #user_id;
end$$
create trigger user_before_update before update on user for each row
begin
set NEW.modify_time = CURRENT_TIMESTAMP;
set NEW.modify_user_id = #user_id;
end$$
Is it possible to wrap the lines that modify OLD and/or NEW into stored procedures that are called via triggers? Something like this:
delimiter $$
create procedure autofill_on_insert(inout NEW data_type) -- what would be the data_type?
begin
set NEW.create_time = CURRENT_TIMESTAMP;
set NEW.create_user_id = #user_id;
set NEW.modify_time = CURRENT_TIMESTAMP;
set NEW.modify_user_id = #user_id;
end$$
create procedure autofill_on_update(inout NEW data_type) -- what would be the data_type?
begin
set NEW.modify_time = CURRENT_TIMESTAMP;
set NEW.modify_user_id = #user_id;
end$$
delimiter ;
create trigger user_before_insert before insert on user
for each row call autofill_on_insert(NEW);
create trigger user_before_update before update on user
for each row call autofill_on_update(NEW);
Additional question: if this is possible, is there any way to check if NEW contains specific columns? There are tables that do not have modify_time and modify_user_id.
I can say that NEW cannot be passed into the procedure, because NEW is an alias that represents a row. Procedure's arguments have to be scalar values, like INT, VARCHAR, etc..
About the 'SET NEW.create_time = CURRENT_TIMESTAMP;'; if field create_time is a TIMESTAMP, you could set CURRENT_TIMESTAMP as default value for it.

MySQL Unmodifiable Column?

Is it possible to declare that a column in MySQL should be unmodifiable once initially set? I have a column that has the following definition: created timestamp default current_timestamp and I'd like to make sure that nobody messes with it after my rows are created.
You can accomplish this using a BEFORE UPDATE trigger:
DELIMITER $$
CREATE TRIGGER trFoo BEFORE UPDATE ON foo
FOR EACH ROW BEGIN
IF NEW.Bar != OLD.Bar THEN
SET NEW.Bar = OLD.Bar;
END IF;
END$$
DELIMITER ;