i'd encountered following error when creating the following trigger. How to resolve the error? Please..
Error at line 6: PLS-00103: Encountered the symbol ")" when expecting one of the following:
( begin case declare end exception exit for goto if loop mod
null pragma raise return select update while with
create or replace trigger totalclaimtrig2
after insert on userinfo
for each row
begin
if (:new.sgaji>'2323.41') and (:new.power>1400) then
(
:new.jumlah_claim := :new.jarak*0.7;
:new.kelas='A';
)
elsif (:new.sgaji>'2323.41') and (:new.power between 1000 and 1400) then
(
:new.jumlah_claim := :new.jarak*0.6;
:new.kelas='B';
)
elsif (:new.sgaji>'2323.41') and (:new.power between 500 and 1000) then
(
:new.jumlah_claim := :new.jarak*0.5;
:new.kelas='C';
)
elsif (:new.sgaji>'2323.41') and (:new.power between 175 and 500) then
(
:new.jumlah_claim := :new.jarak*0.45;
:new.kelas='D';
)
elsif (:new.sgaji>'2323.41') and (:new.power<175) then
(
:new.jumlah_claim := :new.jarak*0.4;
:new.kelas='E';
)
end if;
end;
Remove all parentheses, use := instead of = for assignments, remove the weird character after the last ;, and change after insert to before insert to change the NEW values.
create or replace trigger totalclaimtrig2
before insert on userinfo
for each row
begin
if :new.sgaji>'2323.41' and :new.power>1400 then
:new.jumlah_claim := :new.jarak*0.7;
:new.kelas:='A';
elsif :new.sgaji>'2323.41' and :new.power between 1000 and 1400 then
:new.jumlah_claim := :new.jarak*0.6;
:new.kelas:='B';
elsif :new.sgaji>'2323.41' and :new.power between 500 and 1000 then
:new.jumlah_claim := :new.jarak*0.5;
:new.kelas:='C';
elsif :new.sgaji>'2323.41' and :new.power between 175 and 500 then
:new.jumlah_claim := :new.jarak*0.45;
:new.kelas:='D';
elsif :new.sgaji>'2323.41' and :new.power<175 then
:new.jumlah_claim := :new.jarak*0.4;
:new.kelas:='E';
end if;
end;
Related
I am trying to use a variable to set the length of a substr command.
If I explicitly set say 0,13 the code works fine however, I want to be able to use a variable.
Near the end of the code is the area of question:
:new.DOCNO := substr(:new.DESCRIP,0,15); -- success ... but limited
:new.DOCNO := substr(:new.DESCRIP,0,n_len); -- fail
The code overall is looking to find a number pattern from a file name and place it into another column.
Example: HR_1000-0001_A This is a file.pdf
I have tried various data types: integer, number,... etc.
The code compiles but fails when I run the trigger.
CREATE OR REPLACE TRIGGER set_doc_number
BEFORE UPDATE ON external_doc
FOR EACH ROW
WHEN (
new.STATUS = 'Released'
-- current document# is either '' or is ONLY a number
AND (
new.DOC_LIBRARY_ID = ''
OR
REGEXP_LIKE(new.DOC_LIBRARY_ID,'(\d+)')
)
)
DECLARE
-- init variables
b_update boolean;
n_len number := 0;
BEGIN
-- reset for each loop
b_update := FALSE;
-- check if criteria is met
-- AAA_####-####_AA
IF b_update = FALSE AND REGEXP_LIKE(:new.DESCRIP,'([A-Z][A-Z][A-Z]_(\d{4})-(\d{4})_[A-Z])') THEN
b_update := TRUE;
n_len := 15;
END IF;
-- AA_####-####_AA
IF b_update = FALSE AND REGEXP_LIKE(:new.DESCRIP,'([A-Z][A-Z]_(\d{4})-(\d{4})_[A-Z])') THEN
b_update := TRUE;
n_len := 14;
END IF;
-- AAA_####-####_A
IF b_update = FALSE AND REGEXP_LIKE(:new.DESCRIP,'([A-Z][A-Z][A-Z]_(\d{4})-(\d{4})_[A-Z])') THEN
b_update := TRUE;
n_len := 15;
END IF;
-- AA_####-####_A
IF b_update = FALSE AND REGEXP_LIKE(:new.DESCRIP,'([A-Z][A-Z]_(\d{4})-(\d{4})_[A-Z])') THEN
b_update := TRUE;
n_len := 14;
END IF;
-- AAA_####-####
IF b_update = FALSE AND REGEXP_LIKE(:new.DESCRIP,'([A-Z][A-Z][A-Z]_(\d{4})-(\d{4}))') THEN
b_update := TRUE;
n_len := 13;
END IF;
-- AA_####-####
IF b_update = FALSE AND REGEXP_LIKE(:new.DESCRIP,'([A-Z][A-Z]_(\d{4})-(\d{4}))') THEN
b_update := TRUE;
n_len := 12;
END IF;
-- can we update?
IF b_update = TRUE THEN
-- update
:new.DOCNO := substr(:new.DESCRIP,0,n_len);
END IF;
END;
I'm not sure why using n_len fails, it looks fine to me. PL/SQL indexes start at 1 and not 0, but it works fine if you use 0, so that's not an issue.
If you're going to use regexp functions, I'd suggest just using regexp_substr:
CREATE OR REPLACE TRIGGER set_doc_number
BEFORE UPDATE ON external_doc
FOR EACH ROW
WHEN (
new.STATUS = 'Released'
-- current document# is either '' or is ONLY a number
AND (
new.DOC_LIBRARY_ID = ''
OR
REGEXP_LIKE(new.DOC_LIBRARY_ID,'(\d+)')
)
)
DECLARE
-- init variables
v_docno varchar2(20);
BEGIN
-- look for a str with (2-3 alpha)_####-####(optional underscore and 1-3 alpha)
v_docno := regexp_substr(:new.DESCRIP,'[A-Z][A-Z][A-Z]?_\d{4}-\d{4}(_[A-Z][A-Z]?[A-Z]?)?');
-- can we update?
IF v_docno is not null THEN
-- update
:new.DOCNO := v_docno;
END IF;
END;
Good afternoon everybody.
I have the following problem, I am loading a query to the cursor "c_Pol_Vig_Ant" and after certain validations I save the results in a list
TYPE r_Pol_Vig_Ant IS RECORD(
NUMPOL USRAXVM00.Vm_Poliza.NUMPOL%TYPE,
IDEOBSER USRAXVM00.Vm_Obser_Poliza.IDEOBSER%TYPE,
NUMAVISO USRAXVM00.Vm_Obser_Poliza.NUMAVISO%TYPE,
FECINIVIG USRAXVM00.Vm_Poliza.FECINIVIG%TYPE,
FECFINVIG USRAXVM00.Vm_Poliza.FECFINVIG%TYPE,
FECVCT USRAXVM00.VM_GIROS_FINANCIAMIENTO.FECVCT%TYPE,
ORDEN USRAXVM00.VM_GIROS_FINANCIAMIENTO.NUMGIRO%TYPE,
IDGIRO USRAXVM00.VM_GIROS_FINANCIAMIENTO.IDGIRO%TYPE,
CODMONEDA USRAXVM00.VM_ACREENCIA.CODMONEDA%TYPE,
MTOACREMONEDA USRAXVM00.VM_ACREENCIA.MTOACREMONEDA%TYPE,
STSGIRO USRAXVM00.VM_GIROS_FINANCIAMIENTO.STSGIRO%TYPE,
CODPROD USRAXVM00.Vm_Poliza.CODPROD%TYPE,
PENDIENTE USRAXVM00.VM_ACREENCIA.MTOACREMONEDA%TYPE,
TOTAL USRAXVM00.VM_ACREENCIA.MTOACREMONEDA%TYPE,
COBRADO USRAXVM00.VM_ACREENCIA.MTOACREMONEDA%TYPE,
FECHAEMISAVISO USRAXVM00.Vm_Obser_Poliza.FECHA%TYPE,
CODCANAL USRAXVM00.Vm_Poliza.CODCANAL%TYPE,
CANAL USRAXVM00.Vm_Tercero.NOMTER%TYPE,
CODINTER USRAXVM00.Vm_Part_Inter_Pol.CODINTER%TYPE,
AGENTE USRAXVM00.Vm_Tercero.NOMTER%TYPE,
CODPLAN USRAXVM00.Vm_Cond_Financiamiento.CODPLAN%TYPE,
NOMPLAN USRAXVM00.VM_PLAN_FINANCIAMIENTO.NOMPLAN%TYPE,
ORIGEN VARCHAR2(4),
VIGENCIA VARCHAR2(20)
);
TYPE tab_Pol_Vig_Ant IS TABLE OF r_Pol_Vig_Ant;
TYPE tab_Lista IS TABLE OF r_Pol_Vig_Ant INDEX BY BINARY_INTEGER;
FOR x IN c_Pol_Vig_Ant LOOP
IF x.STSGIRO = 'CAS' OR x.STSGIRO = 'AND' THEN
v_Valor := USRAXVM00.PO_POL_REN_VIG_ANT.Depurar_And_Cas(x.NUMAVISO, x.IDGIRO, x.ORDEN);
IF v_Valor <> 1 THEN
v_Cont := v_Cont + 1;
p_Datos(v_Cont).NUMPOL := x.NUMPOL;
p_Datos(v_Cont).IDEOBSER := x.IDEOBSER;
p_Datos(v_Cont).NUMAVISO := x.NUMAVISO;
p_Datos(v_Cont).FECINIVIG := x.FECINIVIG;
p_Datos(v_Cont).FECFINVIG := x.FECFINVIG;
p_Datos(v_Cont).FECVCT := x.FECVCT;
p_Datos(v_Cont).ORDEN := x.ORDEN;
p_Datos(v_Cont).IDGIRO := x.IDGIRO;
p_Datos(v_Cont).CODMONEDA := x.CODMONEDA;
p_Datos(v_Cont).MTOACREMONEDA := x.MTOACREMONEDA;
p_Datos(v_Cont).STSGIRO := x.STSGIRO;
p_Datos(v_Cont).CODPROD := x.CODPROD;
p_Datos(v_Cont).PENDIENTE := x.PENDIENTE;
p_Datos(v_Cont).TOTAL := x.TOTAL;
p_Datos(v_Cont).COBRADO := x.COBRADO;
p_Datos(v_Cont).FECHAEMISAVISO := x.FECHAEMISAVISO;
p_Datos(v_Cont).CODCANAL := x.CODCANAL;
p_Datos(v_Cont).CANAL := x.CANAL;
p_Datos(v_Cont).CODINTER := x.CODINTER;
p_Datos(v_Cont).AGENTE := x.AGENTE;
p_Datos(v_Cont).CODPLAN := x.CODPLAN;
p_Datos(v_Cont).NOMPLAN := x.NOMPLAN;
p_Datos(v_Cont).ORIGEN := x.ORIGEN;
p_Datos(v_Cont).VIGENCIA := x.VIGENCIA;
END IF;
END IF;
END LOOP;
The error is the following, when making the query to a PIPELINE function sending as parameter my list I get the error expressions is of wrong type.
FOR x IN p_Datos.First..p_Datos.Last LOOP
SELECT COUNT(DISTINCT t.VIGENCIA)
INTO v_NroVigencias
FROM table(USRAXVM00.PO_POL_REN_VIG_ANT.F_Obtener_Datos(p_Listar => p_Datos)) t
WHERE t.NUMPOL = p_Datos(x).NUMPOL;
IF v_NroVigencias = 1 THEN
p_Datos.DELETE(x);
END IF;
END LOOP;
This is my function:
FUNCTION F_Obtener_Datos(p_Listar IN tab_Lista) RETURN tab_Pol_Vig_Ant PIPELINED IS
p_ListaDatos r_Pol_Vig_Ant;
BEGIN
IF p_Listar.Count > 0 THEN
FOR x IN p_Listar.First..p_Listar.Last LOOP
p_ListaDatos.NUMPOL := p_Listar(x).NUMPOL;
p_ListaDatos.NUMAVISO := p_Listar(x).NUMAVISO;
p_ListaDatos.FECINIVIG := p_Listar(x).FECINIVIG;
p_ListaDatos.FECFINVIG := p_Listar(x).FECFINVIG;
p_ListaDatos.FECVCT := p_Listar(x).FECVCT;
p_ListaDatos.ORDEN := p_Listar(x).ORDEN;
p_ListaDatos.IDGIRO := p_Listar(x).IDGIRO;
p_ListaDatos.CODMONEDA := p_Listar(x).CODMONEDA;
p_ListaDatos.MTOACREMONEDA := p_Listar(x).MTOACREMONEDA;
p_ListaDatos.STSGIRO := p_Listar(x).STSGIRO;
p_ListaDatos.CODPROD := p_Listar(x).CODPROD;
p_ListaDatos.PENDIENTE := p_Listar(x).PENDIENTE;
p_ListaDatos.TOTAL := p_Listar(x).TOTAL;
p_ListaDatos.COBRADO := p_Listar(x).COBRADO;
p_ListaDatos.FECHAEMISAVISO := p_Listar(x).FECHAEMISAVISO;
p_ListaDatos.CANAL := p_Listar(x).CANAL;
p_ListaDatos.CODINTER := p_Listar(x).CODINTER;
p_ListaDatos.AGENTE := p_Listar(x).AGENTE;
p_ListaDatos.CODPLAN := p_Listar(x).CODPLAN;
p_ListaDatos.NOMPLAN := p_Listar(x).NOMPLAN;
p_ListaDatos.ORIGEN := p_Listar(x).ORIGEN;
p_ListaDatos.VIGENCIA := p_Listar(x).VIGENCIA;
PIPE ROW(p_ListaDatos);
END LOOP;
END IF;
RETURN;
END F_Obtener_Datos;
Error: PLS-00382: expression is of wrong type
Line: 203
Text: FROM table(USRAXVM00.PO_POL_REN_VIG_ANT.F_Obtener_Datos(p_Listar => p_Datos)) t
Error: PLS-00306: wrong number or types of arguments in call to 'F_OBTENER_DATOS'
Line: 203
Text: FROM table(USRAXVM00.PO_POL_REN_VIG_ANT.F_Obtener_Datos(p_Listar => p_Datos)) t
Error: PL/SQL: ORA-00904: "USRAXVM00"."PO_POL_REN_VIG_ANT"."F_OBTENER_DATOS": invalid identifier
Line: 203
Text: FROM table(USRAXVM00.PO_POL_REN_VIG_ANT.F_Obtener_Datos(p_Listar => p_Datos)) t
Error: PL/SQL: SQL Statement ignored
Line: 201
Text: SELECT COUNT(DISTINCT t.VIGENCIA)
Thank you very much with everyone, I hope you can help me.
I am creating trigger when Selisih column is equal to 0, then Status column become 'Partial'. If QtyInternalUse column is equal to QtyRequested, then Status column is Completed, else, it is Not Issued
CREATE OR REPLACE TRIGGER TG_STATUSINREQ
BEFORE UPDATE OR INSERT ON M_INTERNALREQUESTERLINE
FOR EACH ROW
BEGIN
IF (:new.Selisih <> 0 ) THEN
:new.Status := 'Partial';
ELSIF :new.QtyInternalUse := :new.QtyRequested THEN
:new.Status := 'Completed';
ELSE
:new.Status := 'Not Issued';
END IF;
END;
I've tried execute it and there's error that says
PLS-00103: Encountered the symbol "=" when expecting one of the
following:
. ( * # % & = - + < / > at in is mod remainder not rem then
<an exponent (**)> <> or != or ~= >= <= <> and or like like2
like4 likec between || indicator multiset member submultiset
The symbol "* was inserted before "=" to continue.
I've tried deleting : in = but still it won't work. How can I fix this?
REVISION
I have updated the logic and the := . The trigger was created and it's like this :
BEGIN
IF (:new.QtyInternalUse = 0 ) THEN
:new.Status := 'Not Issued';
ELSIF :new.QtyInternalUse = :new.QtyRequested THEN
:new.Status := 'Completed';
ELSE
:new.Status := 'Partial';
END IF;
END;
This should be pretty easy google-resolve. Still here you go.
ELSIF :new.QtyInternalUse := :new.QtyRequested THEN
You are trying to compare but using assignment operator[:=]. Use equals[=] in stead that will resolve your problem.
ELSIF :new.QtyInternalUse = :new.QtyRequested THEN
I am trying to use 'if' condition inside a 'if' condition to create a function.
I know the syntax looks somewhat like below, but I am unable to do it in my code.
IF sales > (quota + 200) THEN
bonus := (sales - quota)/4;
ELSE
IF sales > quota THEN
bonus := 50;
ELSE
bonus := 0;
END IF;
END IF;
Below is the program I am trying to complete. Please help me with it.
Its a function to find phone bill amount wrt given number of calls
and plan Type
CREATE OR REPLACE FUNCTION BILL(NUM_OF_CALLS NUMBER, PLAN_TYPE NUMBER) RETURN NUMBER IS :
BILL_AMT NUMBER;
MIN_1 NUMBER :=150;
MIN_2 NUMBER :=1000;
BEGIN
IF PLAN_TYPE:=150 THEN
IF NUM_OF_CALLS<150 THEN
BILL_AMT:=MIN_1;
ELSIF NUM_OF_CALLS BETWEEN 151 AND 250 THEN
BILL_AMT:=MIN_1+(NUM_OF_CALLS-150);
ELSIF NUM_OF_CALLS BETWEEN 251 AND 400 THEN
BILL_AMT:=MIN_1+(100*1)+(NUM_OF_CALLS-250)*0.5;
ELSIF NUM_OF_CALLS>400 THEN
BILL_AMT:=MIN_1+(100*1)+(150*0.5)+(NUM_OF_CALLS-400)*0.3;
END IF;
ELSE PLAN_TYPE:=500 THEN
IF NUM_OF_CALLS<1000 THEN
BILL_AMT:=MIN_2;
ELSIF NUM_OF_CALLS BETWEEN 1001 AND 1500 THEN
BILL_AMT:=MIN_2+(NUM_OF_CALLS-1000)*0.50;
ELSIF NUM_OF_CALLS>1500 THEN
BILL_AMT:=MIN_2+(500*0.50)+(NUM_OF_CALLS-1500)*0.25;
END IF;
END IF;
RETURN BILL_AMT;
END;
Below are the errors
SQL> show error
Errors for FUNCTION BILL:
LINE/COL ERROR
11/14 PLS-00103: Encountered the symbol "=" when expecting one of the
following:
. ( * # % & = - + < / > at in is mod remainder not rem then
<an exponent (**)> <> or != or ~= >= <= <> and or like like2
like4 likec between || multiset member submultiset
The symbol "* was inserted before "=" to continue.
22/22 PLS-00103: Encountered the symbol "THEN" when expecting one of
the following:
* & = - + ; < / > at in is mod remainder not rem
<an exponent (**)> <> or != or ~= >= <= <> and or like like2
like4 likec between || multiset member submultiset
31/6 PLS-00103: Encountered the symbol "IF" when expecting one of the
following:
; <an identifier> <a double-quoted delimited-identifier>
current delete exists prior <a single-quoted SQL string>
Your answer is directly in the error output.
PLSQL uses := for assignation and = for comparison. You are intermixing these operators and causing these errors.
Read the errors closely, they exactly describe the problem.
Hint: Add small amounts of logic at a time so that you know where your problems originate. Each of us learns this at some point in time :)
Something like this should work for you:
CREATE OR REPLACE
FUNCTION BILL(NUM_OF_CALLS NUMBER, PLAN_TYPE NUMBER)
RETURN NUMBER
IS
BILL_AMT NUMBER;
MIN_1 NUMBER := 150;
MIN_2 NUMBER := 1000;
BEGIN
IF PLAN_TYPE = 150
THEN
IF NUM_OF_CALLS<150
THEN
BILL_AMT:= MIN_1;
ELSIF NUM_OF_CALLS BETWEEN 151 AND 250
THEN
BILL_AMT:=MIN_1+(NUM_OF_CALLS-150);
ELSIF NUM_OF_CALLS BETWEEN 251 AND 400
THEN
BILL_AMT:=MIN_1+(100*1)+(NUM_OF_CALLS-250)*0.5;
ELSIF NUM_OF_CALLS>400
THEN
BILL_AMT:=MIN_1+(100*1)+(150*0.5)+(NUM_OF_CALLS-400)*0.3;
END IF;
ELSIF PLAN_TYPE = 500
THEN
IF NUM_OF_CALLS<1000
THEN
BILL_AMT:=MIN_2;
ELSIF NUM_OF_CALLS BETWEEN 1001 AND 1500 THEN
BILL_AMT:=MIN_2+(NUM_OF_CALLS-1000)*0.50;
ELSIF NUM_OF_CALLS>1500 THEN
BILL_AMT:=MIN_2+(500*0.50)+(NUM_OF_CALLS-1500)*0.25;
END IF;
END IF;
RETURN BILL_AMT;
END BILL;
Hope it helps...
You can't
ELSE PLAN_TYPE:=500 THEN
But you can
ELSIF PLAN_TYPE =500 THEN
If I've got your logic flow figured out
CREATE OR REPLACE FUNCTION BILL(NUM_OF_CALLS NUMBER, PLAN_TYPE NUMBER) RETURN NUMBER IS
BILL_AMT NUMBER;
MIN_1 NUMBER :=150;
MIN_2 NUMBER :=1000;
BEGIN
IF PLAN_TYPE = 150
THEN
IF NUM_OF_CALLS<150 THEN
BILL_AMT :=MIN_1;
ELSIF NUM_OF_CALLS BETWEEN 151 AND 250 THEN
BILL_AMT:=MIN_1+(NUM_OF_CALLS-150);
ELSIF NUM_OF_CALLS BETWEEN 251 AND 400 THEN
BILL_AMT:=MIN_1+(100*1)+(NUM_OF_CALLS-250)*0.5;
ELSIF NUM_OF_CALLS>400 THEN
BILL_AMT:=MIN_1+(100*1)+(150*0.5)+(NUM_OF_CALLS-400)*0.3;
END IF;
ELSIF PLAN_TYPE = 500 THEN
IF NUM_OF_CALLS<1000 THEN
BILL_AMT:=MIN_2;
ELSIF NUM_OF_CALLS BETWEEN 1001 AND 1500 THEN
BILL_AMT:=MIN_2+(NUM_OF_CALLS-1000)*0.50;
ELSIF NUM_OF_CALLS>1500 THEN
BILL_AMT:=MIN_2+(500*0.50)+(NUM_OF_CALLS-1500)*0.25;
END IF;
END IF;
RETURN BILL_AMT;
END;
When attempting to compile I am getting the following errors
Error(16,8): PLS-00103: Encountered the symbol "SPROLLUPEXPENSEITEM"
when expecting one of the following: := . ( # % ; The symbol ":="
was substituted for "SPROLLUPEXPENSEITEM" to continue.
and
Error(17,15): PLS-00103: Encountered the symbol "=" when expecting one
of the following: . ( * # % & = - + < / > at in is mod remainder
not rem then <> or != or ~= >= <= <> and or like
like2 like4 likec between || multiset member submultiset
create or replace
TRIGGER tr_ExpenseItem_Rollup
AFTER DELETE OR UPDATE of ExpApprAmt
ON ExpenseItem
FOR EACH ROW
DECLARE
RollupAmt Number;
BlnResult Boolean;
BEGIN
IF DELETING THEN
RollupAmt := -1 * :Old.ExpApprAmt;
End If;
IF UPDATING Then
RollupAmt := :New.ExpApprAmt - :Old.ExpApprAmt;
End IF;
Call spRollUpExpenseItem(:New.ERNo,:New.ECNo,RollupAmt,BlnResult);
If BlnResult := TRUE
--Additional Logic Here
End IF;
END;
I'm a student and very new at this, so any help would be appreciated.
call isn't a keyword in PL/SQL and to run a stored procedure you just use its name. Remove call from before spRollUpExpenseItem:
create or replace
TRIGGER tr_ExpenseItem_Rollup
AFTER DELETE OR UPDATE of ExpApprAmt
ON ExpenseItem
FOR EACH ROW
DECLARE
RollupAmt Number;
BlnResult Boolean;
BEGIN
IF DELETING THEN
RollupAmt := -1 * :Old.ExpApprAmt;
End If;
IF UPDATING Then
RollupAmt := :New.ExpApprAmt - :Old.ExpApprAmt;
End IF;
spRollUpExpenseItem(:New.ERNo,:New.ECNo,RollupAmt,BlnResult);
If BlnResult = TRUE Then
--Additional Logic Here
End IF;
END;
I believe your problem is in the last if statement. You're missing Then and you're using := which is the assignment operator, you should use = instead.
If BlnResult = TRUE Then
or just
If BlnResult Then