I am trying to run the following script in mysql :
DELIMITER $$$
DROP TRIGGER IF EXISTS invoice_line_insert
$$$
CREATE TRIGGER invoice_line_insert AFTER INSERT
ON invoice_line FOR EACH ROW
BEGIN
IF NEW.type = "DELIVERY" THEN
UPDATE invoice
SET invoice.etdelivery_amount = invoice.etdelivery_amount + NEW.amount
WHERE invoice.id_invoice = NEW.invoice_parent_id_invoice;
ELSE
UPDATE invoice
SET invoice.etexpense_amount = invoice.etexpense_amount + NEW.amount
WHERE invoice.id_invoice = NEW.invoice_parent_id_invoice;
END IF;
UPDATE invoice
SET invoice.vatamount = (NEW.amount * ((
SELECT vat.rate
FROM vat
WHERE vat.id_vat = NEW.vat_id_vat
) / 100)) + invoice.vatamount
WHERE invoice.id_invoice = NEW.invoice_parent_id_invoice;
UPDATE invoice
SET invoice.itamount = invoice.vatamount +
invoice.etdelivery_amount +
invoice.etexpense_amount
WHERE invoice.id_invoice = NEW.invoice_parent_id_invoice;
END
$$$
When I run it in mySql Workbench, it is working fine, but when play 2 run it authomatically (in a file called 2.sql) I get the following error :
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 $$$ DROP TRIGGER IF EXISTS invoice_line_insert $$$ CREATE TRIGGER invo' at line 1 [ERROR:1064, SQLSTATE:42000], while trying to run this SQL script:
I read on the internet that the delimiter statement is only working on specific gui, not every time. Is that true ? Why ? How to resolve it because I need the delimiter statement ?
Thanks for your help.
This seems to be a duplicate of Play framework 2.0 evolutions and create trigger
(Note that, in my view, the better answer is the one posted by Roger on May 24 2013, i.e. the link above)
"delimiter" cannot be used in the evolution script text; I can't seem to find any documentation as to why this is so. But maybe it is got to do with the fact that "delimiter" is not an SQL statement but an SQL property.
However, there is a solution in the Evolutions section of Play 2 docs:
Play splits your .sql files into a series of semicolon-delimited statements before executing them one-by-one against the database. So if you need to use a semicolon within a statement, escape it by entering ;; instead of ;. For example, INSERT INTO punctuation(name, character) VALUES ('semicolon', ';;');.
So in your case,
Remove the "delimiter" property, and
Use ";;" instead of ";" for your inner SQL statements, so as to prevent the Play 2 parser from executing these inner SQL statements separately.
Here is an example that I have successfully tested in Play 2.3 and mysql 14.14 Distrib 5.5.40 (Ubuntu 12.04LTS):
DROP TRIGGER IF EXISTS SOFTWARE_INSERT_CT_TRIGGER;
CREATE TRIGGER SOFTWARE_INSERT_CT_TRIGGER
BEFORE INSERT ON SOFTWARE
FOR EACH ROW
BEGIN
IF NEW.CREATED_TIME = '0000-00-00 00:00:00' THEN
SET NEW.CREATED_TIME = NOW();;
END IF;;
END;
In the case of your SQL script, the following should work with Play 2.1 and above (Note that I have not tested it):
DROP TRIGGER IF EXISTS invoice_line_insert;
CREATE TRIGGER invoice_line_insert AFTER INSERT
ON invoice_line FOR EACH ROW
BEGIN
IF NEW.type = "DELIVERY" THEN
UPDATE invoice
SET invoice.etdelivery_amount = invoice.etdelivery_amount + NEW.amount
WHERE invoice.id_invoice = NEW.invoice_parent_id_invoice;;
ELSE
UPDATE invoice
SET invoice.etexpense_amount = invoice.etexpense_amount + NEW.amount
WHERE invoice.id_invoice = NEW.invoice_parent_id_invoice;;
END IF;;
UPDATE invoice
SET invoice.vatamount = (NEW.amount * ((
SELECT vat.rate
FROM vat
WHERE vat.id_vat = NEW.vat_id_vat
) / 100)) + invoice.vatamount
WHERE invoice.id_invoice = NEW.invoice_parent_id_invoice;;
UPDATE invoice
SET invoice.itamount = invoice.vatamount +
invoice.etdelivery_amount +
invoice.etexpense_amount
WHERE invoice.id_invoice = NEW.invoice_parent_id_invoice;;
END;
Related
I am trying to create a trigger to update the Project table whenever the Assign table is updated, yet I keep receiving this error: 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 'END IF
Does anyone have any idea of why I am getting this syntax error? Please note that I am a beginner at this so my SQL statements may be entirely wrong. Also, I know for sure that my query being ran in my IF statement works because I've ran it on its own without being inside a trigger.
delimiter $$
CREATE TRIGGER update_trigger AFTER UPDATE ON Assign
FOR EACH ROW
BEGIN
IF OLD.projNo <> new.projNo THEN
#RUN THIS QUERY TO UPDATE MY TABLE
UPDATE Project p JOIN
(SELECT Project.projNo, COUNT(DISTINCT empid) as numEmployeeAssigned
FROM (Project LEFT JOIN Assign ON Project.projNo=Assign.projNo)
GROUP BY projNo
) as tb
ON p.projNo = tb.projNo
SET p.numEmployeeAssigned = tb.numEmployeeAssigned
#END QUERY
END IF
END$$
delimiter;
You can just increment or decrement the count:
UPDATE Project p
SET p.numEmployeeAssigned = p.numEmployeeAssigned +
(case when p.projNo = new.ProjNo then 1 else -1 end)
WHERE p.projNo IN (old.ProjNo, new.ProjNo) AND
old.ProjNo <> new.ProjNo;
Obviously, your code is missing semi-colons after the UPDATE statement and after the END IF.
However, let me suggest that the UPDATE statement could most likely be simplified. As I understand your code, you want to update the count of employees in Project whenever an employee changes its assignment. If so, there is no need to actually query assign. You can just use conditional logic like this:
CREATE TRIGGER update_trigger AFTER UPDATE ON Assign
FOR EACH ROW
BEGIN
IF OLD.projNo <> new.projNo THEN
UPDATE Project p
SET numEmployeeAssigned = CASE
WHEN projNo = new.projNo THEN numEmployeeAssigned + 1
ELSE numEmployeeAssigned - 1
END
WHERE projNo IN (OLD.projNo, NEW.projNo);
END IF;
END$$
You could even remove the IF statement and put that condition in the query directly:
CREATE TRIGGER update_trigger AFTER UPDATE ON Assign
FOR EACH ROW
BEGIN
UPDATE Project p
SET numEmployeeAssigned = CASE
WHEN projNo = new.projNo THEN numEmployeeAssigned + 1
ELSE numEmployeeAssigned - 1
END
WHERE projNo IN (OLD.projNo, NEW.projNo) AND OLD.projNo <> NEW.projNo
END$$
I'm creating a MySQL trigger designed to update various tables with a new value if certain values are changed by an UPDATE query. I keep receiving the following syntax error for this particular trigger:
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 29
Line 29 in this case is the line of the END statement.
This is my full code:
DELIMITER $$
CREATE TRIGGER update_selling_prices BEFORE UPDATE ON t1
FOR EACH ROW
BEGIN
DECLARE update_price INT DEFAULT 0;
DECLARE selling_price_1 DECIMAL(10, 3) DEFAULT 0.000;
DECLARE selling_price_2 DECIMAL(10, 3) DEFAULT 0.000;
IF (OLD.rrp_price <> NEW.rrp_price OR OLD.discount_1 <> NEW.discount_1 OR OLD.discount_2 <> NEW.discount_2 OR OLD.net_price <> NEW.net_price OR OLD.markup <> NEW.markup OR OLD.delivery_cost <> NEW.delivery_cost) THEN
SET update_price = (SELECT b.is_auto_update FROM price_categories c INNER JOIN brands b ON b.brand_name = c.brand_name WHERE c.id = NEW.category_id LIMIT 1);
IF (update_price = 1) THEN
IF (NEW.is_bundle = 0) THEN
UPDATE t2 SET temp = 'Fired Single' WHERE id = NEW.id;
ELSE IF (NEW.is_bundle = 1) THEN
UPDATE t2 SET temp = 'Fired Bundle' WHERE id = NEW.id;
END IF;
END IF;
END IF;
END;
$$
DELIMITER ;
The current UPDATE statements are just placeholders for some actual calculations I'll end up doing.
Please note: I use Sequel Pro for most MySQL-related stuff and initially was using their GUI to try and add the trigger - it automatically adds the surrounding code so I would only create everything between the BEGIN and END statements. That also resulted in this same syntax error, so I don't believe it's related to the delimiters like some similar threads I've already found on here. Nevertheless, I've tried adding the full trigger code via a normal query; changing the delimiter syntax - for example END$$, END $$, END; $$ etc.
I've successfully created other triggers with similar syntax, but they do not include the DECLARE syntax.
Where am I going wrong?
The problem is here:
IF (NEW.is_bundle = 0) THEN
UPDATE t2 SET temp = 'Fired Single' WHERE id = NEW.id;
ELSE IF (NEW.is_bundle = 1) THEN
UPDATE t2 SET temp = 'Fired Bundle' WHERE id = NEW.id;
END IF;
Review documentation: https://dev.mysql.com/doc/refman/8.0/en/if.html
MySQL supports ELSEIF and this is different than ELSE IF. If you use ELSEIF, this continues the structure of the IF statement. If you use ELSE IF, it starts a new IF statement, so it should be like this:
IF (NEW.is_bundle = 0) THEN
UPDATE t2 SET temp = 'Fired Single' WHERE id = NEW.id;
ELSE
IF (NEW.is_bundle = 1) THEN
UPDATE t2 SET temp = 'Fired Bundle' WHERE id = NEW.id;
END IF;
END IF;
See that there is a complete IF/THEN/END IF statement within the ELSE block of the outer one?
But you didn't do that, so the END IF applies to the innermost IF statement, and then you're one level off for the rest of the body of the trigger.
When MySQL gets to the end of the whole CREATE TRIGGER statement, if there aren't enough ENDs to balance the blocks you began, MySQL complains with the error you saw.
So I have a table that holds a list of cuisines and a total of how many restaurants there are with that cuisine. (e.g. Italian | 7)
I'm trying to set-up a trigger in phpMyAdmin that will increment the total every time a new restaurant is added to the database. Here is what I have so far:
CREATE TRIGGER UpdateStats AFTER INSERT ON Restaurant
BEGIN
UPDATE RestaurantStats SET TotalRestaurants = TotalRestaurants + 1 WHERE Cusine = NEW.cusine;
END;
But I keep getting an error message and it's telling me that it has to do with my Syntax. Where am I going wrong? I followed the example I saw pretty well.
Here is the error message:
#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 'BEGIN UPDATE RestaurantStats SET TotalRestaurants = TotalRestaurants + 1 WHERE' at line 2
do you have to have for each row
CREATE TRIGGER UpdateStats
AFTER INSERT ON Restaurant
FOR EACH ROW
UPDATE RestaurantStats SET TotalRestaurants = TotalRestaurants + 1 WHERE Cusine = NEW.cusine;
You need to use FOR EACH ROW and get rid of the BEGIN...END like this:
CREATE TRIGGER UpdateStats AFTER INSERT ON Restaurant
FOR EACH ROW
UPDATE RestaurantStats SET TotalRestaurants = TotalRestaurants + 1 WHERE Cusine = NEW.cusine;
BEGIN...END is only used for multiple queries in the same trigger and requires redefinition of the termination character. So your first ; is terminating the statement and leaving the BEGIN open without an END.
try with "for each row":
CREATE TRIGGER UpdateStats AFTER INSERT ON Restaurant
FOR EACH ROW
BEGIN
UPDATE RestaurantStats SET TotalRestaurants = TotalRestaurants + 1 WHERE Cusine = NEW.cusine;
END;
Haven't tried it myself so not sure if it works...
I need to update oc_product_attribute with a value obtained from an inserted row in vehicles. How can I get this specific value? (xxxCOLUMN_VALUExxx)
CREATE TRIGGER vehicle_attributes AFTER INSERT ON vehicles
FOR EACH ROW
BEGIN
UPDATE oc_product_attribute SET oc_product_attribute.vehicle_name =
(SELECT CONCAT(vehicles.make_name, ' ', vehicles.model_name, ' ',
vehicles.chassis) FROM vehicles WHERE vehicles.id = xxxCOLUMN_VALUExxx)
WHERE oc_product_attribute.id = xxxCOLUMN_VALUExxx
END
Even simplified below: I still get an error in MYSQL:
CREATE TRIGGER vehicle_attributes AFTER INSERT ON vehicles
FOR EACH ROW
BEGIN
UPDATE oc_product_attribute
SET oc_product_attribute.vehicle_name =
CONCAT(NEW.make_name,' ',NEW.model_name,' ',NEW.chassis);
END;
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 7
And Simplified further:
CREATE TRIGGER vehicle_attributes AFTER INSERT ON vehicles
FOR EACH ROW
BEGIN
UPDATE oc_product_attribute
SET oc_product_attribute.vehicle_name = 'test' WHERE 1
END;
I still get the same error - Could it be MYSQL doesn't have triggers enabled?
I guess you need to update oc_product_attribute like this:
CREATE TRIGGER vehicle_attributes AFTER INSERT ON vehicles
FOR EACH ROW
BEGIN
UPDATE oc_product_attribute
SET oc_product_attribute.vehicle_name =
CONCAT(NEW.make_name,' ',NEW.model_name,' ',NEW.chassis)
WHERE oc_product_attribute.id = NEW.id;
END
Although I am no sure if oc_product_attribute.id is holding the vehicles.id. However, the important poart is that in an INSERT AFTER TRIGGER you can access the values of the inserted row by NEW.columnName.
N.B. In update triggers you also can access the value before the change with OLD.columnName
I am trying to Create a Trigger that will fire AFTER Insert of a Record where I will see if there is other records similar to this Inserted Record (Same Date) and if so will update a column in the inserted Record. Once I complete this one I will also update it for AFTER Update as well. Any Help would be Greatly Appreciated.
CREATE
TRIGGER `INSERT_POSTDATEINDEX` AFTER INSERT
ON `zoomloca_listings-dev`.`listings_posts`
FOR EACH ROW
BEGIN
DECLARE vNewPostDateIndex INT;
DECLARE vLastPostDateIndex INT DEFAULT '0';
SET vNewPostDateIndex = '0';
SET vLastPostDateIndex = (SELECT POSTDATEINDEX FROM listings_posts WHERE date(POST_DATE) = date(NEW.POST_DATE) ORDER BY POSTDATEINDEX DESC LIMIT 1);
IF vLastPostDateIndex = '0' THEN
SET vNewPostDateIndex = '0';
ELSE
SET vNewPostDateIndex = vLastPostDateIndex + 1;
END IF;
Update `listings_posts` SET POSTDATEINDEX = vNewPostDateIndex where ID = New.ID;
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 6
The problem is that there is no TOP in MySQL. You have to use LIMIT instead. Besides, if you are not using mysql client, then you should remove DELIMITER since it is not a feature of the MySQL. Another thing is that to demarcate the end of an IF statement in MySQL, you should use END IF instead of ENDIF.