I am looking to set up a trigger that will do some addition(the code below) on two columns if stage_1 or stage_2 is update.
Also is it possible to run the trigger ever 5 min instead of on every update. Thanks In advance for any help.
update monte_carlo_2013 set total = stage_1 + stage_2
I have had a look around the net at trigger and come up with this, which dose not work but am i going in the right direction
CREATE TRIGGER update_stage_1
ON monte_carlo_2013
AFTER INSERT
AS
BEGIN
update monte_carlo_2013 set total_after_1 = (stage_1 + penalty_after_1) WHERE car_num IN (SELECT car_num FROM INSERTED)
END$$
A trigger is not a cronjob, you can also make something like :
CREATE TRIGGER my_first_trigger BEFORE INSERT employees
FOR EACH ROW
BEGIN
IF NEW.id_employee = 55 THEN
INSERT INTO special_employees VALUES (NEW.id_employee, NEW.name);
END IF;
END $$
You juste have to adapt this phpmyadmin-mysql query.
Note : I said phpmyadmin-mysql query because actually "END $$" is used only with phpmyadmin. Normally, we use a system of delimiter.
Related
I want to create an update trigger for a table. The trigger was created, but when I update the column finish, it say mutating table.
This is my code
CREATE OR REPLACE TRIGGER SET_COST BEFORE UPDATE OF finish ON PAY
FOR EACH ROW
BEGIN
UPDATE PAY
SET PAY.COST = (finish-start) * 20000
WHERE PAY.ID=:new.ID;
END;
This trigger gives me 'Mutating Table' error and so far I have been unable to fix it. Any Suggestion ? Thanks
First of all, you shouldn't be doing that at all. There's no use in storing values that are easily calculated whenever you need them.
As of your question: no UPDATE:
begin
:new.cost := (:new.finish - :new.start) * 20000;
end;
I am having an issue with a trigger. After I add the trigger to my database, when I try to insert a row that the trigger will act on, I get a mutating table error. I don't know how to avoid this. Would someone mind looking at this and tell me what I am doing wrong, and how to rewrite it?
CREATE OR REPLACE TRIGGER ORNG_INV_LINE_TOTAL_TRIGGER
FOR INSERT OR UPDATE ON ORNG_INV_LINE
COMPOUND TRIGGER
AFTER EACH ROW IS
BEGIN
UPDATE ORNG_INVOICE SET Inv_Amount = (SELECT SUM(ORNG_INV_LINE.Inv_Line_Total)
FROM ORNG_INV_LINE
WHERE ORNG_INVOICE.INV_Num = :NEW.INV_Num);
END AFTER EACH ROW;
END ORNG_INV_LINE_TOTAL_TRIGGER;
/
I'm not sure why it is triggering an error. I'm trying to do the action after the update. All I want to do is get the sum for all of the lines of all matching invoice numbers, and write that value in the INVOICE table. Thanks for the help.
Your trigger is written on the table ORNG_INV_LINE for insert or update and again you made a select on the same table while updating ORNG_INVOICE table so trigger is mutating,
to over come this you have to use statement level trigger instead of row level trigger .
i.e after each statement should be there in code instead of after each row.
This can help you.
Here is the solution...apparently everyone is busy with Thanksgiving. Hopefully this helps the next guy.
create or replace TRIGGER ORNG_INV_L_TTL_TRIG
AFTER INSERT OR UPDATE OR DELETE ON ORNG_INV_LINE
BEGIN
UPDATE ORNG_INVOICE SET Inv_Amount = (SELECT SUM(Inv_Line_Total)
FROM ORNG_INV_LINE
WHERE INV_Num = ORNG_INVOICE.INV_Num);
END ORNG_INV_L_TTL_TRIG;
/
CREATE OR REPLACE TRIGGER Net_winnings_trigger
AFTER UPDATE OF total_winnings ON Players
FOR EACH ROW
DECLARE
OldTuple OLD
NewTuple NEW
BEGIN
IF(OldTuple.total_winnings > NewTuple.total_winnings)
THEN
UPDATE Players
SET total_winnings = OldTuple.total_winnings
WHERE player_no = NewTuple.player_no;
END IF;
END;
/
I am trying to get a trigger that will only allow the 'total_winnings' field to be updated to a value greater than the current value.
If an update to a smaller value occurs, the trigger should just leave the set the value to the old value (as if the update never occured)
Since you want to override the value that is specified in the UPDATE statement, you'd need to use a BEFORE UPDATE trigger. Something like this
CREATE OR REPLACE TRIGGER Net_winnings_trigger
BEFORE UPDATE OF total_winnings ON Players
FOR EACH ROW
BEGIN
IF(:old.total_winnings > :new.total_winnings)
THEN
:new.total_winnings := :old.total_winnings;
END IF;
END;
But overriding the value specified in an UPDATE statement is a dangerous game. If this is something that shouldn't happen, you really ought to raise an error so that the application can be made aware that there was a problem. Otherwise, you're creating all sorts of potential for the application to make incorrect decisions down the line.
Something like this should work.. although it will be hiding the fact that an update is not taking place if you try to update to a smaller value. To the user, everything will look like it worked but the data will remain unchanged.
CREATE OR REPLACE TRIGGER Net_winnings_trigger
BEFORE UPDATE OF total_winnings
ON Players
FOR EACH ROW
DECLARE
BEGIN
:new.total_winnings := greatest(:old.total_winnings,:new.total_winnings);
END;
I want to write a trigger for a table "TRANSACTION".When a new line is inserted, I want to trigger to update the field "TRANSACTIONID" to the maximum + 1 of all the previous records.
I on't know much about SQL. Can someone help me?
many thanks
This is a really bad idea for a multi-user environment, as it will serialise inserts into the table. The usual approach is to use an Oracle sequence:
create sequence transaction_seq;
create trigger transaction_bir before insert on transaction
for each row
begin
:new.id := transaction_seq.nextval;
end;
To write a trigger based solution that actually got the max current value plus 1, you would need to write a complex 3-trigger solution to avoid the "mutating table" issue. Or you could create a simpler solution using another table to hold the current maximum value like this:
create table transaction_max (current_max_id number);
insert into transaction_max values (0);
create trigger transaction_bir before insert on transaction
for each row
declare
l_current_max_id number;
begin
update transaction_max set current_max_id = current_max_id + 1
returning current_max_id into l_current_max_id;
:new.id := l_current_max_id;
end;
This will avoid the mutating table issue and will serialize (slow down) inserts, so I don't see any advantage of this over using a sequence.
CREATE TRIGGER trigger1 on TransactionTable
INSTEAD OF INSERT
AS
BEGIN
DECLARE #MaxTranId INT
SELECT
#MaxTranId = MAX(TransactionId)
FROM
TransactionTable
INSERT INTO TransactionTable
SELECT
#MaxTranId + 1 ,
RestOfYourInsertedColumnsHere ,
FROM
inserted
END
GO
Trying to create an Oracle trigger that runs after a table is updated in any way. I've been googling this all morning and came up with this:
CREATE OR REPLACE TRIGGER gb_qty_change
AFTER UPDATE OR INSERT OR DELETE ON F_ITEM_STORE
FOR EACH ROW
DECLARE
v_qty V_AD_ON_HAND%rowtype;
v_isbn TD_ITEM_DESCRIPTION.TD_IDENTIFIER%type;
BEGIN
delete from gb_transaction where gb_tide = :new.ITST_ITEM_TIDE_CODE;
select TD_IDENTIFIER INTO v_isbn from TD_ITEM_DESCRIPTION where TD_TIDE = :new.ITST_ITEM_TIDE_CODE;
select * INTO v_qty from V_AD_ON_HAND where ITST_ITEM_TIDE_CODE = :new.ITST_ITEM_TIDE_CODE;
insert into gb_transaction(gb_tide, gb_isbn, gb_used_on_hand, gb_new_on_hand)
values(:new.ITST_ITEM_TIDE_CODE, v_isbn, v_qty.USED_ON_HAND, v_qty.NEW_ON_HAND);
END;
/
I'm trying to keep it to a single record per TIDE_CODE in the new table.
V_AD_ON_HAND is a view that pulls an inventory count.
gb_transaction is my new table where I'm logging these events
Comparing it to other peoples code it looks like it should run but I'm getting "Warning: Trigger created with compilation errors."
The problem, I believe is with the :new designations for a delete trigger. There is, after all, no NEW value as the record is expunged. You can only access the :OLD values on delete.
if you section the trigger by operation, you can do this.
CREATE OR REPLACE TRIGGER gb_qty_change
AFTER UPDATE OR INSERT OR DELETE ON F_ITEM_STORE
FOR EACH ROW
DECLARE
v_qty V_AD_ON_HAND%rowtype;
v_isbn TD_ITEM_DESCRIPTION.TD_IDENTIFIER%type;
BEGIN
IF INSERTING or UPDATING then
... insert your existing code
ELSE
... do something similar with the :old values for the deleting case
end if;
END;
/
Incidentally, it is generally helpfull if you tell us WHAT the error is, not just that you had one. If compiling via SQL*Plus script, after the forward slash call to compile the trigger after the "end;" statement, add a line that says:
SHOW ERRORS TRIGGER YOUR_TRIGGER_NAME;