MySQL BEFORE UPDATE TRIGGER giving ERROR - mysql

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 ;

Related

MySQL how to properly check a variable's value from SELECT INTO statement

I have a before insert trigger in a MySQL 8.0 database that checks for the incoming status and passes it along to the stored procedure, which then returns a value to be SET and passed along to be inserted. The stored procedure is being called correctly; however, when checking the entry in the database, the desired value of 1 is expected. However, NULL is there.
Here is the BEFORE_INSERT trigger on the table
CREATE DEFINER=`user`#`` TRIGGER `data_BEFORE_INSERT` BEFORE INSERT ON `data` FOR EACH ROW BEGIN
DECLARE newSearchAddressId INTEGER;
IF NEW.status = 'fresh' THEN
CALL CALC_FRESH_SEARCH_ADDRESS_ID(NEW.lead, #newSearchAddressId);
SET NEW.searchAddressId = #newSearchAddressId;
END IF;
END
Here is what's in the stored procedure:
CREATE DEFINER=`user`#`` PROCEDURE `CALC_FRESH_SEARCH_ADDRESS_ID`(
IN leadId INT,
OUT newSearchAddressId INT
)
proc_label: BEGIN
DECLARE lastSearchAddressID INT;
DECLARE lastStatus VARCHAR(100);
SELECT
`searchAddressId`,
`status`
INTO
lastSearchAddressID,
lastStatus
FROM `leads`
WHERE `id` = leadId;
-- if there is no status previous it's a first time entry
IF lastStatus IS NULL THEN
SET newSearchAddressId = 1;
LEAVE proc_label;
END IF;
END
In the SELECT statement above from leads table I am assured that only one row will be returned.
The desired outcome is that I select those two columns, status and searchAddressId, and if status is NULL, then we know that there is no previous entry and, therefore, a brand new record. Because it is a brand new record, we assign the #newSearchAddressId to the value of 1 and leave the stored procedure early.
I think I am incorrectly setting the variables or checking in the IF statement. That's at least what I think is going on. I have looked at this post and tried setting just one variable to check with an IF statement but the same undesired result of NULL being in the database.
Here is sample data:
DROP TABLE IF EXISTS `data`;
CREATE TABLE `data` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`lead` INT NOT NULL,
`status` VARCHAR(100) NOT NULL,
`searchAddressId INT NOT NULL
) ENGINE=INNODB;
INSERT INTO `data` (`lead`, `status`, `searchAddressId`)
VALUES(1, 'fresh', 1),
VALUES(2, 'suspended', 1),
VALUES(3, 'stale', 1),
VALUES(4, 'fresh', 1),
VALUES(5, 'cancelled', 1);
Based on the data above, here is what I am expecting from the procedure above
DECLARE lastSearchAddressID INT;
DECLARE lastStatus VARCHAR(100);
SELECT `searchAddressId`, `status`
INTO lastSearchAddressID, lastStatus
FROM `data`
WHERE `lead` = 6;
based on the SELECT statement above searchAddressID and lastStatus should be NULL
so when reaching the IF statement of
IF lastStatus IS NULL THEN
SET newSearchAddressId = 1;
LEAVE proc_label;
END IF;
Integer 1 should be assigned to the OUT newSearchAddressId INT in the stored procedure's parameters.
A follow-up query of
SELECT * FROM `data` WHERE `lead` = 6;
Would yield:
id
lead
status
searchAddress
6
6
'fresh'
1
What is yielded:
id
lead
status
searchAddress
6
6
'fresh'
NULL
here is the db fiddle the fiddle is not working but while I fiddle with getting it working I think you can see more clearly the expectations

Mysql 5.7 Issue in declare handler for duplicate key

We are facing an issue in declaring handlers in MYSQL 5.7 stored procedure.
Using the documentation present in https://dev.mysql.com/doc/refman/5.7/en/get-diagnostics.html, I'm trying to create handler in my stored procedure to do the following:
If a duplicate key appears, log it and move on insert good row.
End of the stored proc, get me all the error and success rows inserted.
As you can see below, we don't have primary key for table, however have the unique key constraint.
Input
CALL userTableInsert('{"userid":100, "username":"Hello"}, {"userid":102, "username":"World"}, {"userid":102, "username":"World"}', #got_dups)
Expected Output
100:Hello should get inserted and 102:World should get errored out and status needs to be corrected depicted in the output of the stored procedure.
Getting ERR : Error Code: 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 'DECLARE CONTINUE HANDLER FOR SQLEXCEPTION ...'
Table: user_table
CREATE TABLE `user_table` (
user_id int(20) NOT NULL,
user_name varchar(255) DEFAULT NULL,
created_by varchar(255) NOT NULL,
created_date date NOT NULL,
UNIQUE KEY `user_ukey` (user_id, user_name)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
===============================================
Stored Procedure
===============================================
DELIMITER $$
DROP PROCEDURE IF EXISTS schema.userTableInsert$$
CREATE PROCEDURE schema.userTableInsert(IN JSONArrayParam MEDIUMTEXT, OUT
got_dups INT)
SQL SECURITY INVOKER
BEGIN
DECLARE code CHAR(5) DEFAULT '00000';
DECLARE msg TEXT;
DECLARE rows INT;
DECLARE result TEXT;
DECLARE rowsJSON MEDIUMTEXT DEFAULT NULL;
SET rowsJSON = TRIM(JSONArrayParam);
SET rowsJSON = TRIM(LEADING '[' FROM rowsJSON);
SET rowsJSON = TRIM(TRAILING ']' FROM rowsJSON);
DROP TEMPORARY TABLE IF EXISTS rowsToUse;
CREATE TEMPORARY TABLE rowsToUse (
user_id INT NOT NULL,
user_name VARCHAR(255) DEFAULT NULL
) ENGINE=MEMORY;
WHILE (rowsJSON != '') DO
BEGIN
DECLARE rowJSON VARCHAR(4096) DEFAULT NULL;
DECLARE temp JSON;
DECLARE userid INT DEFAULT NULL;
DECLARE username VARCHAR(255) DEFAULT NULL;
SET rowJSON = CONCAT(SUBSTRING_INDEX(rowsJSON, '}', 1), '}');
SET temp = JSON_EXTRACT(rowJSON, '$.userid');
SET userid = COALESCE(IF(JSON_TYPE(temp) = 'NULL', NULL, REPLACE(temp, '\"', '')));
SET temp = JSON_EXTRACT(rowJSON, '$.username');
SET username = COALESCE(IF(JSON_TYPE(temp) = 'NULL', NULL, REPLACE(temp, '\"', '')));
INSERT INTO rowsToUse(user_id, user_name)
VALUES(userid, username);
IF LOCATE('{', rowsJSON, 2) > 0 THEN
SET rowsJSON = SUBSTRING(rowsJSON, LOCATE('{', rowsJSON, 2));
ELSE
SET rowsJSON = '';
END IF;
END;
END WHILE;
SET SQL_SAFE_UPDATES=0;
# Getting syntax error here
DECLARE CONTINUE HANDLER FOR 1062
BEGIN
GET DIAGNOSTICS CONDITION 1
code = RETURNED_SQLSTATE, msg = MESSAGE_TEXT;
END;
INSERT INTO user_table(user_id, user_name, created_by , created_date)
SELECT user_id, user_name, 'system', NOW()
FROM rowsToUse;
IF code = '00000' THEN
GET DIAGNOSTICS rows = ROW_COUNT;
SET result = CONCAT('insert succeeded, row count = ',rows);
ELSE
SET result = CONCAT('insert failed, error = ',code,', message = ',msg);
END IF;
DROP TEMPORARY TABLE IF EXISTS rowsToUse;
SET SQL_SAFE_UPDATES=1;
SELECT result;
END
$$
DELIMITER ;
==============================================================
Kindly help me on this.

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 ;

MySQL/MariaDB trigger error

MariaDB version 10.1.16.
I can't find what is the problem in the below trigger:
DROP TRIGGER IF EXISTS `insert_customer`;
DELIMITER |
CREATE TRIGGER `insert_customer` AFTER INSERT ON `installations`
FOR EACH ROW BEGIN
DECLARE customerId INT DEFAULT NULL;
DECLARE versionCode INT DEFAULT NULL;
SELECT c.`id`, c.`version_code` INTO #customerId, #versionCode FROM `customers` c WHERE c.`phone` = NEW.`phone`;
IF #customerId IS NULL THEN
INSERT INTO `customers` (`phone`, `imei`, `platform`, `version_code`, `created`, `modified`) VALUES (NEW.`phone`, NEW.`imei`, NEW.`platform`, NEW.`version_code`, NOW(), NOW());
ELSEIF NEW.`version_code` > #versionCode THEN
UPDATE `customers` SET `version_code` = NEW.`version_code` WHERE `id` = #customerId;
END IF;
END;|
DELIMITER ;
It says 1064 - syntax error near THEN INSERT but I'm sure the problem is elsewhere. Please help.

Trigger to track changes in MySQL Database

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());