Getting error while creating Trigger in Oracle - oracle

I have created a trigger below but its giving me error as
3/1 PLS-00428: an INTO clause is expected in this SELECT statement 5/1 PL/SQL: SQL Statement ignored 6/28 PL/SQL: ORA-00984: column not allowed here Errors: check compiler log
Below is my code
create or replace TRIGGER "APP_WFM"."TRG_INS_NE_SF_SITE_INSTANCE"
BEFORE INSERT OR UPDATE ON NE_SITE_INSTANCE
FOR EACH ROW
BEGIN
select rf_siteid, sap_id, site_name from SF_NE_DETAILS;
INSERT INTO NE_SITE_INSTANCE (rf_siteid, sap_id, sitename)
VALUES (rf_siteid, sap_id, site_name);
END;
What can I try to resolve this?

Based on your previous question, you want to use the :NEW record to get the inserted values and then insert into the second table that you are copying into:
CREATE TRIGGER APP_WFM.TRG_INS_NE_SF_SITE_INSTANCE
BEFORE INSERT OR UPDATE ON NE_SITE_INSTANCE -- Table being copied from
FOR EACH ROW
BEGIN
INSERT INTO SF_NE_DETAILS ( -- Table being copied to
rf_siteid,
sap_id,
site_name
) VALUES (
:NEW.rf_siteid,
:NEW.sap_id,
:NEW.site_name
);
END;
/
db<>fiddle here

Related

I do not know how to create log trigger

I need to create log trigger for after update, after insert and before delete.
In the accounts_history table I have more rows than in the table of accounts and it confuses me
How to write that trigger?
I tried to do it but I did not succeed, This is how I created tables and sequences.
I'm a beginner in Oracle and plsql
I'm sorry if I did not explain my problem well.
create table accounts (
id number,
name varchar2(32),
amount number,
date date
);
create sequnce acc_seq_id
start wtih 1
increment by 1
nocache
nocycle;
create table accounts_history (
id number
, old_name varchar2(32)
, new_name varchar2(32)
, old_amount number
, new_amount number
, change_date date
);
My trigger for only after update
create or replace trigger after_update
after update
on accounts referencing new as new old as old
for each row
begin
iNSERT INTO account_history
(
id,
name,
old_name,
amount,
old_amount,
date
)
values
(
:old.id,
:new.name,
:old.old_name,
:new.amount,
:old.old_amount,
sysdate
);
end;
/
The error:
SQL> show error
Errors for TRIGGER AFTER_UPDATE:
LINE/COL ERROR
-------- --------------------------------------------------------------
2/1 PL/SQL: SQL Statement ignored
9/2 PL/SQL: ORA-01747: invalid user.table.column, table.column, or
column specification
13/2 PLS-00049: bad bind variable 'OLD.ID'
14/2 PLS-00049: bad bind variable 'NEW.NAME'
15/2 PLS-00049: bad bind variable 'OLD.OLD_NAME'
16/2 PLS-00049: bad bind variable 'NEW.AMOUNT'
17/2 PLS-00049: bad bind variable 'OLD.OLD_AMOUNT'
SQL>
The values you insert come from the ACCOUNTS table, the columns you target come ACCOUNT_HISTORY table. You have mixed them up, which is why you get the ORA-01747 error. Try this:
create or replace trigger after_update
after update on accounts
referencing new as new old as old
for each row
begin
INSERT INTO account_history
(
id,
new_name,
old_name,
new_amount,
old_amount,
change_date
)
values
(
:old.id,
:new.name,
:old.name,
:new.amount,
:old.amount,
sysdate
);
End;
/

Oracle PL-SQL: insert a rowtype after select - no enough values

Im trying to execute a block in PL/SQL that
Get the actual data of a row by doing table%rowtype
Modify an attribute from it
And then inserting the record in a INSERT INTO...VALUES statement like follows.
declare
v_record table%ROWTYPE
begin
select *
into v_record
from X_table;
insert into X_table values (v_record)
end;
But the error that raises when I do this is PL/SQL: ORA-00947: not enough values
I've solved this issue removing the parenthesis from the values selection in the INSERT statement.
For example:
insert into X_table values v_record;

Error(3,31): PL/SQL: ORA-00984: Column is not allowed here

I am writing following oracle sql trigger
CREATE OR REPLACE TRIGGER scheme1.INSERTING_TRIGGER AFTER INSERT ON scheme1.Bill
FOR EACH ROW
BEGIN
INSERT INTO scheme2.DM_LOGGER(ID, TECHNOLOGY, WORKFLOW, NAME_EVENT, TIME_EVENT)
VALUES(scheme1.Bill.id,'Repository','UP','Accepted', SYSDATE);
END;
And it throws following errors:
Error(2,1): PL/SQL: SQL Statement ignored
Error(3,31): PL/SQL: ORA-00984: Column isn't allowed here.
If my guess is correct, the problem is in the ID column of the DM_LOGGER.
But I'm not sure what wrong it is about. I just want to insert the id from a new Bill record automatically in my logger.
You need to use the NEW record:
CREATE OR REPLACE TRIGGER scheme1.INSERTING_TRIGGER AFTER INSERT ON scheme1.Bill
FOR EACH ROW
BEGIN
INSERT INTO scheme2.DM_LOGGER(ID, TECHNOLOGY, WORKFLOW, NAME_EVENT, TIME_EVENT)
VALUES(:NEW.id,'Repository','UP','Accepted', SYSDATE);
END;
http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/triggers.htm#LNPLS99955

ERROR at line 2: PL/SQL: Statement ignored

CREATE OR REPLACE TRIGGER log_FAMILY_increase
AFTER UPDATE OF FAMILY_INCOME ON STUDENT
FOR EACH ROW
BEGIN
INSERT INTO STUDENT_2 (NAME, SURNAME, NEW_FAMILY_INCOME)
VALUES (:NEW.NAME,SURNAME, :NEW.FAMILY_INCOME, 'New INCOME');
END;
in oracle 10g i get this error message:
ERROR at line 2: PL/SQL: Statement ignored
You're missing a column name here "(name, surname, new_family_income)", as you are trying to insert 4 values into 3 columns.. I switched the statement, to not list out the columns, maybe that will help..
CREATE OR REPLACE TRIGGER log_family_increase
AFTER UPDATE OF family_income
ON student
REFERENCING NEW AS new OLD AS old
FOR EACH ROW
BEGIN
INSERT INTO student_2
VALUES (:new.name,
:new.surname,
:new.family_income,
'New INCOME');
END;

Create trigger to insert into another table

I have some problem executing the trigger below:
CREATE OR REPLACE TRIGGER AFTERINSERTCREATEBILL
AFTER INSERT
ON READING
FOR EACH ROW
DECLARE
varReadNo Int;
varMeterID Int;
varCustID Varchar(10);
BEGIN
SELECT SeqReadNo.CurrVal INTO varReadNo FROM DUAL;
Select MeterID INTO varMeterID
From Reading
Where ReadNo = varReadNo;
Select CustID INTO varCustID
From Address A
Join Meter M
on A.postCode = M.postCode
Where M.MeterID = varMeterID;
INSERT INTO BILL VALUES
(SEQBILLNO.NEXTVAL, SYSDATE, 'UNPAID' , 100 , varCustID , SEQREADNO.CURRVAL);
END;
Error Message:
*Cause: A trigger (or a user defined plsql function that is referenced in
this statement) attempted to look at (or modify) a table that was
in the middle of being modified by the statement which fired it.
*Action: Rewrite the trigger (or function) so it does not read that table.
Does it mean that I am not suppose to retrieve any details from table Reading?
I believe that the issue occur as I retrieving data from Table Reading while it is inserting the value:
SELECT SeqReadNo.CurrVal INTO varReadNo FROM DUAL;
Select MeterID INTO varMeterID
From Reading
Where ReadNo = varReadNo;
It's there anyway to resolve this? Or is there a better method to do this? I need to insert a new row into table BILL after entering the table Reading where the ReadNo need to reference to the ReadNo I just insert.
You cannot retrieve records from the same table in a row trigger. You can access values from actual record using :new and :old (is this your case?). The trigger could then be rewritten to
CREATE OR REPLACE TRIGGER AFTERINSERTCREATEBILL
AFTER INSERT
ON READING
FOR EACH ROW
DECLARE
varCustID Varchar(10);
BEGIN
Select CustID INTO varCustID
From Address A
Join Meter M
on A.postCode = M.postCode
Where M.MeterID = :new.MeterID;
INSERT INTO BILL VALUES
(SEQBILLNO.NEXTVAL, SYSDATE, 'UNPAID' , 100 , varCustID , SEQREADNO.CURRVAL);
END;
If you need to query other record from READING table you have to use a combination of statement triggers, row trigger and a PLSQL collection. Good example of this is on AskTom.oracle.com
Make sure that you have the necessary permissions on all the tables and access to the sequences you're using in the insert.
I haven't done Oracle in awhile, but you can also try querying dba_errors (or all_errors) in order to try and get more information on why your SP isn't compiling.
Something to the tune of:
SELECT * FROM dba_errors WHERE owner = 'THEOWNER_OF_YOUR_SP';
Add exception handling in your trigger and see what is happening, by doing it would be easy for you to track the exceptions.
CREATE OR REPLACE TRIGGER AFTERINSERTCREATEBILL
AFTER INSERT
ON READING
FOR EACH ROW
DECLARE
varCustID Varchar(10);
BEGIN
-- your code
EXCEPTION
WHEN NO_DATA_FOUND
THEN
DBMS_OUTPUT.PUT_LINE(TO_CHAR(SQLERRM(-20299)));
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(TO_CHAR(SQLERRM(-20298)));
END;
we can combined insert and select statement
CREATE OR REPLACE TRIGGER AFTERINSERTCREATEBILL
AFTER INSERT
ON READING
FOR EACH ROW
DECLARE
varCustID Varchar(10);
BEGIN
insert into bill
values
select SEQBILLNO.NEXTVAL,
SYSDATE,
'UNPAID' ,
100 ,
CustID,SEQREADNO.CURRVAL
From Address A
Join Meter M
on A.postCode = M.postCode
Where M.MeterID = :new.MeterID;
END;
try the above code.

Resources