first mysql trigger failing - mysql

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).

Related

MySQL TRIGGER to INSERT BEFORE INSERT using SELECT, IF, etc

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 :)

How to get the time when a mysql trigger was created or last updated?

We have a trigger in our mysql database which on update affect some data in database. But for some calculation we need to know when this trigger was first created and when it was updated last. Is it possible to get this data from information_schema or any where else?
Unfortunately the answer is no. There is a column CREATED in the schema for triggers, but it is unused (always NULL) at the present time:
The following columns currently always contain NULL: TRIGGER_CATALOG,
EVENT_OBJECT_CATALOG, ACTION_CONDITION, ACTION_REFERENCE_OLD_TABLE,
ACTION_REFERENCE_NEW_TABLE, and CREATED.
You can find information about triggers in INFORMATION_SCHEMA.TRIGGERS:
SELECT * FROM INFORMATION_SCHEMA.TRIGGERS
Hope that helps.
Try this,
I don't know what datatype you are using for created.
But for example, I use DATETIME.
Before insert, and you just need to use SET:
Create:
DELIMITER $$ CREATE
TRIGGER yourtriggername BEFORE INSERT ON yourtablename
FOR EACH ROW
SET NEW.created = NOW();
END$$ DELIMITER ;
Update:
DELIMITER $$ CREATE
TRIGGER yourtriggername AFTER UPDATE ON yourtablename
FOR EACH ROW BEGIN
SET NEW.updated = CURRENT_TIMESTAMP where.....yourconditions;
END$$ DELIMITER ;
Hope it might help.

Creating Last Modified SQL Trigger

I am trying to create a trigger to update last_modified field when the row is updated.
This is what i have tried:
USE `mydb`;
DELIMITER $$
DROP TRIGGER IF EXISTS mydb.products_AUPD$$
USE `mydb`$$
CREATE TRIGGER `products_AUPD` AFTER UPDATE ON products
FOR EACH ROW BEGIN
SET NEW.`last_modified` = NOW();
END;
$$
DELIMITER ;
The problem is MySQL workbench wont let me save it (I'm assuming that there is something wrong with it but i can't find out what)
Turns out the version of MySQL Workbench I was using(6.0xxx) had a bug in it which played havoc with triggers. I updated to 6.2xxx.
That was the first problem.
The second problem was that i was using the NEW keyword in an AFTER trigger which is not allowed:
Within the trigger body, you can refer to columns in the subject table
(the table associated with the trigger) by using the aliases OLD and
NEW. OLD.col_name refers to a column of an existing row before it is
updated or deleted. NEW.col_name refers to the column of a new row to
be inserted or an existing row after it is updated.
So my new trigger looks like this:
CREATE DEFINER = CURRENT_USER TRIGGER `mydb`.`products_BEFORE_UPDATE` BEFORE UPDATE ON `products` FOR EACH ROW
BEGIN
SET NEW.`last_modified` = NOW();
END;
Notice there is no USE or DELIMITER statement? That is because the new version of MySQL Workbench puts this in for you (including the end delimiter $$):
USE `mydb`;
DELIMITER $$
USE `mydb`$$
DROP TRIGGER IF EXISTS `mydb`.`products_BEFORE_INSERT` $$
USE `mydb`$$
CREATE DEFINER = CURRENT_USER TRIGGER `mydb`.`products_BEFORE_INSERT` BEFORE INSERT ON `products` FOR EACH ROW
BEGIN
SET NEW.`last_modified` = NOW();
END;$$

How to create a trigger to find first day of the year?

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.

MySQL trigger to insert records from Table A to Table B

I am unable to get the following code to work, using this page for reference as well as of other posts on this site. I need to create a trigger that will insert a record in Table B whenever Table A is updated. The code below shows what I am attempting; however this produces a syntax error (#1064). I am also unclear on if I need to include the 'DELIMITER $$' syntax or not. I appreciate your help
DELIMITER $$
CREATE TRIGGER MyTrigger
AFTER INSERT
ON TableA
FOR EACH ROW
BEGIN
INSERT INTO TableB SET
TableA_id = NEW.TableB_id,
TableA_date = NEW.TableB_date,
TableA_comment = NEW.TableB_comment;
END;
END $$
DELIMITER ;
EDIT: in the pseudo-code above I am using a $TableName_$FieldName convention to indicate that Column A belongs to Table A, Column B belongs to Table B. I should have made that more clear in my original question. Someone commented below I have the NEW indicator on the wrong side (should be on Table A), but that comment appears to have been removed. Can someone please confirm? Thanks for all your help
Try this:
DELIMITER $$
CREATE TRIGGER MyTrigger
AFTER INSERT
ON TableA
FOR EACH ROW
BEGIN
INSERT INTO TableB SET
TableB_id = NEW.TableA_id,
TableB_date = NEW.TableA_date,
TableB_comment = NEW.TableA_comment;
END $$
DELIMITER ;
The DELIMITER here is used to tell mysql to treat all the following ; as part of the definition instead of actual command terminations.
Notice that I removed an unmatched END; just before the closing END $$
You have an erroneous END; in your trigger (every END should pair with a BEGIN).
For that matter, you don't even need the BEGIN ... END block, since the trigger contains only one statement (and if that block is omitted, you don't even need to change the statement delimiter because no semicolon appears within the CREATE TRIGGER statement):
CREATE TRIGGER MyTrigger AFTER INSERT ON TableA FOR EACH ROW
INSERT INTO TableB SET
TableA_id = NEW.TableB_id,
TableA_date = NEW.TableB_date,
TableA_comment = NEW.TableB_comment