Trigger to track changes in MySQL Database - mysql

I cannot seem to create a trigger. I have tried it the two ways below for the update. I keep getting a syntax error with the insert statement. I have searched forums and web searches for the past 4 hrs with no change. There is alot more code to this, It basically repeats itself. Any help would be appreciated. Thank You. I am running MySQL 5.0 and acessing via phpMyAdmin 2.8.2.4 as Administrator/Root.
TRY 1 (with and without qoutes on all fields and names)
CREATE TRIGGER insert_classes
AFTER insert ON Classes
FOR EACH ROW
BEGIN
insert into insert_tracking_classes (classID, Title, classDesc, Category, isEvent, picLeft, picTop, picRight, picBottom, prnColor, modified)
values(NEW.classID, NEW.Title, NEW.classDesc, NEW.Category, NEW.isEvent, NEW.picLeft, NEW.picTop, NEW.picRight, NEW.picBottom, NEW.prnColor, NOW());
END;
CREATE TRIGGER insert_classes
AFTER insert ON Classes
FOR EACH ROW
BEGIN
insert into insert_tracking_classes
set classID = NEW.classID,
Title = NEW.Title,
classDesc = NEW.classDesc,
Category = NEW.Category,
isEvent = NEW.isEvent,
picLeft = NEW.picLeft,
picTop = NEW.picTop,
picRight = NEW.picRight,
picBottom = NEW.picBottom,
prnColor = NEW.prnColor,
modified = NOW();
END;
ERROR
#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 * (at the end of the insert/values statement)
TRY 2
DELIMITER $$
CREATE TRIGGER insert_classes AFTER insert ON Classes
FOR EACH ROW BEGIN
insert into insert_tracking_classes (classID, Title, classDesc, Category, isEvent, picLeft, picTop, picRight, picBottom, prnColor, modified)
values(NEW.classID, NEW.Title, NEW.classDesc, NEW.Category, NEW.isEvent, NEW.picLeft, NEW.picTop, NEW.picRight, NEW.picBottom, NEW.prnColor, NOW());
END$$
DELIMITER ;
ERROR
SQL query:
DELIMITER $$ CREATE TRIGGER insert_classes AFTER INSERT ON Classes
FOR EACH
ROW BEGIN
INSERT INTO insert_tracking_classes( classID, Title, classDesc, Category, isEvent, picLeft, picTop, picRight, picBottom, prnColor, modified )
VALUES (
--> NEW.classID, NEW.Title, NEW.classDesc, NEW.Category, NEW.isEvent, NEW.picLeft, NEW.picTop, NEW.picRight, NEW.picBottom, NEW.prnColor, NOW( )
);
MySQL said: Documentation
#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 'DELIMITER $$
CREATE TRIGGER insert_classes AFTER insert ON Classes
F' at line 1
My Tables
CREATE TABLE insert_tracking_classes ( --- Same table layout for Classes table minus Modified time and tracking_id
tracking_id int(11) NOT NULL AUTO_INCREMENT,
classID int(11) NOT NULL,
Title varchar(48) NOT NULL,
classDesc text,
Category varchar(128) default NULL,
isEvent int(8) default NULL,
picLeft int(8) default NULL,
picTop int(8) default NULL,
picRight int(8) default NULL,
picBottom int(8) default NULL,
prnColor varchar(4) default NULL,
modified datetime NOT NULL,
PRIMARY KEY (tracking_id)
);
Update: Have tried to use static values and removing the if and modified = NOW() statements with no change.

Had to remove Delimiter, Begin, and End statements.
ANSWER
DROP TRIGGER IF EXISTS insert_classes;
CREATE TRIGGER insert_classes AFTER insert ON Classes
FOR EACH ROW
insert into tracking_classes (command, classID, Title, classDesc, Category, isEvent, picLeft, picTop, picRight, picBottom, prnColor, modified)
values('insert', NEW.classID, NEW.Title, NEW.Desc, NEW.Category, NEW.isEvent, NEW.picLeft, NEW.picTop, NEW.picRight, NEW.picBottom, NEW.prnColor, NOW());

Related

How to fix "Can't update table testtab in stored function/trigger

I have created a table
CREATE TABLE testtab (
`id` int(11) NOT NULL AUTO_INCREMENT,
`customer_id` bigint(20) DEFAULT NULL,
`food_id` int(11) DEFAULT NULL,
`created_date` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
)
Table contains below row
INSERT INTO testtab (`customer_id`, `food_id`, `created_date`)
VALUES ('433', '9', '2019-05-14 12:00:54');
Now the condition is for a specific customer_id there can be only one row with food_id either 8 or 9.
Now I try to add the below insert statement
INSERT INTO testtab (`customer_id`, `food_id`, `created_date`)
VALUES ('433', '8', '2019-05-14 12:00:54');
Now It should either get failed or get deleted immediately after inserted(record with tag_id=8).I have used the below trigger.But unfortunately i got error
Can't update table 'testtab' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
DELIMITER $$
USE `ipay`$$
DROP TRIGGER /*!50032 IF EXISTS */ `testtabTrigger`$$
CREATE
TRIGGER `testtabTrigger` AFTER INSERT ON `testtab`
FOR EACH ROW BEGIN
IF ((SELECT COUNT(*) FROM testtab WHERE food_id =9 AND customer_id = new.customer_id) =1 && new.food_id = 8) THEN
DELETE FROM testtab WHERE food_id = 8 AND customer_id = new.customer_id;
END IF;
END;
$$
DELIMITER ;
The idea is that you do something like this:
CREATE TRIGGER `testtabTrigger` BEORE INSERT ON `testtab`
FOR EACH ROW
BEGIN
IF (EXISTS (SELECT COUNT(*)
FROM testtab tt
WHERE tt.food_id = 9 AND
tt.customer_id = new.customer_id
) AND
new.food_id = 8
) THEN
signal sqlstate '45000' set message_text = 'Attempted insert of 8 when there is a 9';
END IF;
END;

Creating a BEFORE INSERT TRIGGER IN MYSQL

I need help creating a BEFORE INSERT TRIGGER on mySQL Bench. im new to this please.
CREATE TABLE `quincyninying`.`toytracking` (
`Toyid` INT NOT NULL,
`ToyName` VARCHAR(50) NULL,
`Toycost` DECIMAL NULL,
`ToyAction` VARCHAR(50) NULL,
`ActionDate` DATETIME NULL,
PRIMARY KEY (`Toyid`));
CREATE TABLE `quincyninying`.`toy` (
`Toyid` INT NOT NULL,
`ToyName` VARCHAR(50) NULL,
`Toycost` DECIMAL NULL,
PRIMARY KEY (`Toyid`));
Create a BEFORE INSERT trigger on the toy table that adds a record to the toytracking table with the information from the toy table record that is being INSERTED, hard coded ToyAction that will be ‘INSERT’ and the current Date and time the record is inserted.
ERROR 1054: Unknown column 'inserted' in 'NEW' SQL Statement:
CREATE DEFINER = CURRENT_USER TRIGGER `quincyninying`.`toy_BEFORE_INSERT` BEFORE INSERT ON `toy`
FOR EACH ROW
BEGIN
IF new.inserted THEN
SET #toyaction = 'DELETE';
ELSE
SET #toyaction = 'NEW';
END IF;
INSERT INTO `quincyninying`.`toytracking` (toyId, ToyName, ToyCost, Toyaction, ActionDate)
VALUES (new.toyid, new.Toyname, new.Toycost,#Toyaction, now());
END
It throws me an error saying " ERROR 1054: Unknown column 'inserted' in 'NEW' "
Get rid of the IF new.inserted test, since there's no column with that name, and just hard-code INSERT as the value for the ToyAction column as you stated in the requirements.
CREATE DEFINER = CURRENT_USER TRIGGER `quincyninying`.`toy_BEFORE_INSERT` BEFORE INSERT ON `toy`
FOR EACH ROW
BEGIN
INSERT INTO `quincyninying`.`toytracking` (toyId, ToyName, ToyCost, Toyaction, ActionDate)
VALUES (new.toyid, new.Toyname, new.Toycost, 'INSERT', now());
END
Try this:
DELIMITER $$
CREATE
TRIGGER toy_before_insert BEFORE INSERT
ON toy
FOR EACH ROW BEGIN
IF NEW.Toyaction THEN
SET #Toyaction = 'DELETE';
ELSE
SET #Toyaction = 'NEW';
END IF;
INSERT INTO toytracking (toyId, ToyName, ToyCost, Toyaction, ActionDate) VALUES (NEW.Toyid, NEW.ToyName, NEW.ToyCost, #Toyaction, NOW());
END$$
DELIMITER ;

#1442 - Can't update table ... in stored function/trigger because it is already used by statement which invoked this stored function/trigger

I have this situation:
Two table in two databases:
1st: `persone`.`T_Persone` that contain detailed information about workers plus two fields empty by default: `user_id` and `username`;
2nd: `joomla`.`fe48y_users` that contain information of user in the CMS Joomla including `id` and `username`.
I created a procedure that insert a new user in joomla and return user_id and username of new user created.
I also created also 2 triggers (on update and on insert) that call the procedure and set user_id and username on `T_Persone` table.
I also created a trigger on delete of `joomla`.`fe48y_users` that update `persone`.`T_Persone` and set null to `user_id` and `username` fields.
This is the procedure:
CREATE DEFINER=`root`#`localhost` PROCEDURE `persone_users_upd`(IN `in_id` INT(10) UNSIGNED, IN `new_email` VARCHAR(255), IN `old_email` VARCHAR(255), OUT `out_user_id` INT(10) UNSIGNED, OUT `out_username` VARCHAR(255))
BEGIN
DECLARE has_email Boolean;
DECLARE my_user_id INT;
DECLARE my_username VARCHAR(255);
DECLARE my_name VARCHAR(255);
SELECT (CASE new_email WHEN '' THEN FALSE ELSE TRUE END) INTO #has_email;
IF #has_email THEN
SELECT CONCAT(`Nome`,' ',`Cognome`), COALESCE(`CF`,LOWER(SUBSTR(new_email, 1, INSTR(new_email, '#') - 1))) INTO #my_name, #my_username FROM `T_Persone` WHERE `IDPersona` = in_id;
IF new_email = old_email THEN
INSERT INTO `spmsf`.`fe48y_users` (`name`, `username`, `email`, `password`, `block`, `sendEmail`, `registerDate`, `lastvisitDate`, `activation`, `params`, `lastResetTime`, `resetCount`, `otpKey`, `otep`, `requireReset`) VALUES
(#my_name, #my_username, new_email, '<omissis>', 0, 1, NOW(), '0000-00-00 00:00:00', '', '{"admin_style":"","admin_language":"","language":"","editor":"","helpsite":"","timezone":"Europe/Rome"}', '0000-00-00 00:00:00', 0, '', '', 0) ON DUPLICATE KEY UPDATE `name` = VALUES(`name`), `email` = VALUES(`email`);
ELSE
UPDATE `spmsf`.`fe48y_users` SET `email` = #my_email WHERE `email` = new_email;
END IF;
SELECT `id`, `username` INTO #my_user_id, #my_username FROM `spmsf`.`fe48y_users` WHERE `email` = new_email;
INSERT IGNORE INTO `spmsf`.`fe48y_user_usergroup_map` (`user_id`,`group_id`) VALUES (#my_user_id, 10);
SET out_user_id=#my_user_id, out_username=#my_username;
END IF;
END
these are the triggers on `T_Persone`:
CREATE TRIGGER `persone_del` AFTER DELETE ON `T_Persone`
FOR EACH ROW BEGIN
IF OLD.`user_id` IS NOT NULL THEN
DELETE FROM `spmsf`.`fe48y_users` WHERE `id` = OLD.`user_id`;
DELETE FROM `spmsf`.`fe48y_user_usergroup_map` WHERE `user_id` = OLD.`user_id`;
END IF;
END
CREATE TRIGGER `persone_ins` BEFORE INSERT ON `T_Persone`
FOR EACH ROW BEGIN
CALL persone_users_upd(NEW.`IDPersona`,COALESCE(NEW.`Email`,NEW.`Email_alt`),COALESCE(NEW.`Email`,NEW.`Email_alt`), #user_id, #username);
SET NEW.`user_id` = #user_id, NEW.`username` = #username;
END
CREATE TRIGGER `persone_upd` BEFORE UPDATE ON `T_Persone`
FOR EACH ROW BEGIN
CALL persone_users_upd(NEW.`IDPersona`,COALESCE(NEW.`Email`,NEW.`Email_alt`),COALESCE(OLD.`Email`,OLD.`Email_alt`), #user_id, #username);
SET NEW.`user_id` = #user_id, NEW.`username` = #username;
END
and this is the trigger on `fe48y_users` delete:
CREATE TRIGGER `users_del` BEFORE DELETE ON `fe48y_users`
FOR EACH ROW BEGIN
DECLARE my_user_id Int;
SELECT COUNT(*) INTO #my_user_id FROM `personale`.`T_Persone` WHERE `user_id` = OLD.`id`;
IF #my_user_id > 0 THEN
UPDATE `personale`.`T_Persone` SET `user_id` = NULL, `username` = NULL WHERE `user_id` = OLD.`id`;
END IF;
END
SO, I have two problems:
1st: When I try to delete a user in `fe48y_users` I have the error
#1442 - Can't update table 'fe48y_users' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
2nd: When I insert a new person it don't appear in 'fe48y_users' but when I update it than appear.

Error importing a previously exported mysql trigger

I had a mysql trigger that has been working, I exported it and removed it and am trying to put it back, but I keep running into the following error:
#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 12
My trigger is:
CREATE TRIGGER `accounts_tracking` AFTER UPDATE ON `accounts`
FOR EACH ROW BEGIN
IF( NEW.`check_level` != OLD.`check_level` ) THEN
INSERT INTO `accounts_tracking` ( `change_type`, `account_id`, `field`, `old_int`, `new_int`, `old_time`, `new_time` )
VALUES
( "1",
OLD.id,
"check_level",
OLD.`check_level`,
NEW.`check_level`,
UNIX_TIMESTAMP(),
UNIX_TIMESTAMP());
END IF;
END
Line #12 is the 2nd UNIX_TIMESTAMP()
My table structure is as follows:
CREATE TABLE `accounts_tracking` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`change_type` smallint(5) unsigned NOT NULL,
`account_id` int(10) unsigned NOT NULL,
`field` varchar(255) NOT NULL,
`old_int` int(11) NOT NULL,
`new_int` int(11) NOT NULL,
`new_time` int(10) unsigned NOT NULL,
`old_time` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `account_id` (`account_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Server type: MySQL
Server version: 5.1.73-log
Thanks.
As barranka suggested in comments section, you need to enclose this trigger in a delimiter, like so:
DELIMITER $$
CREATE TRIGGER `accounts_tracking` AFTER UPDATE ON `accounts`
FOR EACH ROW BEGIN
IF( NEW.`check_level` != OLD.`check_level`) THEN
INSERT INTO `accounts_tracking` ( `change_type`, `account_id`, `field`, `old_int`, `new_int`, `old_time`, `new_time` )
VALUES
( "1",
OLD.id,
"check_level",
OLD.`check_level`,
NEW.`check_level`,
UNIX_TIMESTAMP(),
UNIX_TIMESTAMP());
END IF;
END$$
DELIMITER ;
The reason is that by adding a Begin and End to the statement you are essentially creating a stored routine/procedure with the trigger itself. In order to run multiple statements, like in stored routine/procedure, you need to add delimiters.
In other cases where you do not have the Begin and End within the trigger, you do not need the delimiters. For Example:
CREATE TABLE account (acct_num INT, amount DECIMAL(10,2));
CREATE TRIGGER ins_sum BEFORE INSERT ON account FOR EACH ROW SET #sum = #sum + NEW.amount;

MySQL BEFORE UPDATE TRIGGER giving ERROR

I've been working on a trigger for MySQL for a couple hours now, and I can't figure out what's wrong.
Here is my table structure:
CREATE TABLE IF NOT EXISTS `RentalVideo` (
`OrderID` int(11) NOT NULL,
`VideoBarcode` int(11) NOT NULL,
`RentalReturned` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`OrderID`,`VideoBarcode`),
KEY `RentalVideo_VideoBarcode_FK` (`VideoBarcode`)
)
Here's some sample data:
INSERT INTO `RentalVideo` (`OrderID`, `VideoBarcode`, `RentalReturned`) VALUES
(1, 223823, 0),
(1, 447956, 0),
(3, 705481, 0),
(4, 988908, 0),
(5, 143375, 0);
Here's the trigger that's not working:
CREATE
TRIGGER `RENT_FIVE_VIDEOS_MAX` BEFORE INSERT
ON `bollywoo_video`.`RentalVideo`
FOR EACH ROW BEGIN
-- variable declarations
DECLARE vRentedVideos int;
DECLARE vCustomer int;
-- trigger code
SELECT RentalOrder.CustID
FROM RentalOrder
WHERE RentalOrder.OrderID = NEW.OrderID
INTO vCustomer;
SELECT COUNT(*)
FROM RentalOrder, RentalVideo
WHERE RentalOrder.CustID = vCustomer
AND RentalVideo.RentalReturned = 0
AND RentalOrder.OrderId = RentalVideo.VideoID
INTO vRentedVideos;
IF vRentedVideos >= 5 THEN
CALL RAISE_APPLICATION_ERROR(-2000, 'Cannot checkout more than 5 videos');
END IF;
END
And last but not least, this is the error I'm getting:
Error
SQL query:
CREATE TRIGGER `RENT_FIVE_VIDEOS_MAX` BEFORE INSERT ON `bollywoo_video`.`RentalVideo`
FOR EACH
ROW BEGIN -- variable declarations
DECLARE vRentedVideos INT;
MySQL said: Documentation
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 6
The error appears to be occurring right before DECLARE vRentedVideos int;
Remove semicolon and try this
DELIMITER $$
CREATE
TRIGGER `RENT_FIVE_VIDEOS_MAX` BEFORE INSERT
ON `bollywoo_video`.`RentalVideo`
FOR EACH ROW BEGIN
...
END$$
DELIMITER ;