While creating a trigger on the 'emprunter' table, I'm trying to compare a value coming from another table 'exemplaire.numexemplaire' which is supposed to be an INTEGER. But I keep getting the same errors which is:
Error(4,7): PL/SQL: SQL Statement ignored
Error(7,15): PL/SQL: ORA-00904: "EMPRUNTER"."NUMEXEMPLAIRE":
invalid identifier
How can I do to retrieve the value of a field coming from another table (exemplaire.numexemplaire)?
CREATE OR REPLACE TRIGGER BIEmprunter
BEFORE INSERT OR UPDATE OF numexemplaire ON emprunter
FOR EACH ROW
DECLARE
livreEmpruntable INTEGER;
BEGIN
SELECT exemplaire.empruntable
INTO livreEmpruntable
FROM exemplaire
WHERE emprunter.numexemplaire = exemplaire.numexemplaire;
IF livreEmpruntable != 1 THEN
raise_application_error(-20000, 'exemplaire non empruntable');
END if;
END;
UPDATE 1
Thanks for the answer but I keep getting this error whule trying to test the trigger...
SQL Error: ORA-04098: trigger 'EQUIPE10.ABONNEMENTPASAJOUR' is invalid and failed re-validation
04098. 00000 - "trigger '%s.%s' is invalid and failed re-validation"
*Cause: A trigger was attempted to be retrieved for execution and was
found to be invalid. This also means that compilation/authorization
failed for the trigger.
*Action: Options are to resolve the compilation/authorization errors,
disable the trigger, or drop the trigger.
Update 2
Thanks again for the answer, the trigger can compile now. But when now I'm trying to make it work when inserting value but I keep getting the error because there is no data yet...
INSERT INTO emprunter
VALUES (2, 1, 18, '17-02-01', null);
Error report -
SQL Error: ORA-01403: no data found
ORA-06512: at "EQUIPE10.BIEMPRUNTER", line 4
ORA-04088: error during execution of trigger 'EQUIPE10.BIEMPRUNTER'
01403. 00000 - "no data found"
*Cause: No data was found from the objects.
*Action: There was no data from the objects which may be due to end of fetch.
You want to join the two tables:
CREATE OR REPLACE TRIGGER BIEmprunter
BEFORE INSERT OR UPDATE OF numexemplaire ON emprunter
FOR EACH ROW
DECLARE
livreEmpruntable INTEGER;
BEGIN
SELECT exemplaire.empruntable
INTO livreEmpruntable
FROM exemplaire
join emprunter
ON emprunter.numexemplaire = exemplaire.numexemplaire;
IF livreEmpruntable != 1 THEN
raise_application_error(-20000, 'exemplaire non empruntable');
END if;
END;
Also, the above join query can potentially return multiple rows and the call will result in exception (uncaught as of now)
ORA-01422: exact fetch returns more than requested number of rows
I guess you want to use :new to access the record that triggered the trigger:
CREATE OR REPLACE TRIGGER BIEmprunter
BEFORE INSERT OR UPDATE OF numexemplaire ON emprunter
FOR EACH ROW
DECLARE
livreEmpruntable INTEGER;
BEGIN
SELECT exemplaire.empruntable
INTO livreEmpruntable
FROM exemplaire
WHERE :new.numexemplaire = exemplaire.numexemplaire;
IF livreEmpruntable != 1 THEN
raise_application_error(-20000, 'exemplaire non empruntable');
END if;
END;
Related
I'm trying to create Oracle after insert trigger with the following code:
CREATE OR REPLACE TRIGGER AutoManhour
AFTER INSERT ON TBL_MSTPROJECT
FOR EACH ROW
DECLARE
CURSOR c_Section IS
SELECT IDSECTION AS IDSECTION FROM TBL_MSTSECTIONHR;
v_Section c_Section%ROWTYPE;
BEGIN
OPEN c_Section;
LOOP
FETCH c_Section INTO v_Section;
INSERT INTO TBL_TRXMANHOURS (ID_SECTION,INPUTBY_TRXMANHOURS,INPUTON_TRXMANHOURS,ID_PROJECT)
VALUES (v_Section.IDSECTION,'IT_ROBOT',SYSDATE,:new.IDPROJECT);
END LOOP;
CLOSE c_Section;
END AutoManhour;
/
But it retrieve an error :
ORA-04098: trigger 'DEPEEL.AUTOMANHOUR' is invalid and failed
re-validation
Why does this happen?
I think you must have used the incorrect column/table names or incorrect datatypes are used while inserting data into TBL_TRXMANHOURS. And of course, there is an infinite loop, You should make some condition to make it finite
Oracle will try to recompile invalid objects as they are referred to. Here the trigger is invalid
select * from user_errors where type = 'TRIGGER' and name = 'AUTOMANHOUR'
You can try the above query to find the actual error.
Cheers!!
When I generate the SQL using PowerDesigner and run it in Oracle, it throws the error
Warning:Trigger creation with compilation errors
create trigger "tib_material_classify" before insert
on "material_classify" for each row
declare
integrity_error exception;
errno integer;
errmsg char(200);
dummy integer;
found boolean;
begin
-- column ""id"" uses sequence material_classify_seq;
select material_classify_seq.nextval into :new."id" from dual;
-- errors handling
exception
when integrity_error then
raise_application_error(errno, errmsg);
end;
When I issue show errors in Oracle, it says the following:
10/5 PL/SQL: SQL Statement ignored
10/12 PL/SQL: ORA-02289: sequence does not exist
What am I doing wrong?
The error message suggests that sequence material_classify_seq is missing. You can create the missing sequence with the following SQL statement:
Create Sequence material_classify_seq;
Before create trigger you need create sequnce
Create sequence material_classify_seq start with 1; after create trigger
I am trying to execute my trigger:
CREATE OR REPLACE TRIGGER Trg_video_bfr_delete
AFTER DELETE ON CMS_VIDEO
FOR EACH ROW
DECLARE
CODE varchar2(60);
BEGIN
SELECT CODE INTO CODE
from CMS_VIDEO
WHERE CODE = :OLD.CODE;
IF CODE IS NOT NULL THEN
INSERT INTO ASSET_DELETE_INDEX(CODE,ASSET_TYPE,IW_VPATH,LANGUAGE,MODIFIED_DTE)
VALUES (CODE,'Video',:old.IW_VPATH,:old.CONTENT_LANGUAGE,sysdate);
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
INSERT INTO ASSET_DELETE_INDEX (CODE,ASSET_TYPE,IW_VPATH,LANGUAGE,MODIFIED_DTE)
VALUES (CODE,'Video',null,:old.CONTENT_LANGUAGE,sysdate);
COMMIT;
END Trg_video_bfr_delete;
/
But I am getting the following error while executing a delete command on the table
Error report -
SQL Error: ORA-04091: table LSDS.CMS_VIDEO is mutating, trigger/function may not see it
ORA-06512: at "LSDS.TRG_VIDEO_BFR_DELETE", line 6
ORA-04088: error during execution of trigger 'LSDS.TRG_VIDEO_BFR_DELETE'
04091. 00000 - "table %s.%s is mutating, trigger/function may not see it"
*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.
Could anyone please help?
You have written trigger AFTER DELETE ON CMS_VIDEO. This trigger will fire when DELETE is performed from CMS_VIDEO table. So when CMS_VIDEO table is being modified, you cannot modify or query the same table in any of your triggers, procedures or functions.
CREATE OR REPLACE TRIGGER Trg_video_bfr_delete
AFTER DELETE ON CMS_VIDEO
FOR EACH ROW
BEGIN
IF :old.CODE IS NOT NULL THEN
INSERT INTO ASSET_DELETE_INDEX(CODE, ASSET_TYPE, IW_VPATH, LANGUAGE, MODIFIED_DTE)
VALUES (:old.CODE, 'Video', :old.IW_VPATH, :old.CONTENT_LANGUAGE, sysdate);
END IF;
END Trg_video_bfr_delete;
/
This is because you are deleting record from table and same table is used as reference inside trigger. This is case of "Mutating Error". You should switch to statement level trigger is it fits your requirement or you can use compound trigger which has multiple entry point and are capable of handling such scenarios.
Please refer https://oracle-base.com/articles/9i/mutating-table-exceptions
As per the snippet provided, I dont see any point in doing a SELECT on mutating TABLE.
We can easily ise :OLD.CODE to fetch the value. Hope below snippet helps.
CREATE OR REPLACE TRIGGER Trg_video_bfr_delete AFTER
DELETE ON CMS_VIDEO FOR EACH ROW
-- DECLARE CODE VARCHAR2(60);
BEGIN
-- SELECT CODE INTO CODE FROM CMS_VIDEO WHERE CODE = :OLD.CODE;
IF CODE IS NOT NULL THEN
INSERT
INTO ASSET_DELETE_INDEX
(
CODE,
ASSET_TYPE,
IW_VPATH,
LANGUAGE,
MODIFIED_DTE
)
VALUES
(
:old.code,
'Video',
:old.IW_VPATH,
:old.CONTENT_LANGUAGE,
sysdate
);
END IF;
EXCEPTION
WHEN OTHERS THEN
INSERT
INTO ASSET_DELETE_INDEX
(
CODE,
ASSET_TYPE,
IW_VPATH,
LANGUAGE,
MODIFIED_DTE
)
VALUES
(
:old.code,
'Video',
NULL,
:old.CONTENT_LANGUAGE,
sysdate
);
COMMIT;
END Trg_video_bfr_delete;
I am trying to get a trigger on the table PACKS that set a min Value in INT Field - PRICE when inserting a new PACK - for example '333'. for insert calling a Procedure new pack.
thats the trigger:
CREATE OR REPLACE TRIGGER pack_min_price
BEFORE
INSERT
ON PACKS
FOR EACH ROW
BEGIN
IF new.PRICE < 333 THEN
:new.PRICE := :new.PRICE + 333;
END IF;
END;
and thats the PROCEDURE:
create or replace PROCEDURE newPack(
cntr IN PACKS.COUNTRY%TYPE,
trns IN PACKS.TRANSPORT%TYPE,
htl IN PACKS.HOTEL%TYPE,
extr IN PACKS.HOTELEXTRAS%TYPE,
othextr IN PACKS.OTHEREXTRAS%TYPE,
strdt IN PACKS.STARTDATE%TYPE,
enddt IN PACKS.ENDDATE%TYPE,
prc IN PACKS.PRICE%TYPE)
IS
BEGIN
INSERT INTO PACKS
(COUNTRY,TRANSPORT,HOTEL,HOTELEXTRAS,OTHEREXTRAS,STARTDATE,ENDDATE,PRICE)
VALUES
(cntr,trns,htl,extr,othextr,strdt,enddt,prc);
COMMIT;
END;
the error i get when i try to compile the trigger -
Compilation failed, line 2 (10:12:41) The line numbers associated with compilation errors are relative to the first BEGIN statement. This only affects the compilation of database triggers.
PLS-00201: identifier 'NEW.PRICE' must be declaredCompilation failed, line 2 (10:12:41) The line numbers associated with compilation errors are relative to the first BEGIN statement. This only affects the compilation of database triggers.
PL/SQL: Statement ignored
and when i start the procedure -
ORA-04098: trigger 'PROJECT160.PACK_MIN_PRICE' is invalid and failed re-validation
without the Trigger the Procedure is working perfectly fine. Can you help? thx
You are missing the : on the new instance in the IF statement.
IF :new.PRICE < 333 THEN
:new.PRICE := :new.PRICE + 333;
END IF;
I have a procedure created and i am using a merge query inside it.
when i compile the procedure, there is no error and when i try to execute it giving me
below error. Can someone help in solving this.
Code:
CREATE OR REPLACE PROCEDURE DEVICE.Check1
IS
BEGIN
MERGE INTO DEVICE.APP_C_CATEGORY A
USING (SELECT market_segment_id,
market_segment_name,
UPDATE_USER,
UPDATE_DATE
FROM CUST_INTEL.MSE_MARKET_SEGMENT_MASTER#SOURCE_CUST_INTEL.ITG.TI.COM
WHERE market_segment_id NOT IN ('120', '130', '100')) B
ON (A.APP_CATEGORY_ID = B.market_segment_id
AND A.APP_CATEGORY_NAME = B.market_segment_name)
WHEN MATCHED
THEN
UPDATE SET A.DESCRIPTION = B.market_segment_name,
A.PARENT_APP_AREA_ID = NULL,
A.RECORD_CHANGED_BY = B.UPDATE_USER,
A.RECORD_CHANGE_DATE = B.UPDATE_DATE
WHEN NOT MATCHED
THEN
INSERT (A.APP_CATEGORY_NAME,
A.DESCRIPTION,
A.TYPE,
A.PARENT_APP_AREA_ID,
A.RECORD_CHANGED_BY,
A.RECORD_CHANGE_DATE)
VALUES (B.market_segment_name,
B.market_segment_name,
1,
NULL,
B.UPDATE_USER,
B.UPDATE_DATE);
COMMIT;
EXCEPTION
WHEN OTHERS
THEN
ROLLBACK;
DBMS_OUTPUT.PUT_LINE (SQLERRM);
DBMS_OUTPUT.PUT_LINE (SQLCODE);
END;
/
Error: when i am executing
BEGIN
DEVICE.CHECK1;
COMMIT;
END;
the following errors occur:
ORA-06550: line 2, column 10:
PLS-00302: component 'CHECK1' must be declared
ORA-06550: line 2, column 3:
PL/SQL: Statement ignored
This is nothing to do with the merge, it isn't getting as far as actually executing your procedure. From the create procedure statement you have a schema called DEVICE. Since the error message is only complaining about CHECK1, not DEVICE.CHECK1, you also appear to have a package called DEVICE. Your anonymous block is trying to find a procedure called CHECK1 within that package, not at schema level.
If you are connected as the device schema owner (user) when you execute this, just remove the schema prefix:
BEGIN
CHECK1;
COMMIT;
END;
/