I'm having a hard time understanding this error:
Error at line 3: PLS-00103: Encountered the symbol "&" when expecting one of the following:
) , * & - + / at mod remainder rem and or
as || multiset
CREATE OR REPLACE TRIGGER class_trigger
BEFORE INSERT ON Class FOR EACH ROW
BEGIN
IF (type = 'vl' && mass < 15000) THEN
mass := 15000;
The code is:
CREATE OR REPLACE TRIGGER class_trigger
BEFORE INSERT ON Class FOR EACH ROW
BEGIN
IF (type = 'vl' && mass < 15000) THEN
mass := 15000;
END IF;
END;
What is wrong with my code? I'm using Oracle's APEX. Thanks.
You have two problems:
PL/SQL uses AND as the logical operator for the boolean AND operation, not &&.
When accessing fields which are passed to the trigger, you must qualify them with the :OLD or :NEW pseudo-row names.
Thus, you'd need to rewrite your trigger as:
CREATE OR REPLACE TRIGGER class_trigger
BEFORE INSERT ON Class
FOR EACH ROW
BEGIN
IF :NEW.TYPE = 'vl' AND
:NEW.mass < 15000
THEN
:NEW.MASS := 15000;
END IF;
END class_trigger;
Related
I am trying to create a trigger that runs when a car price that's inserted or updated is too high or low.
When trying to compile it just says identifier must be declared where other similar methods I have used or seen use the same methods.
CREATE OR REPLACE TRIGGER carlistprice_insert_update
BEFORE INSERT OR UPDATE ON car
FOR EACH ROW
WHEN (NEW.carlistprice < 0 OR NEW.carlistprice > 250000)
BEGIN
IF NEW.carlistprice < 0 THEN
:NEW.carlistprice := 0;
END IF;
IF NEW.carlistprice > 250000 THEN
:NEW.carlistprice := 250000;
END IF;
END;
/
I am basing this program off of this block of code which works and doesn't need identifier declared.
CREATE OR REPLACE TRIGGER cust_before_insert
BEFORE INSERT ON customer
FOR EACH ROW
WHEN(NEW.custname != UPPER(NEW.custname))
BEGIN
:NEW.custname := UPPER(:NEW.custname);
END;
/
The carlistprice is a valid column in one of my tables
in WHEN clause, NEW (as well as OLD) is without a colon.
elsewhere, it has to be preceded by a colon
So:
CREATE OR REPLACE TRIGGER carlistprice_insert_update
BEFORE INSERT OR UPDATE ON car
FOR EACH ROW
WHEN (NEW.carlistprice < 0 OR NEW.carlistprice > 250000) -- no colon here
BEGIN
IF :NEW.carlistprice < 0 THEN -- colon here
:NEW.carlistprice := 0; -- and here
END IF;
IF :NEW.carlistprice > 250000 THEN -- and here
:NEW.carlistprice := 250000; -- and here
END IF;
END;
/
PLS-00103: Encountered the symbol "&" when expecting one of the following...
code:
Declare
num number;
Begin
num := #
if num > 0 then
dbms_output.put_line(‘Hello’);
end if;
end;
/
I'm not sure why I'm getting this message when I'm not seeing anything wrong.
Oracle Live SQL is a tool for trying out SQL and PL/SQL but it doesn't support substitution variable syntax (&var.).
Instead, you can create tables, populate them with data, then run SQL or PL/SQL using them, e.g.:
create table inputs (num number);
insert into inputs values (10);
Declare
num number;
Begin
select num into num from inputs;
if num > 0 then
dbms_output.put_line('Hello');
end if;
end;
/
(p.s. I had to fix the quotes around 'Hello' for this to work)
Oracle live does not support & for get value.
Instead you can initialize the Variable
Declare
num number := 10;
Begin
if num > 0 then
dbms_output.put_line(‘Hello’);
end if;
end;
/
I have these errors - PLS-00679: trigger binds not allowed in before/after statement section
PLS-00201: identifier 'DBMS_OUT.PUT_LINE' must be declared - but cant locate the problem.
These are the scripts involved-
create or replace trigger hiTk
for insert or update on lending
COMPOUND TRIGGER
--declare
L_Date date;
subtype copy_booksRec is lending%ROWTYPE;
type copied_bks is table of copy_booksRec;
cbks copied_bks := copied_bks();
before each row is
begin
cbks.extend;
cbks(cbks.last).cb_num := :new.cb_num;
cbks(cbks.last).sb_num := :new.sb_num;
-- cbks.last(i).date_L := :new.date_L;
end before each row;
before statement is
begin
for i in cbks.first .. cbks.last loop
select count(date_L) into L_Date from lending where sb_num = cbks(i).sb_num and date_L = :new.date_L;
if (Sysdate = :new.date_L) then
dbms_out.put_line('You can only make ONE LOAN at a time! You have already loaned a book on ' || L_Date);
else
cbks.delete;
end if;
end loop;
FORALL i IN cbks.first .. cbks.last
insert into lending values cbks(i);
cbks.delete;
end before statement;
end hiTk;
/
show errors
Both errors are accurately telling you what is wrong:
PLS-00679: trigger binds not allowed in before/after statement section
But you have:
before statement is
begin
for i in cbks.first .. cbks.last loop
select count(date_L) into L_Date from lending where sb_num = cbks(i).sb_num
and date_L = :new.date_L;
-- ^^^^ THIS IS A TRIGGER BIND, NOT ALLOWED IN BEFORE STATEMENT
PLS-00201: identifier 'DBMS_OUT.PUT_LINE' must be declared
There is no supplied package called DBMS_OUT, it is called DBMS_OUTPUT.
I have created a trigger with a select statement and I want to say if this select statement does not return any rows then put a 0 in the variable "auxiliar". I tried to use NVL(auxiliar,0) but it does not work. How can I do this?
SELECT NVL(salary,0) INTO auxiliar FROM BILL WHERE code=:NEW.code;
[UPDATED] My trigger code:
IF preCondicio THEN
KMpendents:=coalesce(SELECT rev_pendent_km
INTO KMpendents
FROM REV_PENDENT
WHERE rev_pendent_vehicle_codi=:NEW.lloguer_vehicle_codi,0);
IF KMtotals+KMpendents>=15000 THEN
SELECT venedor_codi
INTO venedorCodi
FROM venedor
WHERE venedor_alta=(
SELECT MAX(venedor_alta)
FROM venedor
WHERE venedor_delegacio_codi=(
SELECT venedor_delegacio_codi
FROM venedor
WHERE venedor_codi=:NEW.lloguer_venedor_codi));
INSERT INTO REVISIONS VALUES(:NEW.lloguer_vehicle_codi,:NEW.lloguer_dataf,KMtotals+KMpendents,venedorCodi);
IF KMpendents!=0 THEN
DELETE FROM REV_PENDENT
WHERE rev_pendent_vehicle_codi=:NEW.lloguer_vehicle_codi;
END IF;
ELSE
IF KMpendents!=0 THEN
UPDATE REV_PENDENT SET rev_pendent_km=KMtotals+KMpendents WHERE rev_pendent_vehicle_codi=:NEW.lloguer_vehicle_codi;
ELSE INSERT INTO REV_PENDENT VALUES(:NEW.lloguer_vehicle_codi,KMtotals,:NEW.lloguer_dataf);
END IF;
END IF;
END IF;
The variable KMpendents is equivalent to the variable auxiliar which I told before the updated. But Oracle shows me these errors:
PLS-00103: Encountered the symbol "," when expecting one of the
following: . ( * # % & - + ; / at for mod remainder rem and or group
having intersect minus order start union where connect || indicator
multiset
If the select clause contains only aggregate functions then there will always be at least one row returned.
SELECT coalesce(sum(salary),0)
INTO auxiliar
FROM BILL
WHERE code=:NEW.code;
BEGIN
SELECT NVL(salary,0) INTO auxiliar FROM BILL WHERE code=:NEW.code;
EXCEPTION
WHEN NOTFOUND THEN
auxiliar := 0;
END;
Or you can use SQL%NOTFOUND too to check if the statement returned no rows.
CREATE or REPLACE TRIGGER trigger_name
BEFORE INSERT
ON table_name
[ FOR EACH ROW ]
DECLARE
-- variable declarations
BEGIN
....
....
BEGIN
SELECT NVL(salary,0) INTO auxiliar FROM BILL WHERE code=:NEW.code;
EXCEPTION
WHEN NOTFOUND THEN
auxiliar := 0;
END;
--Yes, this is possible and valid.
EXCEPTION
WHEN ...
-- exception handling
END;
I have a problem with trigger not working. Here is my trigger code
create or replace trigger "ZIVOTINJE_T2"
BEFORE
insert or update on "ZIVOTINJE"
for each row
begin
IF new.cijena>10 THEN
:new.cijena:=9.9
ELSEIF new.cijena<0 THEN
:new.cijena:=0.1
END IF;
end;
When I try to insert entity in table ZIVOTINJE, I get this
ORA-04098: trigger 'DENISS.ZIVOTINJE_T2' is invalid and failed re-validation
I can see three problems in the code of your trigger:
You need to refer to the new values of the row using :new (including the colon), not new.
To change values that are about to be inserted/updated, write :new.cijena := 9.9; instead of SET new.cijena=9.9. Note that (a) there is no SET keyword here; (b) the assignment operator is :=, not =; and (c) you need a semi-colon at the end of the line.
Use ELSIF instead of ELSEIF.
Finally, in SQL*Plus, you can use SHOW ERRORS TRIGGER "ZIVOTINJE_T2" to show the errors for this trigger.
try this.
CREATE OR REPLACE TRIGGER "ZIVOTINJE_T2"
BEFORE
insert or update on "ZIVOTINJE"
for each row
begin
IF :new.cijena = 10 THEN
:new.cijena := 9.9;
ELSE
IF :new.cijena < 0 THEN
:new.cijena := 0.1;
END IF;
end if;
end;