MySql trigger not works - mysql

I have 3 tables
tbl_payments(pay_id,date,amount,description,-------)
tbl_pay_trans(pay_id,trans_id)
tbl_transactions(trans_id,trans_date,trans_amount,trans_description,-----)
'tbl_transaction' has the same data from the 'tbl_payments' along with some other values. To maintain the relationship between the two tables I use 'tbl_pay_trans'. What I want to do is, when an update done on tbl_payments(amount,description) the same changes need to do in tbl_transactions(trans_amount,trans_description). I wrote a trigger to do that, but it dose not update the tbl_transaction table values as it supposed to.
My trigger is
DELIMITER $$
CREATE TRIGGER update_trans
AFTER UPDATE on tbl_payments
FOR EACH ROW
BEGIN
DECLARE new_amount VARCHAR(50);
DECLARE new_description TEXT;
DECLARE new_pay_id,new_trans_id INT;
SET new_pay_id = OLD.pay_id;
SET new_amount = OLD.amount;
SET new_description = OLD.description;
SELECT trans_id INTO new_trans_id FROM tbl_pay_trans WHERE pay_id = new_pay_id;
UPDATE tbl_transactions SET
trans_amount = new_amount,
trans_description = new_description
WHERE trans_id = new_trans_id;
END$$
DELIMITER ;
Please someone help me to figure out what I did wrong.

It's not updating because you are using OLD on the amount and description columns where you need to use NEW i.e.
SET new_amount = NEW.amount;
SET new_description = NEW.description;
OLD refers to the column value before the update occurred in tbl_payments. See the manual.

Related

Need Guidance with writing MySQL Trigger

I'll admit, up front, that this is my first MySQL trigger. The MySQL version is 8.0.
I have a table for orders and order line items. In the orders table I have a column that stores the total of all line items. I need a trigger that updates that total every time a line items is added or changed for that order. Here's what I have so far:
CREATE TRIGGER update_line_item_total
AFTER INSERT
ON orderlines.price FOR EACH ROW
BEGIN
-- variable declarations
DECLARE li_order_id INT;
DECLARE li_total DEC;
SET li_order_id = orderlines.order_id;
SET li_total = SUM (orderlines.price) WHERE orderlines.order_id = li_order_id;
-- trigger code
UPDATE orders SET
total_lineitems = li_total
WHERE orders.order_id = li_order_id;
END;
I put this into MySQL Workbench and it was rejected. I know that the DECLARE statements, the 2nd SET statement, and the END statements were the ones flagged as incorrect, however I'm not even sure where to look to find out what's wrong.
Looking for guidance and direction.
Thanks,
Michael Frankel
Wizard Consulting Group, Inc.
your problem is on this line : SET li_total = SUM (orderlines.price) WHERE orderlines.order_id = li_order_id;
add delimiters.
do this :
delimiter |
CREATE TRIGGER update_line_item_total
AFTER INSERT
ON orderlines.price FOR EACH ROW
BEGIN
-- variable declarations
DECLARE li_order_id INT;
DECLARE li_total DEC;
declare li_total_temp dec;
SET li_order_id = orderlines.order_id;
select orderlines.price into li_total_temp WHERE orderlines.order_id = li_order_id;
SET li_total = li_total + li_total_temp;
-- trigger code
UPDATE orders SET
total_lineitems = li_total
WHERE orders.order_id = li_order_id;
END |
delimiter ;

MySQL Trigger updates all rows even if a distinct where clause is given

Refer to the following trigger,
create trigger trigger_update_rows after insert on transaction for each row
DECLARE tr_type VARCHAR(15);
DECLARE tr_op VARCHAR(10);
DECLARE tr_amt FLOAT(8,2);
DECLARE tr_qnt INTEGER;
DECLARE item_id INTEGER;
SET tr_type = NEW.TRANSACTION_TYPE;
SET tr_op = (SELECT TRANSACTION_TYPE_OPERATION FROM transaction_type WHERE
TRANSACTION_TYPE_NAME=tr_type limit 1);
SET tr_amt = NEW.TRANSACTION_AMOUNT;
SET tr_qnt = NEW.QUANTITY;
SET item_id = NEW.ITEM_ID;
IF tr_op = 'ADD' THEN
update item set QUANTITY_AVAILABLE=QUANTITY_AVAILABLE-
tr_qnt,QUANTITY_SOLD=QUANTITY_SOLD+tr_qnt,AVAILABLE_GOODS_VALUE =
AVAILABLE_GOODS_VALUE - tr_amt,SOLD_GOODS_VALUE=SOLD_GOODS_VALUE+tr_amt
where ITEM_ID=item_id;
ELSEIF tr_op = 'SUBTRACT' THEN
update item set QUANTITY_AVAILABLE=QUANTITY_AVAILABLE+tr_qnt,QUANTITY_BOUGHT=QUANTITY_BOUGHT+tr_qnt,AVAILABLE_GOODS_VALUE=AVAILABLE_GOODS_VALUE+tr_amt,BOUGHT_GOODS_VALUE=BOUGHT_GOODS_VALUE+tr_amt where ITEM_ID=item_id;
END IF;
END
ITEM_ID is a primary key in the table item and the following is the transaction row inserted
insert into transaction(TRANSACTION_DATE,TRANSACTION_TYPE,ITEM_ID,QUANTITY,TRANSACTION_AMOUNT,ACCOUNT_ID,BUYER,SELLER) values ('2017-08-12','BUY',2,5,500.00,3,1,2);
What is making the above trigger update all rows in item instead following the where clause
You problem is:
where ITEM_ID = item_id;
You may think that one of the item_ids is somehow connected to the variable. It is not.
Rename the variable to something like v_item_id and then use:
where item_id = v_item_id

sql server UPDATE TRIGGER doesn't fire

i have a trigger like below, the logic is to change FID status after fidRule status changed.
in my app, i update 1 row in each statement,
but i found sometimes(very rare) the trigger not firing.
ALTER TRIGGER [dbo].[triggerSetFIDStatus]
ON [dbo].[FIDRules]
AFTER UPDATE
AS
BEGIN
set nocount on
DECLARE #ruleStatus INT
DECLARE #newRuleStatus INT
DECLARE #FIDAlertStatus INT
DECLARE #FIDId INT
DECLARE #isFIDEnabled int
DECLARE #ruleId INT
SELECT #ruleStatus = deleted.alertStatus,
#FIDId = deleted.FIDID,
#ruleId = deleted.id
from
deleted
SELECT #newRuleStatus = inserted.alertStatus
from
inserted
SELECT #FIDAlertStatus = alertStatus,
#isFIDEnabled= isEnabled
FROM FID
WHERE id = #FIDId
IF #FIDAlertStatus <> #newRuleStatus
BEGIN
-- change FID-status by FIDRule-status
UPDATE [dbo].[FID] SET alertStatus=#newRuleStatus WHERE id=#FIDId
END
IF #newRuleStatus >= 0 AND #newRuleStatus <> #ruleStatus
UPDATE [dbo].[FIDRules] SET isAlertStatChanged=1, AlertStatChangeTime = SYSUTCDATETIME() WHERE id=#ruleId
END
The trigger will not be fired if the UPDATE statement fails or another triggers fails to execute before this trigger is fired.
One comment about your trigger itself:
You are expecting one records from DELETED which is not always correct.
Please make your trigger robust enough in case DELETED contains multiple records
-- What if deleted contains multiple records?
SELECT #ruleStatus = deleted.alertStatus,
#FIDId = deleted.FIDID,
#ruleId = deleted.id
FROM
deleted
You can either use SELECT TOP(1) or make sure your trigger is able to handle multiple records from the DELETED list.

Assigning the value from a select statement to a vairable in MySQL

I'm fairly new to SQL in general and even more so to MySQL and I've hit a stumbling block. I'm attempting to use a procedure to copy the value of one field to another if the original field is not null, this procedure is then called by triggers whenever the table is updated or has a new row inserted into it. Here is what I have so far:
-- WORK_NOTES_PROCEDURE - This copies the contents of the estimate notes to the work order notes if the original estimate had any notes with it.
DROP PROCEDURE IF EXISTS 'WORK_NOTES_PROCEDURE';
DELIMITER $$
CREATE PROCEDURE WORK_NOTES_PROCEDURE()
BEGIN
DECLARE var_temp VARCHAR(50);
SET var_temp := (SELECT ESTIMATE_NOTES FROM ESTIMATES WHERE ESTIMATES.ESTIMATE_NUMBER = WORK_ORDERS.ESTIMATE_NUMBER);
IF var_temp IS NOT NULL THEN
UPDATE WORK_ORDERS SET WORK_ORDER_NOTES = var_temp WHERE WORK_ORDERS.ESTIMATE NUMBER = ESTIMATES.ESTIMATE_NUMBER;
END IF;
END$$
DELIMITER ;
Absolutely any help would be appreciated, the error I'm getting is a syntax error for the line where I'm assigning a value to var_temp.
try,
SET var_temp = (SELECT ESTIMATE_NOTES
FROM ESTIMATES INNER JOIN WORK_ORDERS
ON ESTIMATES.ESTIMATE_NUMBER = WORK_ORDERS.ESTIMATE_NUMBER
LIMIT 1);

sql server trigger for custom PK

I want to generate PK through trigger as it is custom PK.
It is like depending on the member type field, I want to generate member id which is PK.
e.g. if new record's member type is DGIA, then member id will be DGIA1, DGIA2, DGIA3 ...and so on... if member type is DGIL, then member id will be DGIL1, DGIL2, DGIL3 ...and so on...
So, how to write trigger for the same... I have tried as following but it is working for 1st record only.
ALTER TRIGGER [dbo].[next_member_id] ON [dbo].[DAD_MEMBERSHIP] AFTER INSERT
AS
BEGIN
DECLARE #COUNT INT
SET #COUNT=0;
SELECT #COUNT=ISNULL(MAX(CAST(SUBSTRING(DAD_MEMBERSHIP.MEMBER_ID,5,15) AS INT)),0)+1 FROM DAD_MEMBERSHIP where DAD_MEMBERSHIP.MEMBER_TYPE = DAD_MEMBERSHIP.MEMBER_TYPE
update DAD_MEMBERSHIP set DAD_MEMBERSHIP.MEMBER_ID = DAD_MEMBERSHIP.MEMBER_TYPE + CONVERT(varchar,#COUNT)
from DAD_MEMBERSHIP inner join inserted on DAD_MEMBERSHIP.MEMBER_TYPE = inserted.MEMBER_TYPE
END
Triggers operate by batch of records, you cannot assign to a scalar variable and expect it to work for more than one record. You need to rethink your whole process into a set-based process.
I solved the problem using following trigger
ALTER TRIGGER [dbo].[next_member_id]
ON [dbo].[DAD_MEMBERSHIP]
AFTER INSERT
AS
BEGIN
DECLARE #COUNT INT
SET #COUNT=0;
DECLARE #STR VARCHAR(5)
SET #STR=''
select #STR=i.MEMBER_TYPE from inserted i;
SELECT #COUNT=ISNULL(MAX(CAST(SUBSTRING(DAD_MEMBERSHIP.MEMBER_ID,5,15) AS INT)),0)+1
from DAD_MEMBERSHIP where MEMBER_TYPE=#STR
update DAD_MEMBERSHIP set DAD_MEMBERSHIP.MEMBER_ID = #STR + CONVERT(varchar,#COUNT)
from DAD_MEMBERSHIP inner join inserted i on i.MEMBER_TYPE=DAD_MEMBERSHIP.MEMBER_TYPE where DAD_MEMBERSHIP.MEMBER_ID is null
END