SQL trigger error - invalid trigger - sql

I'm using pl\sql developer and I have a report table with a number(38) ID column.
I want to keep track of all updates for this table so I created another table like this:
CREATE TABLE reportUpdate (report_id number(38), updatedate number(32));
And I created a trigger:
CREATE or REPLACE TRIGGER BeforeUpdateReport
BEFORE
UPDATE ON REPORT
FOR EACH ROW
Begin
INSERT INTO reportUpdate
Values(old.ID,sysdate);
END;
And when I run it, I get an error, saying: trigger 'SYSTEM.BEFOREUPDATEREPORT' is invalidand failed re-validation.
Can someone please help

You can use show errors after you see compiled with warnings, or query the user_errors view to see what is wrong later.
One obvious thing is that you haven't prefixed the old reference with a colon:
CREATE or REPLACE TRIGGER BeforeUpdateReport
BEFORE
UPDATE ON REPORT
FOR EACH ROW
Begin
INSERT INTO reportUpdate
Values(:old.ID,sysdate);
END;
/
It's also better to specify the target table fields in the insert statement:
INSERT INTO reportUpdate (report_id, updatedate)
Values(:old.ID,sysdate);
But you have update_date defined in your table creation script as number(32), which doesn't make sense. As #realspirituals pointed out, it should be:
CREATE TABLE reportUpdate (report_id number, updatedate date);

Related

Oracle PL/SQL - BEFORE INSERT 'table does not exist' error?

I'm taking my first steps in Pl/SQL and am struggling with triggers. I've tried creating the trigger below but am receiving this error:
Error at line 2: PL/SQL: SQL Statement ignored
PL/SQL: ORA-00942: table or view does not exist
To clarify: I have checked the name of the table over and over, and it does exist. It is also in the same schema as the trigger I'm trying to create. The 'customer_seq.NEXTVAL' refers to a sequence created previously that runs without errors.
The code is as follows:
CREATE TRIGGER new_customer
BEFORE INSERT ON customer
FOR EACH ROW
BEGIN
INSERT INTO customer_id VALUES ('c-', customer_seq.NEXTVAL);
END;
Thanks in advance for any help.
You probably intend something like this:
CREATE TRIGGER new_customer
BEFORE INSERT ON customer
FOR EACH ROW
BEGIN
SELECT customer_seq.NEXTVAL INTO :NEW.customer_id
FROM dual;
END;
It is unclear what the purpose of 'C_' is. If it is part of the customer id, I would advise you to stick to numbers.
Also note that more recent versions of Oracle support generated always as identity -- which is much preferred over defining a sequence and trigger.

trigger to update specific column when insert/update happened in same table

I trying to write a trigger that will update a column when user insert or updates a row, within the same table.
Example:
insert into user(ID, F_NM, L_NM, EMAIL) values ('1', 'John','Doe','john.doe#market.org.com');
after the insert, i want to call: update user set ORG = 'market' where ID = '1'.
create or replace trigger user_change
after insert or update of EMAIL on USER
for each row
declare
NEW_ORG VARCHAR(10);
BEGIN
CASE
when :NEW.EMAIL like '$#market.org.com' then
NEW_ORG := 'market';
........
END CASE;
UPDATE USER set ORG = NEW_ORG where ID = :NEW.ID
END;
Calculating the new ORG work, but I can't get the update statement to work.
I get 'ORA-04091 table USER is mutating, trigger/funtion may not see it', figure its due to me inserting/updating the same record at same time. Tried adding 'pragma autonomous_transaction' and 'commit' to the trigger, the insert/update of fields works but the ORG does not get updated.
Also tried changing to INSTEAD OF INSERT OR UPDATE OF EMAIL but I keep getting 'ORA-04073 column list not valid for this trigger type'
create or replace trigger user_change
instead of insert or update of EMAIL on USER
while i get 'ORA-25002 cannot create instead of triggers on tables'
create or replace trigger user_change
instead of insert on USER
Why not simply turn the trigger to a before trigger, when you can set the value before it is written? This way, you don't need to run a new DML statement on the table, which avoid the "mutating" error.
create or replace trigger user_change
after insert or update of email on user
for each row
begin
if :new.email like '%#market.org.com' then
:new.org := 'market';
end if;
end;
Looks like your org column can be calculated virtual column. In this case it would be better to create user-defined deterministic pl/sql function that returns correct calculated value and add it to your table, for example:
Alter table t add org varchar2(30) generated always as (f_get_org(email))

How to update the same table in SAP HANA Triggers

I am trying to write a trigger in SAP HANA to update a field of a table when new records are being inserted to that table. Following is a sample trigger that I have written.
CREATE TRIGGER SAMPLE
AFTER INSERT ON TARGET_TABLE
REFERENCING NEW ROW NEW_ROW
FOR EACH ROW
BEGIN
UPDATE TARGET_TABLE SET VALID_FROM='2018-02-01' WHERE ITEM=:NEW_ROW.ITEM
END
When I try this, I get the error:
Modification of subject table in trigger not allowed
Is there a way by which I can achieve this?
This suggests to use the transition variable NEW_ROW, appreciate if a code sample can be provided.
You don't actually need to create trigger for your requirement as I can see from your post (of course if it is only updating a date field)
You can define the VALID_FROM column with a DEFAULT value
For example,
Create Column Table DefaultColumnTable (
Id int,
Code varchar(5),
VALID_FROM date default '2018-02-01'
)
So whenever a new row is inserted, unless an alternative value is stated the valid_from column will be populated with default date specified in the DDL command above.
The users can change the valid_from field value without any problem
#Kalpa, maybe you can use BEFORE INSERT Trigger
Please check following sample
create trigger TriggerTable_B_INS BEFORE INSERT on TriggerTable
REFERENCING NEW ROW mynewrow
FOR EACH ROW
begin
declare lv_d date;
lv_d := '20180201';
mynewrow.VALID_FROM = :lv_d;
end;
You set only the new row columns before Insert command executes over the target table.
You don't explicitly execute an INSERT command, just set new values for new row columns. That's all
I hope it helps

Why does my SQL trigger statement not appear in DBMS_OUTPUT?

I'm trying to get my head around triggers, but I'm getting errors
Error(2,4): PL/SQL: SQL Statement ignored
Error(2,8): PL/SQL: ORA-00922: missing or invalid option
when creating the following trigger:
CREATE TRIGGER TableTrigger
AFTER UPDATE ON TestTable
FOR EACH ROW
BEGIN
set serveroutput on format wrapped;
DBMS_OUTPUT.put_line('TABLE UPDATED!');
END;
Which works on the following table:
CREATE TABLE TestTable
(
test1 INT,
test2 INT,
test3 INT,
PRIMARY KEY (test1)
);
I'm not sure what to do, does anyone have any suggestions?
Using DBMS_OUTPUT in triggers is not best practice. If you want to see that something was done create a logging table or an audit history table or set auditing of update on for that table.
DBMS_OUTPUT is useful when you are running a PL/SQL procedure or package from SQLPlus or other IDE.
Different versions of SQL may or may not show you the output of the buffer from a trigger.

Oracle Trigger on Insert or Delete or Update

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;