I have a table reservation details which has columns and one of the column is creation date.
I want to create a trigger which checks whether the creation date is first day of the year. If it is then, insert values into to master_ids table. I have created a trigger but don't know whether its correct or not. My project is in php.
CREATE TRIGGER upd_check BEFORE INSERT ON ColdStorage.ReservationDetails
FOR EACH ROW
BEGIN
IF NEW.creationdate = DATE_FORMAT(NOW() ,'%Y-01-01') then
UPDATE master_ids SET nextOccId="1",nextResId="1",nextAgrnoId="1",nextRecNo="1";
END if;
END;
Please suggest me some solutions. I also want that if the date is 01-01-yy then.. its should not insert the row which i m inserting.
You need to change the delimiter. MySQL sees the first ; as the end of the CREATE TRIGGER statement, and thinks the whole statement ends there. So you have to change the delimiter like this:
/* Change the delimiter */
DELIMITER $$
CREATE TRIGGER upd_check BEFORE INSERT ON ColdStorage.ReservationDetails
FOR EACH ROW
BEGIN
IF NEW.creationdate = DATE_FORMAT(NOW() ,'%Y-01-01') then
insert into master_ids values ('0','0','0','0');
END if;
END$$
/* the CREATE TRIGGER statement ends with new delimiter */
/* change the delimiter back to ; */
DELIMITER ;
I haven't tested it, but it seems fine. What bothers me is that this will work just for one day during the year, the other 364 (365) days it is completely useless, and looks like an overhead.
Related
Firstly let me say I'm new to and just getting my head around MySQL and finding date manipulation has its challenges. It seems to me it should be possible to have three columns:
column A contains date member joined 2020-01-12 for example, mapped from a form.
column B contains the length of membership in years 1 or 5, currently entered manually
Then calculate expiry 'date A'+ 'integer B' Year inserted in column C on member creation or update
It's OK to do manually but I feel it should be something automatic.
If anyone can give me a start or point to a tutorial that might help I'd be grateful.
In MySql you can use DATE_ADD() funciton:
SELECT columnA, columnB, DATE_ADD(columnA, INTERVAL columnB YEAR) AS EXPIRY;
Use this web page as reference.
You could define triggers BEFORE INSERT and/or BEFORE UPDATE which will do the job for you:
BEFORE INSERT trigger:
DROP TRIGGER IF EXISTS before_insert;
DELIMITER $$
CREATE TRIGGER before_insert
BEFORE INSERT ON `my_table`
FOR EACH ROW
BEGIN
SET NEW.`valid` = DATE_ADD(NEW.`date`, INTERVAL NEW.`membership` YEAR);
END$$
DELIMITER ;
BEFORE UPDATE trigger:
DROP TRIGGER IF EXISTS before_update;
DELIMITER $$
CREATE TRIGGER before_update
BEFORE UPDATE ON `my_table`
FOR EACH ROW
BEGIN
SET NEW.`valid` = DATE_ADD(NEW.`date`, INTERVAL NEW.`membership` YEAR);
END$$
DELIMITER ;
It is quite enough to insert both date and membership values during insert (obviously) or to update membership value on already inserted record(s).
Your Column C is the valid column in both queries.
I am trying to write a trigger that combines an insert & select, I've found numerous topics online, but, none seem to relate to my exact problem, maybe I am missing something with my structure?
The aim of this is that on the event of a cancellation in our audit log, then I define a cancellation reason based on a series of business logic in another table, this logic is drawn together in a SELECT using CASE & subqueries.
I want to expand the following trigger that currently works and replace the SET cancellation_point='test' element with the SELECT query I just mentioned.
DELIMITER $$
CREATE
TRIGGER `cancellation_stage` BEFORE INSERT ON `log`
FOR EACH ROW
BEGIN
IF (NEW.status='cancel' AND NEW.type='0') THEN
INSERT INTO cancellation_stage
SET
id=NEW.id,
property_id=NEW.entity_id,
cancellation_date=NOW(),
cancellation_point='test';
END IF;
END;
$$
DELIMITER ;
I did try to construct this myself using various guidance from here, but, its just not working. I got this code to physically save as a trigger, but, it did not populate the data in the database (I have replaced my SELECT with a basic query example below):
DELIMITER $$
CREATE
TRIGGER `cancellation_stage` BEFORE INSERT ON `log`
FOR EACH ROW
BEGIN
DECLARE cancellation_point VARCHAR(255);
SET cancellation_point = ( SELECT * FROM x);
IF (NEW.transition='cancel' AND NEW.entity_type='property') THEN
INSERT INTO cancellation_stage
SET
id=NEW.id,
property_id=NEW.entity_id,
cancellation_date=NOW(),
cancellation_point=NEW.cancellation_point;
END IF;
END;
$$
DELIMITER ;
Any help would be greatly appreciated :)
I have this code for the trigger:
CREATE TRIGGER `insert_after` AFTER INSERT ON `hyk50_0001`
FOR EACH ROW BEGIN
INSERT INTO hyk50_0001_copy(Fecha)
SELECT Fecha FROM hyk50_0001
END;
but doesn't work, it says a syntax error but I didn't see it
I'm using Navicat. And hyk50_0001_copy it's a identical copy of hyk50_0001.
The target is take the new row of hyk50_0001 and INSERT in hyk50_0001_copy
I want put all the database, but if it doesn't work with only a value I can't progress.
I don't see a syntax error, but I assume you intend:
DELIMITER $$
CREATE TRIGGER `insert_after` AFTER INSERT ON `hyk50_0001`
FOR EACH ROW
BEGIN
INSERT INTO hyk50_0001_copy(Fecha)
VALUES (new.Fecha)
END;$$
DELIMITER ;
That is, you probably want to insert only the row that was just created.
So I am trying to create trigger that will only execute when a specific column within a table is updated. The table in question is track the column in question is track.track_hits. What I want to do is if that value changes then it inserts a value into a table called play_log. The insert should be the track_id from track and a timestamp.
The code I have done so far is below but it doesn't work, how can it be fixed?
CREATE TRIGGER pi_play AFTER UPDATE ON track
FOR EACH ROW
BEGIN
if :new.track_hits != :old.track_hits
then
INSERT INTO play_log (track_id,access_time)
VALUES (NEW.track_id, NOW())
end if;
END;
NEW and OLD do not need : in front. Also, when creating triggers, you may need to change the delimiter. If you don't change the delimiter, your create trigger statement may be terminated early.
Here's how I would do it:
delimiter |
create trigger pi_play after update on track
for each row
begin
if new.track_hits != old.track_hits then
insert into play_log(track_id, access_time) values (new.track_id, now());
end if;
end|
delimiter ;
Here's the fiddle showing it in action: http://sqlfiddle.com/#!2/3d99d/1 Notice that I changed the delimiter in the schema window to | instead of the default ;. Since SQL uses JDBC and JDBC doesn't take the command DELIMITER, I chose the delimiter.
Ok, I've started writing my first trigger in mysql, it doesn't give an errors, but it doesn't work either...
DELIMITER $$
DROP TRIGGER `cc`.`update_expires_date_trig`$$
CREATE TRIGGER `update_expires_date_trig` BEFORE INSERT ON `credit_test_acc`
FOR EACH ROW BEGIN
UPDATE credit_test_acc SET date_expires_acc = DATE_ADD(CURDATE(), INTERVAL 6 MONTH) WHERE type_acc = 'init'
END;
$$
DELIMITER ;
I have 2 problems:
Can't update table 'credit_test_acc' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
Is the trigger as defined going to update JUST the JUST inserted row, or EVERY row in the database?
As far as I know, it must be rewritten like this to work as you expect it to work:
DELIMITER $$
DROP TRIGGER `cc`.`update_expires_date_trig`$$
CREATE TRIGGER `update_expires_date_trig` BEFORE INSERT ON `credit_test_acc`
FOR EACH ROW BEGIN
SET NEW.date_expires_acc = DATE_ADD(CURDATE(), INTERVAL 6 MONTH)
END;
$$
DELIMITER ;
Where NEW refers to the row that is about to be inserted into the table. You didn't give any explanation as to what role 'type_acc' might play here (I can think of more than one way it could be interpreted), so I've left that out. If it is what I think it is, you can apply it like this:
IF NEW.type_acc = 'init' THEN # do whatever you want here
A Trigger cannot change the table that triggered it.
Either directly or indirectly.
You can only change values in a BEFORE trigger by SET new.field = newvalue.
And this can only effect the 'current' row that pulled the trigger (so to speak).