PL/SQL Statement ignored error occurs - oracle

in bellow code PL/SQL Statement ignored error occurs error accurs line is in bold and italic fonts
create or replace
TRIGGER TRGBILLINGADDRESS
AFTER UPDATE ON TBLMACCOUNTADDRESS
FOR EACH ROW
DECLARE
add1 VARCHAR2(100);
add2 VARCHAR2(100);
cityid VARCHAR2(75);
stateid VARCHAR2(75);
pincd VARCHAR2(10);
BEGIN
SELECT address1,address2,city_id,state_id,pincode
INTO add1,add2,cityid,stateid,pincd FROM wom.tbltaddress ta WHERE ta.ID IN (
SELECT vbac.billing_address_id
FROM wom.vw_billaddresschange vbac, wom.tbltaddress ita
WHERE vbac.billing_address_id = ita.ID
AND vbac.lcid = parlcid);
***IF add1 = :NEW.address1 AND add2 = :NEW.address2 AND cityid = :NEW.cityid AND stateid = :NEW.stateid AND pincode = :NEW.zip THEN***
dbms_output.put_line('Address Already Exist in tbltaddress table');
ELSE
UPDATE wom.tbltaddress ta
SET ta.address1 = :NEW.address1,
ta.address2 = :NEW.address2,
***ta.city_id = :NEW.cityid*,**
ta.country_id = 'CTR0001',
ta.state_id = :NEW.stateid,
ta.pincode = :NEW.zip
WHERE ta.ID IN (
SELECT vbac.billing_address_id
FROM wom.vw_billaddresschange vbac, wom.tbltaddress ita
WHERE vbac.billing_address_id = ita.ID
AND vbac.lcid = parlcid);
END IF;
END;

Your variable is declared as pincd, not pincode. pincode is the field in the table.

Related

Using DECLARE in stored procedure for Oracle results in syntax error

create or replace PROCEDURE "SYNC_EMPLOYEES_WITH_HR" (
EMPLOYEE_NUMBER IN NUMBER
) AS
Declare middle_initial varchar(200);
Declare first_initial varchar(200);
Declare last_initial varchar(200);
Declare TERMINATION_DATE Date;
Declare network_Id varchar(200);
BEGIN
select #first_initial = first_name,#middle_initial =middle_initial,#last_initial =last_name, #network_Id = network_id, #TERMINATION_DATE = termination_date from human_resources where employee_number = EMPLOYEE_NUMBER;
update Employee set first_name = #first_initial,middle_initial = #middle_initial,last_name = #last_initial,user_id = #network_Id, inactive_date = #TERMINATION_DATE where employee_number = EMPLOYEE_NUMBER;
END
I do not have access to Oracle PL/SQL so I need to hand the code to the DBA and he tells me there is a syntax error (that's all it said).
I do not see the syntax error. Can anyone help me? I'd appreciate it.
Your procedure is not valid syntax in Oracle as:
DECLARE begins a the variable declaration section of a PL/SQL block (it is not used before each variable);
# is not a valid prefix for variables.
You need to use SELECT value1, value2 INTO variable1, variable2 FROM ... rather than SELECT variable1 = column1, variable2 = column2 FROM ....
where employee_number = EMPLOYEE_NUMBER is like WHERE 1 = 1 as employee_number is taken from the local SQL scope on both sides of the operation rather than having one from the local SQL scope and one from the outer PL/SQL scope; you need to name your PL/SQL variable differently to the column name.
You can simplify it all down to a single MERGE statement:
CREATE PROCEDURE SYNC_EMPLOYEES_WITH_HR (
P_EMPLOYEE_NUMBER IN EMPLOYEE.EMPLOYEE_NUMBER%TYPE
) AS
BEGIN
MERGE INTO Employee dst
USING (
SELECT employee_number,
first_name,
middle_initial,
last_name,
network_id,
termination_date
FROM human_resources
WHERE employee_number = P_EMPLOYEE_NUMBER
) src
ON (dst.employee_number = src.employee_number)
WHEN MATCHED THEN
UPDATE
SET first_name = src.first_name,
middle_initial = src.middle_initial,
last_name = src.last_name,
network_id = src.network_id,
termination_date = src.termination_date;
END;
/
fiddle

Retrieving multiple attributes in SELECT

In PL/SQL function, I am trying to write a function with following code:
CREATE OR REPLACE FUNCTION Lib_func(id number,dateToday date)
RETURN number IS retVal number(1);
myBorrower number;
myBook number;
BEGIN
SELECT P.book_id INTO myBook, P.request_id INTO myBorrower
FROM My_requests P
WHERE P.book_id = book_id AND ROWNUM <=1;
//some if condition which updates value of retVal
RETURN retVal;
END;
/
problem is that this results in error when I compile. If I remove the second thing (i.e. P.request_id INTO myBorrower) then error is removed.
Can I not get both things selected in a single query ?
The syntax for selecting multiple variables is :
SELECT P.book_id , P.request_id
INTO myBook,myBorrower
FROM My_requests P
WHERE P.book_id = book_id AND ROWNUM <=1;

How to return a table of records from a PLSQL function?

I have a function which is having three different queries. First query is returning a single record in a plsql record type.Second query is returning another single value and third is also returning a different single value. Now I want to append first record with those two values and return a table of that new record from my function. How can I achieve that.
create or replace function test(p_actBillDat date) return <what should I return> as
type tab_accountNum is table of account.account_num%type;
var_accountNum tab_accountNum;
type query1Record is record(
accountNum account.account_num%type,
customerRef customer.customer_ref%type,
internalCreditScore CUSTOMERATTRIBUTES.Internal_Credit_Score%type);
var_query1Rec query1Record;
var_nsfDat date;
var_writeOffdat date;
cursor cur_accountNum is
select ACCOUNT_NUM
from BILLSUMMARY
where trunc(ACTUAL_BILL_DTM) = p_actBillDat
and CANCELLATION_REQUEST_DAT is null;
begin
open cur_accountNum;
Loop
fetch cur_accountNum bulk collect
into var_accountNum limit 100;
close cur_accountNum;
for i in 1 .. var_accountNum.count
loop
select A.ACCOUNT_NUM, A.CUSTOMER_REF, CA.INTERNAL_CREDIT_SCORE
into var_query1Rec
from ACCOUNT A, CUSTOMERATTRIBUTES CA, CONTACTDETAILS CD, CONTACT CNT
where A.ACCOUNT_NUM = var_accountNum(i) and
A.CUSTOMER_REF = CA.CUSTOMER_REF(+) and
A.CUSTOMER_REF = CD.CUSTOMER_REF and
CNT.CUSTOMER_REF = A.CUSTOMER_REF and
CD.CONTACT_SEQ = CNT.CONTACT_SEQ and
CD.CONTACT_SEQ = 1 and
CD.START_DAT = (select min(CNTD.START_DAT)
from CONTACTDETAILS CNTD
where CNTD.CONTACT_SEQ = CD.CONTACT_SEQ and
CNTD.CUSTOMER_REF = A.CUSTOMER_REF);
select max(AP.ACCOUNT_PAYMENT_DAT) into var_writeOffdat
from ACCOUNT A, ACCOUNTPAYMENT AP
where A.ACCOUNT_NUM = AP.ACCOUNT_NUM and
A.ACCOUNT_NUM = var_accountNum(i) AND
A.TOTAL_WRITEOFF_TOT <> 0 and
(AP.PAYMENT_ORIGIN_ID = 2 or AP.PAYMENT_ORIGIN_ID = 3) and
AP.CANCELLED_DTM is null and
AP.FAILED_DTM is null;
select max(PP.FAILED_DTM) into var_nsfDat
from ACCOUNTPAYMENT AP, PHYSICALPAYMENT PP
where AP.ACCOUNT_NUM = var_accountNum(i) and
AP.ACCOUNT_PAYMENT_STATUS = 3 and
AP.PHYSICAL_PAYMENT_SEQ = PP.PHYSICAL_PAYMENT_SEQ and
AP.CUSTOMER_REF = PP.CUSTOMER_REF and
PP.PHYSICAL_PAYMENT_STATUS = 3 and
PP.FAILURE_CODE_ID in (select PFC.FAILURE_CODE
from CGPAYMENTFAILURECONFIG PFC
where PFC.FAILURE_TYPE = 'Decline NSF') ;
<how to appned var_query1Rec with var_writeOffdat and var_writeOffdat>
<how to make a PLSQl table of that record and return from function>
end loop;
end loop;
end;
If this function is not part of a package - why wouldn't it be? then you have no other choice but to declare a SQL Object type like this example:
CREATE TYPE person_typ AS OBJECT (
idno NUMBER,
first_name VARCHAR2(20)
);
Declare the variables at the top of your function to access the type created.
type t_arr is table of person_typ ;
l_arr t_arr := t_arr();
Then assign them in your code:
l_arr.extend;
l_arr(i).idno := xxx;
l_arr(i).first_name := yyyy;
The create function returns the object:
create or replace function test(p_actBillDat date) return person_typ as
.....
return(l_arr);
end;
But I would have this function in a package then in the package body header or spec you could do this:
type t_rec is
record(x number
,y varchar2(100)
);
type t_tbl is table of t_rec index by binary_integer;
Then declare in your function:
l_tbl t_tbl;
Then assign them in the function:
l_tbl(i).x := xxx;
l_tbl(i).y := yyy;
And finally just return the type in your function like this:
create or replace function test(p_actBillDat date) return t_tbl as
......
l_tbl t_tbl;
begin
.......
for i in 1..counter loop
.. SQL statements
l_tbl(i).x := xxx;
l_tbl(i).y := yyy;
end loop;
return l_tbl;
end;

pls 00905 object is invalid

create or replace procedure p_update_project_status(v_project_id in number(10)) is
declare
v_bid_file_status number(2);
v_bid_form_status number(2);
v_supplier_status number(2);
begin
select status into v_bid_file_status from PROJECT_FILE where type = 0 and associated_project_id = v_project_id;
select status into v_bid_form_status from PROJECT_FILE where type = 1 and associated_project_id = v_project_id;
select status into v_supplier_status from SUPPLIER_INFO where associated_project_id = v_project_id;
if( (v_bid_file_status = 3) and (v_bid_form_status = 3) and (v_supplier_status = 3) ) then
update PROJECT_INFO set status = 3 where id = v_project_id;
else
update PROJECT_INFO set status = 0 where id = v_project_id;
end if;
end;
I execute the procedure,but it's invalid, I have tried my best to correct it, but still invalid.I don't know where is going wrong.Please help me
DECLARE keyword is not necessary here. You need it only if youre running an anonymous block. Remove that and it should compile.

Query in Procedure PLSQL must return 1 row, but return more rows

I have a strange problem implementing pl/sql procedure.
My procedure has four varchar input parameter, and extracts from a table an id value with a query like this:
SELECT ID INTO idvar FROM TABLE T WHERE T.NAME = pn AND T.SUR = ln;
In this table, name and sur are unique key. So for a couple of input parameter (pn,ln), I expect to obtain only one row, but isn't so.
Indeed, it seems that only the first condition processed, and the second doesn't.
In my table I have, this test row:
ID | NAME | SUR
1 | JO | SOME THING
2 | JO | OTHER ONE
3 | BO | SOME THING
If in my procedure I pass
('JO', 'SOME THING')
I obtain ID: 1 and 2.
But if I pass values
('BO', 'SOME THING')
i obtain only ID 3.
Clearly, with previous query I obtained error ORA-01422, so I substitute it with a cursor definition first, and a "for row in (query) " later:
CURSOR C IS
SELECT ID FROM TABLE T WHERE T.NAME = pn AND T.SUR = ln;
This behavior is strange for me, in fact if I exec only query from sqlplus or toad, i obtain correct result.
Oracle version is 8.1.
Thanks in advance
#
This is my procedure (I Hope you don't find mismatch, because I changed name of objects):
CREATE OR REPLACE PROCEDURE myproc (
pn in VARCHAR2,
ln in VARCHAR2,
other in VARCHAR2,
datarif in VARCHAR2
)
AS
idT NUMBER;
idST NUMBER;
idSE NUMBER;
CURSOR C IS
SELECT ID
FROM TABLE T
WHERE
T.NAME = pn AND T.SUR = ln;
BEGIN
for x in ( SELECT ID
FROM TABLE T
WHERE
T.NAME = pn AND T.SUR = ln )
loop
DBMS_OUTPUT.put_line('INFOR:' || x.ID);
end loop;
open C;
loop
fetch C into idT;
exit when C%NOTFOUND;
DBMS_OUTPUT.put_line('INLOOP:ID='||idT);
end loop;
close C;
DBMS_OUTPUT.put_line ( 'OUTLOOP: ID='||idT );
EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL;
WHEN TOO_MANY_ROWS THEN
RAISE_APPLICATION_ERROR(-20001, 'Exact Fetch Returned many Rows');
WHEN OTHERS THEN
DBMS_OUTPUT.put_line('ERROR');
ROLLBACK;
RAISE;
END myproc;
/
Thank you
Maybe there's a clash between your parameters and fields of the table?
Change it by adding the name of your procedure as scope for your parameters:
T.NAME = myproc.pn AND T.SUR = myproc.ln
"... because I changed name of objects"
Maybe some of your parameters have the same names as some columns.
For example if your procedure looked like this:
CREATE OR REPLACE PROCEDURE myproc (
pn in VARCHAR2,
sur in VARCHAR2,
other in VARCHAR2,
datarif in VARCHAR2
)
...
SELECT ID INTO idvar FROM TABLE T WHERE T.NAME = pn AND T.SUR = sur;
...
you would get TOO_MANY_ROWS error because the condition "T.SUR = sur" would have the same effect as "T.SUR = T.SUR".
I tested your first statement with your example table! And on my machine it works. But that is an Oracle 10g database.
Edit:
I re-writed your procedure and on my machine that version works well!
create or replace
PROCEDURE myproc (
pn in VARCHAR2,
ln in VARCHAR2,
other in VARCHAR2,
datarif in VARCHAR2
)
AS
idvar NUMBER;
BEGIN
SELECT ID INTO idvar FROM TEST T WHERE T.NAME = pn AND T.SUR = ln;
DBMS_OUTPUT.put_line ( 'OUTLOOP: ID='||idvar );
END myproc;

Resources