Writing a trigger for AFER Update on DB2 - sql

I want to set the column EDI_INVOICE to False whenever the DOCUMENT_TYPE is a REBILL for only specific BILL_TO_CODES
This is how I wrote my trigger
CREATE TRIGGER BT_CU_CASS_REBILLS
AFTER UPDATE OF DOCUMENT_TYPE ON TLORDER
REFERENCING OLD AS O NEW AS N
FOR EACH ROW MODE DB2SQL
BEGIN ATOMIC
IF N.DOCUMENT_TYPE <> O.DOCUMENT_TYPE AND N.DOCUMENT_TYPE = 'REBILL'
AND N.BILL_TO_CODE IN (SELECT TRADING_PARTNER FROM EDI_PROFILES WHERE EDI_TYPE = '210' AND EDI_ACTIVE = 'True' AND UPPER(FTP_ADDRESS) LIKE '%CASS%')
THEN SET N.EDI_INVOICE = 'True';
END IF;
END
But when trying to execute the Query to create the trigger I get this Error
SQL0797N The Trigger Lynx.BT_CU_CASS_REBILLS is defined with an unsporrted triggered SQL statement. Line Number = 11. SQLSTATE = 42987
Thank you in advance.

If you want the trigger to change the data in the row for which the trigger is firing, ie.
THEN SET N.EDI_INVOICE = 'True';
you need to use a BEFORE UPDATE trigger.

Related

How to rewrite a trigger causing an update deadlock error

I have the following trigger. It is executed after an update statement from a REST API request. My issue is that when it is sent two API calls concurrently, the trigger is executed twice, therefore a deadlock error comes up because the transaction is not finished. Is there any SQL trickery I can try? Can I check in table B if it already has B_NEEDSRECALCULATION set to '+' and bypass the update, or maybe create a trigger on tableb?
CREATE OR ALTER TRIGGER TR_TESTTRIGGER_AU FOR TABLEA
ACTIVE AFTER UPDATE POSITION 0
AS
begin
if (rdb$get_context('USER_TRANSACTION', 'WISASCRIPT') = '1') then exit;
if ((new.A_FiledB IS NULL) and
(old.A_FieldA <> new.A_FieldB) )THEN
begin
UPDATE TableB
SET B_NEEDSRECALCULATION = '+'
WHERE (B_TESTID = new.A_TESTIDFK);
end
end

Trigger is not called on update table in oracle

I'm trying to make a trigger that updates the ID_ABONAMENT from the CONTRACTE table, when the ABONATI table is updated.
The problem is that the trigger is not called when I update a row in the ABONATI table.
Below is the trigger I made. Thank you in advance.
CREATE OR REPLACE TRIGGER UPDATE_CONTRACT_TRIGGER
AFTER UPDATE ON ABONATI
FOR EACH ROW
DECLARE
id_abonat number;
cod_abonament number;
BEGIN
id_abonat := :new.ID_ABONAT;
cod_abonament := :new.COD_ABONAMENT;
UPDATE CONTRACTE SET COD_ABONAMENT = cod_abonament WHERE ID_ABONAT = id_abonat;
END;
Thank you in advance.
You actually have a completely different problem - the trigger is being called but it's updating every row, each time it's updating a column to itself.
set COD_ABONAMENT = cod_abonament
WHERE ID_ABONAT = id_abonat;
These are going to be evaluated as referring to the columns in your table rather than the variables. So this is going to evaluate to true for every row which has an id_abonat value that isn't null and set the column to itself. You need to either use a different variable name or fully specify it in your update statement.
I would just forget about using a user defined variable here and just use :new.id_abonat in your update statement as is:
CREATE OR REPLACE TRIGGER UPDATE_CONTRACT_TRIGGER
AFTER UPDATE ON ABONATI
FOR EACH ROW
BEGIN
UPDATE CONTRACTE SET COD_ABONAMENT = :new.COD_ABONAMENT WHERE ID_ABONAT = :new.ID_ABONAT;
END;
/

Update column in another table with trigger

I would like to update a column in another table with the code below but I get a error that the trigger is invalid.
Whats wrong with it?
CREATE OR REPLACE TRIGGER UPDATE_PAYMENT
AFTER INSERT OR UPDATE ON PAYMENT
for each row
begin
update PAYMENTTYPE PT
set PT.PAYMENTTYPECOLUMN = PAYMENT.PAYMENTTYPECOLUMN
where PT.ID = :NEW.ID and PT.ID2 = :NEW.ID2;
end UPDATE_PAYMENT;
In your trigger you refer twice to PAYMENT columns by :NEW., and this is correct, while the third time you use PAYMENT., which is wrong.
The trigger should be:
CREATE OR REPLACE TRIGGER UPDATE_PAYMENT
AFTER INSERT OR UPDATE ON PAYMENT
for each row
begin
update PAYMENTTYPE PT
set PT.PAYMENTTYPECOLUMN = :NEW.PAYMENTTYPECOLUMN -- <------ HERE
where PT.ID = :NEW.ID and PT.ID2 = :NEW.ID2;
end UPDATE_PAYMENT;

SQL Transactions Error: Can't update table 'todo' in stored function/trigger because it is already used

Yii::app()->db->createCommand("DROP TRIGGER IF EXISTS update_todo;")->execute();
Yii::app()->db->createCommand("CREATE TRIGGER update_todo AFTER DELETE ON user_todo_send FOR EACH ROW BEGIN "
. " UPDATE todo SET status = 1 WHERE id = OLD.id_todo; END;")->execute();
In response, I receive an error :
Can't update table 'todo' in stored function/trigger because it is
already used by statement which invoked this stored function/trigger..
I am going to guess that you are really using MySQL. Use an after delete trigger. Using your syntax, that would look like this (and I assume you have the right delimiter statements:
DROP TRIGGER IF EXISTS `update_todo`;
CREATE TRIGGER `update_todo` AFTER DELETE ON `user_todo_send` FOR EACH ROW
BEGIN
UPDATE `todo`
SET status = 1
WHERE id IN (SELECT OLD.id_todo
FROM user_todo_send
WHERE OLD.id_todo = todo.id
);
END;
This is really simpler to write as:
DROP TRIGGER IF EXISTS `update_todo`;
CREATE TRIGGER `update_todo` AFTER DELETE ON `user_todo_send` FOR EACH ROW
BEGIN
UPDATE `todo`
SET status = 1
WHERE id = OLD.id_todo
END;
Or, forget triggers altogether and add a cascading delete foreign key reference.

Oracle 11g Trigger Issue

I'm a newbie to database and trying to create a trigger which will change a char from "Y" to "N" if another table's tuple is set to 0. I have it working somewhat but it is changing all tuples instead of the single one I want. Here is the trigger and code. Any suggestions gratefully received.
create or replace TRIGGER CHANGE_STOCK_FLAG
AFTER UPDATE OF AMOUNT_REMAINING ON PRODUCT
FOR EACH ROW
BEGIN
UPDATE BOOK
SET IN_STOCK = 'N';
END;
Update statement:
UPDATE PRODUCT
SET AMOUNT_REMAINING = 0
WHERE PROD_ID = 5001;
The trigger compiled OK and on update above resets IN_STOCK to "N" on all tuples in the Book TABLE.
Is there a where clause or something I can use?
Try this:
CREATE OR REPLACE TRIGGER CHANGE_STOCK_FLAG
AFTER UPDATE OF AMOUNT_REMAINING ON PRODUCT
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
BEGIN
IF (:NEW.AMOUNT_REMAINING=0) THEN
UPDATE BOOK SET IN_STOCK = 'N' WHERE PROD_ID=:NEW.PROD_ID;
END IF;
END;