MYSQL Invalid use of group function How to resolve? - mysql

After creating trigger It started to displaying the Invalid use of group function error on update query.
Trigger:
CREATE TRIGGER header_true BEFORE UPDATE
ON category
FOR EACH row
begin
IF new.Header = 'True' THEN
SET new.H_order = max(old.H_order) + 1;
end IF;
end
Update Query:
UPDATE `category` SET `Header` = 'True' WHERE `category`.`ID` = 23
Anyone can please help me How can I resolve this issue?

You can try this solution for your problem :
MAX function is used to return the maximum value of an expression in a SELECT statement. MAX function is not possible without SELECT statement.
CREATE TRIGGER header_true BEFORE UPDATE
ON category
FOR EACH row
begin
IF new.Header = 'True' THEN
SET new.H_order = (select max(H_order) + 1 from category) + 1;
end IF;
end
I hope it will help.

Related

Trying to resolve a syntax error for MYSQL update trigger

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$$

MySQL Create Trigger Syntax Error (Last Line)

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.

Problem with comparison within a trigger statement using a variable gotten from query

I am trying to use an attribute from a 2nd table in the trigger of the 1st. To do this I am trying to load that value into a variable and then use it as a comparison.
However whenever I try and test the process the comparison answers false.
DELIMITER $$
create trigger evolve_persona before update on phantom_thieves
for each row begin
set #t := (select tier from persona where pname = old.persona);
if((new.persona != old.persona) and (select cast(#t as unsigned) = '1')) then
set
new.st = old.st+10, new.ma = old.ma+10, new.en= old.en+10, new.ag= old.ag+10,
new.lu= old.lu+20;
end if;
end$$
DELIMITER ;
I can see nothing wrong with your trigger but, this is somewhat more complicated as be written in a comment.
Make please following
SET #t = -1;
SELECT #t; -- returns -1
update phantom_thieves SET .....
SELECT #t; -should display at sometime 1
This seems to be the only problem that tier don't has the response 1 and with above, you can see what you get.

MySQL - Update Column Value with Function and Trigger Before Insert

i'm trying to update 2 column with trigger before insert, but i have unexpected result. i insert some data and the 2 last column will automatically inserted with values, here my first attempt
see? the last 2 column is null even i set some trigger and function to fill that columns automatically. Here my second attempt WITH EXACTLY SAME DATA
the last 2 column is filled with data, but i don't understand why the first attempt is fail?
here my trigger i use in the column total_harga
CREATE TRIGGER `set_total_harga` BEFORE INSERT ON `tbl_transaksi_detail`
FOR EACH ROW BEGIN
set NEW.total_harga = hitungTotalHargaPerItem(NEW.qty, NEW.harga_satuan);
END
trigger for column harga_satuan
CREATE TRIGGER `set_harga_satuan` BEFORE INSERT ON `tbl_transaksi_detail`
FOR EACH ROW BEGIN
set NEW.harga_satuan = set_Harga_Unit(NEW.unit, NEW.id_barang, NEW.no_transaksi);
END
function set_Harga_Unit
BEGIN
DECLARE
q,
id_toko INT;
SET
id_toko =(
SELECT DISTINCT
`tbl_transaksi`.`id_toko`
FROM
`tbl_transaksi`,
`tbl_transaksi_detail`
WHERE
`tbl_transaksi`.`no_transaksi` = no_trans
); IF unit = "PCS" THEN
SET
q =(
SELECT
`tbl_harga_jual`.`harga_pcs`
FROM
`tbl_harga_jual`
WHERE
`tbl_harga_jual`.`id_barang` = id_brg AND `tbl_harga_jual`.`id_toko` = id_toko
); RETURN q; ELSEIF unit = "PAK" THEN
SET
q =(
SELECT
`tbl_harga_jual`.`harga_pak`
FROM
`tbl_harga_jual`
WHERE
`tbl_harga_jual`.`id_barang` = id_brg AND `tbl_harga_jual`.`id_toko` = id_toko
); RETURN q; ELSEIF unit = "KARTON" THEN
SET
q =(
SELECT
`tbl_harga_jual`.`harga_karton`
FROM
`tbl_harga_jual`
WHERE
`tbl_harga_jual`.`id_barang` = id_brg AND `tbl_harga_jual`.`id_toko` = id_toko
); RETURN q;
END IF; RETURN q;
END
function hitungTotalHargaPerItem
BEGIN
DECLARE hasil int;
set hasil = qty * harga_satuan;
RETURN hasil;
END
The root cause serms to be the select that sets id_toko variable's value:
SET
id_toko =(
SELECT DISTINCT
`tbl_transaksi`.`id_toko`
FROM
`tbl_transaksi`,
`tbl_transaksi_detail`
WHERE
`tbl_transaksi`.`no_transaksi` = no_trans
);
In the select you inner join tbl_transaksi_detail (the table with the trigger in question) on another table. However, in the 1st case tbl_transaksi_detail is still empty (the trigger is before insert), therefore id_toko variable is set to null.
This will result q being null, which in turn results in the entire calculation set to null.
In the 2nd case there is already a record inserted into tbl_transaksi_detail table, therefore the calculation returns a non null value. But it returns the correct values only because the 1st and 2nd records' details are exactly the same.
I do not really understand that select that calculates id_toko anyway. If that is a transaction id, then you may use last_insert_id() if it is auto increment and the transaction record has just been created or max(id_toko) to get the highest value of id_toko (this is not multi user safe).
it seem i have mistaken select query in function set_Harga_Unit, based on clues from #Shadow
SET
id_toko =(
SELECT DISTINCT
`tbl_transaksi`.`id_toko`
FROM
`tbl_transaksi`,
`tbl_transaksi_detail`<<== I DON'T NEED THIS
WHERE
`tbl_transaksi`.`no_transaksi` = no_trans
); IF unit = "PCS" THEN
when first insert in tbl_transaksi_detail, the value no_transaksi is null because i use trigger before insert in empty table (tbl_transaksi_detail), so i remove tbl_transaksi_detail from query
SET
id_toko =(
SELECT DISTINCT
`tbl_transaksi`.`id_toko`
FROM
`tbl_transaksi`
WHERE
`tbl_transaksi`.`no_transaksi` = no_trans
); IF unit = "PCS" THEN
now it working, thanks everybody!

stored procedure syntax in mysql

I am new to writing stored Procedures and I can't seem to find the error in this procedure.
The error is marked near the where part.
I tried looking for an example where the set is done based on a if condition but I can't seem to find such an example. Can anyone point me to my error?
DELIMITER $$
CREATE PROCEDURE `incubation`.`bt_voice_modification`
(in input_slot varchar(45),in input_port varchar(45))
BEGIN
SET #SVLAN_STH:=1000;
SET #SVLAN_DTH:=999;
SET #CVLAN_DTH:=1000;
SET #FLOW_INSTANCE:=1;
UPDATE one_2_one_table
SET L2S_USER_FLOW_INSTANCE = #FLOW_INSTANCE := #FLOW_INSTANCE+1;
SET L2S_NW_SLOT = input_slot;
SET L2S_NW_PORT = input_port;
IF STH_DTH = 'STH' then
set L2S_NW_SVLAN = #SVLAN_STH :=#SVLAN_STH + 1;
ELSE
set L2S_NW_SVLAN = #SVLAN_DTH ;
set L2S_NW_CVLAN = #CVLAN_DTH :=#CVLAN_DTH + 1;
END if;
WHERE IPDSLAM_USER_SLOT = 2 AND L2S_USER_TYPE like "%gplt%";
END
Your code suggest you don't have a very clear picture of how UPDATE statement works or the exact syntax. When you put a ;, it marks the end of the (UPDATE) statement. The syntax is - for one table:
UPDATE tableX
SET columnA = what_value_should_columnA-get ,
columnB = what_value_should_columnB_get ,
...
columnX = what_value_should_columnX_get
WHERE (conditions that restrict the rows that will be affected)
ORDER BY SomeColumn ; --- this can be used in MySQL only. Standard SQL
--- (and most DBMS) do not allow ORDER BY clause in
--- UPDATE statements. Since you are using variables
--- and the order of updating affects the updated values,
--- it's essential that you include an ordering.
So, your UPDATE would be something like:
UPDATE one_2_one_table
SET L2S_USER_FLOW_INSTANCE = #FLOW_INSTANCE := #FLOW_INSTANCE+1 ,
L2S_NW_SLOT = input_slot,
L2S_NW_PORT = input_port,
L2S_NW_SVLAN = CASE WHEN STH_DTH = 'STH'
THEN #SVLAN_STH := #SVLAN_STH + 1
ELSE #SVLAN_DTH
END ,
L2S_NW_CVLAN = CASE WHEN STH_DTH = 'STH'
THEN L2S_NW_CVLAN
ELSE #CVLAN_DTH := #CVLAN_DTH + 1
END
WHERE IPDSLAM_USER_SLOT = 2
AND L2S_USER_TYPE like '%gplt%'
ORDER BY SomeColumn ;