Oracle SQL Trigger for set min Value to INT Field on NULL - oracle

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;

Related

a double-quoted delimited-identifier error SQL

Hi everyone am experiencing this error in oracle
Errors: TRIGGER NOUPDATE
Line/Col: 9/5 PLS-00103: Encountered the symbol "IF" when expecting one of the following:
; <an identifier> <a double-quoted delimited-identifier>
This is the code:
CREATE OR REPLACE TRIGGER NoUpdate
BEFORE UPDATE OF apartmentsize ON rental
FOR EACH ROW
DECLARE
apartmentsize INT(22);
BEGIN
IF (apartmentsize < 60) THEN
BEGIN
RAISE_APPLICATION_ERROR(-20112,
'You cannot update the apartmentsize');
ROLLBACK;
END IF;
END;
/
I think it's firing the trigger but the IF condition is never true. I don't see anywhere that you assign a value to apartmentsize.
If you think it is this statement:
apartmentsize int(22);
Then no, that is simply saying that aparmentsize is declared as a 22-digit integer. If you want to assign a value:
apartmentsize int := 22;
And according to the 18c SQL Language Reference, 'int' is not a valid data type. Supported numeric data types are:
number
float
binary_float
binary_double
What you want is NUMBER(precision,scale). See here.
You have a BEGIN without an END and you probably want to use :NEW.apartmentsize bind variable to reference the updated value rather than declaring a variable in the trigger:
CREATE OR REPLACE TRIGGER NoUpdate
BEFORE UPDATE OF apartmentsize ON rental
FOR EACH ROW
DECLARE
BEGIN
IF (:NEW.apartmentsize < 60) THEN
RAISE_APPLICATION_ERROR(
-20112,
'You cannot update the apartmentsize'
);
END IF;
END;
/
(Note: Including ROLLBACK is pointless as raising the exception will implicitly trigger a rollback and once you have raised the exception the rest of the code in the trigger will not be parsed as an exception has been raised.)
Then if you have the table:
CREATE TABLE rental ( id, apartmentsize ) AS
SELECT 1, 100 FROM DUAL;
Then:
UPDATE rental
SET apartmentsize = 60
WHERE id = 1;
Will work but:
UPDATE rental
SET apartmentsize = 59
WHERE id = 1;
Will raise the exception:
ORA-20112: You cannot update the apartmentsize
ORA-06512: at "FIDDLE_DAVWBSJBRDBITOSDOROT.NOUPDATE", line 4
ORA-04088: error during execution of trigger 'FIDDLE_DAVWBSJBRDBITOSDOROT.NOUPDATE'
db<>fiddle here

Oracle Trigger To Check Values On Insert & Update

I am trying to check a value-gap crossed with each other or not. Let me explain with a quick scenario.
Rec 1 : Company AA : Distance Gap -> 100 - 200
Rec 2 : Company AA : Distance Gap -> 200 - 300 VALID
Rec 3 : Company AA : Distance Gap -> 250 - 450 INVALID
Rec 4 : Company JL : Distance Gap -> 250 - 450 VALID
Rec 3 Invalid because it is between REC 2's distance values.
Rec 4 Valid because company is different
Thus I wrote a trigger to prevent it.
create or replace trigger ab_redemption_billing_mpr
after insert or update on redemption_billing_mpr
for each row
declare
v_is_distance_range_valid boolean;
begin
v_is_distance_range_valid := p_redemption_billing.is_distance_range_valid(:new.id,
:new.redemption_billing_company,
:new.distance_min,
:new.distance_max,
'redemption_billing_mpr');
if not v_is_distance_range_valid then
raise_application_error(-20001, 'This is a custom error');
end if;
end ab_redemption_billing_mpr;
FUNCTION:
function is_distance_range_valid(p_id in number,
p_company in varchar2,
p_distance_min in number,
p_distance_max in number,
p_table_name in varchar2) return boolean is
d_record_number number;
begin
execute immediate 'select count(*) from ' || p_table_name || ' r
where r.redemption_billing_company = :1
and (:2 between r.distance_min and r.distance_max or :3 between r.distance_min and r.distance_max)
and r.id = nvl(:4, id)'
into d_record_number
using p_company, p_distance_min, p_distance_max, p_id;
if (d_record_number > 0) then
return false;
else
return true;
end if;
end;
is_distance_range_valid() works just as I expected. If it returns false, that means range check is not valid and don't insert or update.
When I create a scenario to catch this exception, oracle gives
ORA-04091: table name is mutating, trigger/function may not see it
and it points select count(*) line when I click debug button.
I don't know why I am getting this error. Thanks in advance.
Just check whether the below approach resolves your issue
Create a log table with columns required for finding the is_distance_range_valid validation and In your trigger insert into this log tab.The trigger on main table has to be a before insert or update trigger
Create a trigger on this log table and do the validation in the log table trigger and raise error.The trigger on log table has to be an after insert or update trigger.
Also this will only work if the row is already existing in the main table and it is not part of the current insert or update. If validation of the current insert or update is required then we need to use the :new.column_name to do the validation
Test:-
create table t_trg( n number);
create table t_trg_log( n number);
create or replace trigger trg_t
before insert or update on t_trg
for each row
declare
l_cnt number;
begin
insert into t_trg_log values(:new.n);
end trg_t;
create or replace trigger trg_t_log
after insert or update on t_trg_log
for each row
declare
l_cnt number;
begin
select count(1) into l_cnt from t_trg
where n=:new.n;
if l_cnt > 0 then
raise_application_error(-20001, 'This is a custom error');
end if;
end trg_t_log;
The first time I insert it doesn't throw error
insert into t_trg values(7);
1 row inserted.
The second time I execute, I get the custom error
insert into t_trg values(7);
Error report -
ORA-20001: This is a custom error
ORA-06512: at "TRG_T_LOG", line 7
ORA-04088: error during execution of trigger 'TRG_T_LOG'
ORA-06512: at "TRG_T", line 4
ORA-04088: error during execution of trigger 'TRG_T'
Update:-Using compound trigger the error is thrown in the first time the insert is done since it also takes into account the current row that we are updating or inserting while doing the SELECT
First I want to thanks to psaraj12 for his effort.
I found solution. Oracle forces us to not use select query before each row.
Oracle trigger error ORA-04091
So I wrote this and it works.
create or replace trigger ab_redemption_billing_mpr
for insert or update on redemption_billing_mpr
compound trigger
v_is_distance_range_valid boolean;
id redemption_billing_mpr.id%type;
redemption_billing_company redemption_billing_mpr.redemption_billing_company%type;
distance_min redemption_billing_mpr.distance_min%type;
distance_max redemption_billing_mpr.distance_max%type;
after each row is
begin
id := :new.id;
redemption_billing_company := :new.redemption_billing_company;
distance_min := :new.distance_min;
distance_max := :new.distance_max;
end after each row;
after statement is
begin
v_is_distance_range_valid := p_redemption_billing.is_distance_range_valid(id,
redemption_billing_company,
distance_min,
distance_max,
'redemption_billing_mpr');
if not v_is_distance_range_valid then
raise_application_error(-20001, 'This is a custom error');
end if;
end after statement;
end ab_redemption_billing_mpr;
We must use compound trigger to deal with it.

error during execution of trigger : ORA-06502: PL/SQL numeric or value error

when I try to insert in the data table, I get this"numeric or value error: character to number conversion error"
This is my trigger :
CREATE OR REPLACE TRIGGER TRIGGER_ON_TEMP
BEFORE INSERT ON DATA
FOR EACH ROW
DECLARE
CURSOR ERR_MSG_CURSOR IS
SELECT ERROR_MSG FROM REFERENTIEL;
codeERR VARCHAR2(100);
BEGIN
OPEN ERR_MSG_CURSOR; ****
LOOP
FETCH ERR_MSG_CURSOR INTO codeERR;
if (:new.DESCRIPTION LIKE '%'+codeERR+'%') THEN
DBMS_OUTPUT.PUT_LINE('I got here:'||:new.DESCRIPTION);
END IF;
END LOOP;
CLOSE ERR_MSG_CURSOR;
END;
The error is occuring on the line with ****. I'm not quite too sure as to what is causing this error, any help?

PL/SQL Invalid Identifier

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;

Oracle Pl/Sql Procedure Help Merge

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;
/

Resources