MySQL Trigger for after insert and update table - mysql

i was created a table for content management.I am not familiar with Mysql trigger.
Key Default
a varchar(50)
b varchar(50)
c text
status varchar(100)
This my table.I was created a trigger When each table update table change the status.
DELIMITER $$
CREATE TRIGGER tr2 BEFORE insert or UPDATE ON p
FOR EACH ROW BEGIN
SET NEW.status = '1';
END;
$$
DELIMITER ;
This trigger only update when the row will be modified .How can create trigger for change the "status" during every insert and update.. Please help me any one

This is not correct syntax. Just create a trigger before update
DELIMITER $$
CREATE TRIGGER tr2 BEFORE UPDATE ON p
FOR EACH ROW BEGIN
SET NEW.date = '1';
END;
$$
DELIMITER ;
and make the default value for column status = '1'.
CREATE TABLE p(
a varchar(50),
b varchar(50),
c text,
status varchar(100) NOT NULL DEFAULT '1'
);
That way whenever you insert a row into p and don't specify a value for status, status will be 1. You could create another trigger BEFORE INSERT but I don't recommend that. And the above solution does the same.

Related

MYSQL: I am trying to set a trigger to update my current row on update.(not updating all the rows just the updated row) [duplicate]

Here's what I'm trying to do:
When there's a new INSERT into the table ACCOUNTS, I need to update the row in ACCOUNTS where pk = NEW.edit_on by setting status='E' to denote that the particular (old) account has been edited.
DELIMITER $$
DROP TRIGGER IF EXISTS `setEditStatus`$$
CREATE TRIGGER `setEditStatus` AFTER INSERT on ACCOUNTS
FOR EACH ROW BEGIN
update ACCOUNTS set status='E' where ACCOUNTS.pk = NEW.edit_on ;
END$$
DELIMITER ;
The requirement is NOT that I manipulate the newly inserted column, but an already existing column with pk = NEW.edit_on
However, I can't update the same table: Can't update table ACCOUNTS ... already used by the statement that invoked this trigger
Please suggest a workaround
PS: I have already gone through Updating table in trigger after update on the same table, Insert into same table trigger mysql, Update with after insert trigger on same table and mysql trigger with insert and update after insert on table but they dont seem to answer my question.
Edit
ACCOUNTS Table:
CREATE TABLE `ACCOUNTS` (
`pk` bigint(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` bigint(9) unsigned NOT NULL,
`edit_on` bigint(10) unsigned DEFAULT NULL,
`status` varchar(1) NOT NULL DEFAULT 'A',
PRIMARY KEY (`pk`) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=2147483726 DEFAULT CHARSET=latin1
It seems that you can't do all this in a trigger. According to the documentation:
Within a stored function or trigger, it is not permitted to modify a table that is already being used (for reading or writing) by the statement that invoked the function or trigger.
According to this answer, it seems that you should:
create a stored procedure, that inserts into/Updates the target table, then updates the other row(s), all in a transaction.
With a stored proc you'll manually commit the changes (insert and update). I haven't done this in MySQL, but this post looks like a good example.
This is how I update a row in the same table on insert
activationCode and email are rows in the table USER.
On insert I don't specify a value for activationCode, it will be created on the fly by MySQL.
Change username with your MySQL username and db_name with your db name.
CREATE DEFINER=`username`#`localhost`
TRIGGER `db_name`.`user_BEFORE_INSERT`
BEFORE INSERT ON `user`
FOR EACH ROW
BEGIN
SET new.activationCode = MD5(new.email);
END
Had the same problem but had to update a column with the id that was about to enter, so you can make an update should be done BEFORE and AFTER not BEFORE had no id so I did this trick
DELIMITER $$
DROP TRIGGER IF EXISTS `codigo_video`$$
CREATE TRIGGER `codigo_video` BEFORE INSERT ON `videos`
FOR EACH ROW BEGIN
DECLARE ultimo_id, proximo_id INT(11);
SELECT id INTO ultimo_id FROM videos ORDER BY id DESC LIMIT 1;
SET proximo_id = ultimo_id+1;
SET NEW.cassette = CONCAT(NEW.cassette, LPAD(proximo_id, 5, '0'));
END$$
DELIMITER ;
On the last entry; this is another trick:
SELECT AUTO_INCREMENT FROM information_schema.tables WHERE table_schema = ... and table_name = ...
DELIMITER $$
DROP TRIGGER IF EXISTS `setEditStatus`$$
CREATE TRIGGER `setEditStatus` **BEFORE** INSERT on ACCOUNTS
FOR EACH ROW BEGIN
SET NEW.STATUS = 'E';
END$$
DELIMITER ;
Instead you can use before insert and get max pkid for the particular table and then update the maximium pkid table record.

SQL After Update Trigger

Im having some trouble with sql triggers in MySQL. The tables below are just used for testing.
First table:
CREATE TABLE `test`.`t1` (
`c1` INT NOT NULL,
`c2` VARCHAR(45) NULL,
`c3` VARCHAR(45) NULL,
PRIMARY KEY (`c1`));
Second Table:
CREATE TABLE `test`.`t2` (
`cc1` INT NOT NULL,
`cc2` VARCHAR(45) NULL,
`cc3` VARCHAR(45) NULL,
PRIMARY KEY (`cc1`));
cc1 references c1
ALl i want to do is, if the values in c2 are updated, then the corresponding field should be updated in cc2.
The trigger i came up with is:
DROP TRIGGER IF EXISTS `test`.`t1_AFTER_UPDATE`;
DELIMITER $$
USE `test`$$
CREATE DEFINER = CURRENT_USER TRIGGER `test`.`t1_AFTER_UPDATE` AFTER UPDATE ON `t1` FOR EACH ROW
BEGIN
update t2
set cc2=c2
where t2.cc1=t1.c1;
END$$
DELIMITER ;
This executes with no errors but if i try to update the values of c2,
UPDATE `test`.`t1` SET `c2` = '23' WHERE (`c1` = '11');
Operation failed: There was an error while applying the SQL script to
the database. ERROR 1054: 1054: Unknown column 't1.c1' in 'where
clause'
The update goes through if i remove the trigger.
In a Trigger, we refer to columns in the rows being updated/inserted/deleted by NEW (after operation), and OLD (before operation) keywords.
You will need to use these keywords in order to be able to update the other table.
Also, we can optimize the Trigger to initiate UPDATE operation only when there has been a change observed in the c2 value.
DROP TRIGGER IF EXISTS `test`.`t1_AFTER_UPDATE`;
DELIMITER $$
USE `test`$$
CREATE DEFINER = CURRENT_USER TRIGGER `test`.`t1_AFTER_UPDATE`
AFTER UPDATE ON `t1` FOR EACH ROW
BEGIN
-- Check if there has been any change in the c2 value or not
IF (NEW.c2 <> OLD.c2) THEN
-- Update only when there is some change
UPDATE t2
SET cc2 = NEW.c2 -- access the recent updated value of c2 using NEW keyword
WHERE cc1 = NEW.c1; -- access the c1 value of updated row using NEW keyword
END IF;
END$$
DELIMITER ;

Create Stored Procedure to update field for a new record

I am trying to create a stored procedure in MYSQL that populates a field if left blank while creating the record. Specifically we have an application that uses a CC field to populate e-mail address when a new ticket is created.
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `cc_update`()
BEGIN
SELECT * FROM `ehelpdesk`.`ticket` WHERE `CC` = 'Null';
UPDATE `ehelpdesk`.`ticket` SET `CC`='email#mail.com';
END
What i'm not figuring out is how to call the procedure when a new ticket or 'ID' is created.
Here's the full code I used to create the trigger
DELIMITER $$
CREATE TRIGGER `ins_cc` BEFORE INSERT ON `ticket` FOR EACH ROW BEGIN
IF (NEW.CC IS NULL) THEN
SET NEW.CC='email.string';
End If;
end$$
DELIMITER ;
You could create a trigger, which is be execute each time a record is inserted to the ehelpdesk table:
CREATE TRIGGER `ticket_BINS` BEFORE INSERT ON `ticket` FOR EACH ROW
BEGIN
IF (NEW.CC IS NULL) THEN
SET NEW.CC= "email#mail.com";
END IF;
END;
For what you are doing, ensure that CC is not null, I 'd suggest setting the default value of ticket.CC to email#mail.com
ALTER TABLE `ehelpdesk`.`ticket`
CHANGE COLUMN `CC` `CC` VARCHAR(45) NULL DEFAULT 'email#mail.com' ;
Your stored procedure is not correct
CREATE DEFINER=`root`#`localhost` PROCEDURE `cc_update`()
BEGIN
UPDATE `ehelpdesk`.`ticket` SET `CC`='email#mail.com' WHERE `CC` IS NULL;
END

creating trigger inserting UNIX_TIMESTAMP() to a log table

Hi im stuck on the syntax of making this trigger to insert values to my log table. Using the sql tab inside phpmyadmin an error appears before executing the sql statement
`#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 8 `
here is my sql statement in creating a trigger
CREATE TRIGGER after_insert_list
AFTER INSERT ON list FOR EACH ROW
BEGIN
INSERT INTO log (user_id, action, date_log)
VALUES (
NEW.user_id,
NEW.action,
UNIX_TIMESTAMP()
);
END
Create your trigger like follows:
delimiter |
CREATE TRIGGER testref
BEFORE INSERT ON test1FOR EACH ROW BEGIN
INSERT INTO test2 SET a2 = NEW.a1;
DELETE FROM test3 WHERE a3 = NEW.a1;
UPDATE test4 SET b4 = b4 + 1 WHERE a4 = NEW.a1;
END;
|
delimiter ;
Here is a 100% working example:
Table demo
CREATE TABLE `demo` (
`id` int NOT NULL AUTO_INCREMENT,
`text` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
`updated_at` int NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
);
Trigger on INSERT
DELIMITER ;;
CREATE TRIGGER `updated_at__on_insert`
BEFORE INSERT
ON `demo`
FOR EACH ROW
BEGIN
SET new.updated_at = UNIX_TIMESTAMP();
END;;
DELIMITER ;
Trigger on UPDATE
DELIMITER ;;
CREATE TRIGGER `updated_at__on_update`
BEFORE UPDATE
ON `demo`
FOR EACH ROW
BEGIN
SET new.updated_at = UNIX_TIMESTAMP();
END;;
DELIMITER ;
p.s. I was looking for such a solution for my CMS EFFCORE.

MySQL - Trigger for updating same table after insert

Here's what I'm trying to do:
When there's a new INSERT into the table ACCOUNTS, I need to update the row in ACCOUNTS where pk = NEW.edit_on by setting status='E' to denote that the particular (old) account has been edited.
DELIMITER $$
DROP TRIGGER IF EXISTS `setEditStatus`$$
CREATE TRIGGER `setEditStatus` AFTER INSERT on ACCOUNTS
FOR EACH ROW BEGIN
update ACCOUNTS set status='E' where ACCOUNTS.pk = NEW.edit_on ;
END$$
DELIMITER ;
The requirement is NOT that I manipulate the newly inserted column, but an already existing column with pk = NEW.edit_on
However, I can't update the same table: Can't update table ACCOUNTS ... already used by the statement that invoked this trigger
Please suggest a workaround
PS: I have already gone through Updating table in trigger after update on the same table, Insert into same table trigger mysql, Update with after insert trigger on same table and mysql trigger with insert and update after insert on table but they dont seem to answer my question.
Edit
ACCOUNTS Table:
CREATE TABLE `ACCOUNTS` (
`pk` bigint(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` bigint(9) unsigned NOT NULL,
`edit_on` bigint(10) unsigned DEFAULT NULL,
`status` varchar(1) NOT NULL DEFAULT 'A',
PRIMARY KEY (`pk`) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=2147483726 DEFAULT CHARSET=latin1
It seems that you can't do all this in a trigger. According to the documentation:
Within a stored function or trigger, it is not permitted to modify a table that is already being used (for reading or writing) by the statement that invoked the function or trigger.
According to this answer, it seems that you should:
create a stored procedure, that inserts into/Updates the target table, then updates the other row(s), all in a transaction.
With a stored proc you'll manually commit the changes (insert and update). I haven't done this in MySQL, but this post looks like a good example.
This is how I update a row in the same table on insert
activationCode and email are rows in the table USER.
On insert I don't specify a value for activationCode, it will be created on the fly by MySQL.
Change username with your MySQL username and db_name with your db name.
CREATE DEFINER=`username`#`localhost`
TRIGGER `db_name`.`user_BEFORE_INSERT`
BEFORE INSERT ON `user`
FOR EACH ROW
BEGIN
SET new.activationCode = MD5(new.email);
END
Had the same problem but had to update a column with the id that was about to enter, so you can make an update should be done BEFORE and AFTER not BEFORE had no id so I did this trick
DELIMITER $$
DROP TRIGGER IF EXISTS `codigo_video`$$
CREATE TRIGGER `codigo_video` BEFORE INSERT ON `videos`
FOR EACH ROW BEGIN
DECLARE ultimo_id, proximo_id INT(11);
SELECT id INTO ultimo_id FROM videos ORDER BY id DESC LIMIT 1;
SET proximo_id = ultimo_id+1;
SET NEW.cassette = CONCAT(NEW.cassette, LPAD(proximo_id, 5, '0'));
END$$
DELIMITER ;
On the last entry; this is another trick:
SELECT AUTO_INCREMENT FROM information_schema.tables WHERE table_schema = ... and table_name = ...
DELIMITER $$
DROP TRIGGER IF EXISTS `setEditStatus`$$
CREATE TRIGGER `setEditStatus` **BEFORE** INSERT on ACCOUNTS
FOR EACH ROW BEGIN
SET NEW.STATUS = 'E';
END$$
DELIMITER ;
Instead you can use before insert and get max pkid for the particular table and then update the maximium pkid table record.