Reference to Unintialized collection exception using array PLSQL - sql

I am getting reference to uninitialized collection exception when trying to add element to an array. Please help.Is that correct way to initialize the array as mentioned in my calling code?
CREATE OR REPLACE TYPE SCHEMA.STRARRAY AS TABLE OF VARCHAR2 (255);
CREATE OR REPLACE PROCEDURE SCHEMA.PR_VALIDATE
(
FILEARRAY IN STRARRAY,
DUPARRAY OUT STRARRAY)
IS
dupCount NUMBER;
fileName VARCHAR2 (50);
fileId NUMBER;
dupfileName VARCHAR2(50);
BEGIN
for i in 1 .. FILEARRAY.count
loop
fileName := FILEARRAY(i);
SELECT COUNT (T.FILEID), T.FILEID INTO dupCount,fileId FROM TB_COMPANY T, TB_COMPANY S
WHERE T.FILEID=S.FILEID
AND T.RPDT_ORI_FLE_NM = fileName AND T.RPDT_STA_CD IN ('PASS', 'FAIL')
GROUP BY T.FILEID;
IF dupCount>1
THEN
SELECT RPDT_ORI_FLE_NM INTO dupfileName FROM TB_RDTE_COMPANY_HDR_DT
WHERE RPDT_STA_CD IN ('PR15','PR16') AND RPDT_FLE_ID=fileId
AND RPDT_ORI_FLE_NM != fileName;
DBMS_OUTPUT.PUT_LINE(dupfileName);
DUPARRAY(DUPARRAY.LAST +1 ) :=dupfileName; --Here is the exception.
END IF;
end loop;
EXCEPTION
WHEN OTHERS THEN
PR_RDTE_ERRORS('PR_VALIDATE', SQLERRM);
ROLLBACK;
END;
/
Calling code:
DECLARE
DUPARRAY STRARRAY:=STRARRAY();
BEGIN
PR_VALIDATE (STRARRAY('abc.txt'),DUPARRAY);
END;

DUPARRAY.LAST will get the index of the last element of the array (and not the index of the last non-NULL value of the array) - so if you use DUPARRAY.LAST + 1 you will always exceed the array bounds.
Also, you have not extended the array - which you need to do to add an extra element.
You need to do:
DUPARRAY.EXTEND;
DUPARRAY(DUPARRAY.LAST) :=dupfileName;
You also need to initialise the DUPARRRY inside the procedure (instead of in the calling code):
So something like this:
CREATE OR REPLACE PROCEDURE PR_VALIDATE
(
FILEARRAY IN STRARRAY,
DUPARRAY OUT STRARRAY
)
IS
dupCount NUMBER;
fileName VARCHAR2 (50);
dupfileName VARCHAR2(50);
fileId NUMBER;
BEGIN
DUPARRAY := STRARRAY();
for i in 1 .. FILEARRAY.count loop
fileName := FILEARRAY(i);
SELECT COUNT (T.FILEID), T.FILEID
INTO dupCount,fileId
FROM TB_COMPANY T
INNER JOIN TB_COMPANY S
ON T.FILEID=S.FILEID
WHERE T.RPDT_ORI_FLE_NM = fileName
AND T.RPDT_STA_CD IN ('PASS', 'FAIL')
GROUP BY T.FILEID;
IF dupCount>1 THEN
SELECT RPDT_ORI_FLE_NM
INTO dupfileName
FROM TB_RDTE_COMPANY_HDR_DT
WHERE RPDT_STA_CD IN ('PR15','PR16')
AND RPDT_FLE_ID=fileId
AND RPDT_ORI_FLE_NM != fileName;
DBMS_OUTPUT.PUT_LINE(dupfileName);
DUPARRAY.EXTEND;
DUPARRAY(DUPARRAY.LAST) :=dupfileName;
END IF;
end loop;
END;
/
Then call it:
DECLARE
DUPARRAY STRARRAY;
BEGIN
PR_VALIDATE(STRARRAY('abc.txt'),DUPARRAY);
END;
/

Related

PL-SQL: returning error - inserting elements into (user input) index with shifting all the elements to element[i+1]

TYPE arr is VARRAY(10) of VARCHAR(32);
ar arr := arr('1', '1', '1');
idx INTEGER(100);
tmp INTEGER(100);
val VARCHAR(32);
PROCEDURE APPENDARR (arr IN OUT arr, idx IN, val IN) IS
BEGIN
if(idx > arr.LIMIT) then
tmp := (idx - arr.LIMIT);
arr.extend(tmp);
FOR i in REVERSE idx..arr.LAST LOOP
arr(i) := arr(i - 1);
if(arr(i) = arr(idx)) THEN
arr(i) := val;
END IF;
END LOOP;
ELSE
arr.extend();
arr(idx) := val;
END IF;
END;
error code:
ORA-06550: line 10, column 48:
PLS-00103: Encountered the symbol "," when expecting one of the following:
out
long double ref char time timestamp interval date binary
national character nchar
anyone who can help me with my error? sorry english is not my native language but i try my best :)!
I'm guessing this is part of a package, as otherwise you would need the create or replace syntax. For demo purposes, I put it in an anonymous block just to test compilation.
Two issues:
integer doesn't take a precision, it's just integer.
The idx and val parameters are missing datatypes.
The following compiles (I haven't checked what it does or whether there is any better implementation):
declare
type arr is varray(10) of varchar(32);
ar arr := arr('1', '1', '1');
idx integer;
tmp integer;
val varchar(32);
procedure appendarr
( arr in out arr
, idx in integer
, val in varchar2 )
is
begin
if idx > arr.limit then
tmp := idx - arr.limit;
arr.extend(tmp);
for i in reverse idx .. arr.last loop
arr(i) := arr(i - 1);
if arr(i) = arr(idx) then
arr(i) := val;
end if;
end loop;
else
arr.extend();
arr(idx) := val;
end if;
end;
begin
null;
end;
PL/SQL if conditions are terminated by the then keyword so they don't need brackets as in other languages, so I removed them.
Also, you have variables idx, tmp and val declared at the top which are not used anywhere, and which also have the same names as local variables within the procedure, which could be confusing. If there isn't some more code you haven't shown that uses them, maybe you can get rid of them.
Edit: As requested, here is what it would look like as a standalone procedure:
create or replace type arr as varray(10) of varchar(32)
/
create or replace procedure appendarr
( arr in out arr
, idx in integer
, val in varchar2 )
as
tmp integer;
begin
if idx > arr.limit then
tmp := idx - arr.limit;
arr.extend(tmp);
for i in reverse idx .. arr.last loop
arr(i) := arr(i - 1);
if arr(i) = arr(idx) then
arr(i) := val;
end if;
end loop;
else
arr.extend();
arr(idx) := val;
end if;
end appendarr;
/
(The / character is required by some development tools to separate blocks, but is not part of the PL/SQL language itself.)
It seems the aim is to insert value val into element idx of array arr, shifting existing values up one place. However, it doesn't quite work:
declare
ar arr := arr('First', 'Second');
begin
appendarr
( arr => ar
, idx => 2
, val => 'New value' );
for i in ar.first..ar.last loop
dbms_output.put_line(i||' '||ar(i));
end loop;
end;
1 First
2 New value
3
Fixed version:
create or replace type varchar2_tt as table of varchar2(50)
/
create or replace procedure varchar2_tt_append
( arr in out varchar2_tt
, pos in pls_integer default null
, val in varchar2 )
as
idx pls_integer := nvl(pos,arr.last +1);
begin
if idx > arr.last then
arr.extend(idx - arr.last);
else
arr.extend();
for i in reverse greatest(idx,2)..arr.last loop
arr(i) := arr(i - 1);
end loop;
end if;
arr(idx) := val;
end varchar2_tt_append;
/
Test:
declare
ar varchar2_tt := varchar2_tt('First', 'Second', 'Third', 'Fourth');
begin
varchar2_tt_append
( arr => ar
, pos => 1
, val => 'New value' );
for i in ar.first..ar.last loop
dbms_output.put_line(i||' '||ar(i));
end loop;
end;
1 New value
2 First
3 Second
4 Third
5 Fourth

how to update a blob column containing XML data in oracle

i have tried below two approaches:
update table set blobcolname='<?xml>...';
got this error: "string literal tool long" - since the xml value that i am inserting is tool long
2.
DECLARE
str varchar2(32767);
BEGIN
str:='<?xml>...';
update table set blobcolname = str;
END;
/
got this error: ORA-01461:can bind a LONG value only for insert into a LONG column
If you have an option to install two functions in your database, I would use this:
First: I create a function to convert a clob to a blob object
create or replace function clob_to_blob (p1_clob CLOB) return BLOB is
Result BLOB;
o1 integer;
o2 integer;
c integer;
w integer;
begin
o1 := 1;
o2 := 1;
c := 0;
w := 0;
DBMS_LOB.CreateTemporary(Result, true);
DBMS_LOB.ConvertToBlob(Result, p1_clob, length(p1_clob), o1, o2, 0, c, w);
return(Result);
end clob2blob;
/
Second: I create a function to the opposite, convert a blob to a clob
create or replace function blob_to_char (p1_blob BLOB)
return clob is
out_clob clob;
n number;
begin
if (p1_blob is null) then
return null;
end if;
if (length(p1_blob)=0) then
return empty_clob();
end if;
dbms_lob.createtemporary(out_clob,true);
n:=1;
while (n+32767<=length(p1_blob)) loop
dbms_lob.writeappend(out_clob,32767,utl_raw.cast_to_varchar2(dbms_lob.substr(p1_blob,32767,n)));
n:=n+32767;
end loop;
dbms_lob.writeappend(out_clob,length(p1_blob)-n+1,utl_raw.cast_to_varchar2(dbms_lob.substr(p1_blob,length(p1_blob)-n+1,n)));
return out_clob;
end;
/
Third: To verify that I can insert
declare
str clob;
BEGIN
str :='<?xml>...';
update table set blobcolname = clob_to_blob ( str );
END;
/
Lastly: To make a regression test and check that I got the xml as it was originally
select blob_to_char( blobcolname ) from your table;

PLSQL DML statements inside procedure

I am trying to execute below procedure but it says me to use BULKCOLLECT and FORALL to refactor my code. Is it just a warning or should i not use like below for my procedure. If so, how should i modify the code as i am iterating through an array and i need each value to update into table.
CREATE OR REPLACE PROCEDURE SCHEMA.PR_VALIDATE
(
FILEARRAY IN STRARRAY,
DUPARRAY OUT STRARRAY,
PASSARRAY OUT STRARRAY,
FAILARRAY OUT STRARRAY,
MISSARRAY OUT STRARRAY
)
IS
dupCount NUMBER;
staCode VARCHAR2 (10);
fileName VARCHAR2 (50);
dupfileName VARCHAR2(50);
fileId NUMBER;
ID VARCHAR2(20);
BEGIN
for i in 1 .. FILEARRAY.count
loop
fileName := FILEARRAY(i);
SELECT COUNT (T.FILEID), T.FILEID,T.STATUS,T.ID INTO dupCount,fileId,staCode,ID FROM TB_TABLE_NAME T, TB_TABLE_NAME S
WHERE T.FILEID=S.FILEID
AND T.STATUS=S.STATUS
AND T.FILENAME = fileName AND T.STATUS IN ('PASS', 'FAIL)
GROUP BY T.FILEID,T.STATUS,T.ID;
IF dupCount>1
THEN
SELECT FILENAME INTO dupfileName FROM TB_TABLE_1
WHERE STATUS IN ('PASS','FAIL') AND FILEID=fileId
AND FILENAME != fileName;
DBMS_OUTPUT.PUT_LINE(dupfileName);
UPDATE TB_TABLE_1 SET STATUS='DUP' WHERE FILENAME=dupfileName;
DUPARRAY(DUPARRAY.LAST +1 ) :=dupfileName;
DBMS_OUTPUT.PUT_LINE(dupfileName);
END IF;
IF staCode = 'FAIL'
THEN
FAILARRAY(FAILARRAY.LAST+1) :=fileName;
ELSIF staCode = 'PASS'
THEN
PASSARRAY(PASSARRAY.LAST+1) :=fileName;
END IF;
end loop;
EXCEPTION
WHEN NO_DATA_FOUND THEN
staCode :=NULL;
MISSARRAY(MISSARRAY.LAST +1 ) :=fileName;
WHEN OTHERS THEN
PR_ERRORS('PR_VALIDATE', SQLERRM);
ROLLBACK;
END;
/
As I mentioned in the comment FORALL here is out of context as business logic is incorporated here but again you can try BULK COLLECT with FOR loop to iterate. But data volume is not that large you can still go with the row-by-row approach. Hope below snippet helps. Also there were some single quotes missing which would have given compile time error.
CREATE OR REPLACE PROCEDURE SCHEMA.PR_VALIDATE(
FILEARRAY IN STRARRAY,
DUPARRAY OUT STRARRAY,
PASSARRAY OUT STRARRAY,
FAILARRAY OUT STRARRAY,
MISSARRAY OUT STRARRAY )
IS
dupCount NUMBER;
staCode VARCHAR2 (10);
fileName VARCHAR2 (50);
dupfileName VARCHAR2(50);
fileId NUMBER;
ID VARCHAR2(20);
BEGIN
FOR i IN 1 .. FILEARRAY.count
LOOP
fileName := FILEARRAY(i);
SELECT COUNT (T.FILEID),
T.FILEID,
T.STATUS,
T.ID
INTO dupCount,
fileId,
staCode,
ID
FROM TB_TABLE_NAME T,
TB_TABLE_NAME S
WHERE T.FILEID =S.FILEID
AND T.STATUS =S.STATUS
AND T.FILENAME = fileName
AND T.STATUS IN ('PASS', 'FAIL')
GROUP BY T.FILEID,
T.STATUS,
T.ID;
IF dupCount>1 THEN
SELECT FILENAME
INTO dupfileName
FROM TB_TABLE_1
WHERE STATUS IN ('PASS','FAIL')
AND FILEID =fileId
AND FILENAME != fileName;
DBMS_OUTPUT.PUT_LINE(dupfileName);
UPDATE TB_TABLE_1
SET STATUS='DUP'
WHERE FILENAME=dupfileName;
DUPARRAY(DUPARRAY.LAST +1 ) :=dupfileName;
DBMS_OUTPUT.PUT_LINE(dupfileName);
END IF;
IF staCode = 'FAIL' THEN
FAILARRAY(FAILARRAY.LAST+1) :=fileName;
ELSIF staCode = 'PASS' THEN
PASSARRAY(PASSARRAY.LAST+1) :=fileName;
END IF;
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
staCode :=NULL;
MISSARRAY(MISSARRAY.LAST +1 ) :=fileName;
WHEN OTHERS THEN
PR_ERRORS('PR_VALIDATE', SQLERRM);
ROLLBACK;
END;

PL sql to find a string in a list

I have a problem because in this code I don't know how I can to test if a string is in a list which isn't initialized .
The code is this :
TYPE t1 IS TABLE OF VARCHAR2(32767) index by PLS_INTEGER;
v_t1 t1;
WOUT varchar2(80) :='bbbb';
v_t1(1):='bbbb';
if (WOUT member of v_t1 ) then
....
end if;
I don't know how i can write in plsql the condition that wout is inside v_t1 because member is accepted only with lists initialized.
Thanks for the help
With the collection declared as you have it there's no simple way to do what you're trying to do except to iterate through the collection to find the element you want:
declare
TYPE t1 IS TABLE OF VARCHAR2(32767)
index by PLS_INTEGER;
v_t1 t1;
WOUT VARCHAR2(80) := 'zzzz';
i NUMBER;
bFound BOOLEAN := FALSE;
BEGIN
v_t1(0) := 'aaaa';
v_t1(1) := 'bbbb';
v_t1(2) := 'cccc';
v_t1(26) := 'zzzz';
i := v_t1.FIRST;
LOOP
DBMS_OUTPUT.PUT_LINE('i=' || i);
IF v_t1(i) = WOUT THEN
bFound := TRUE;
EXIT;
END IF;
i := v_t1.NEXT(i);
IF i IS NULL THEN
EXIT;
END IF;
END LOOP;
DBMS_OUTPUT.PUT_LINE('bFound=' || CASE WHEN bFOUND THEN 'TRUE' ELSE 'FALSE' END);
end;
HOWEVER - if you change the collection so that it's indexed by the string it contains you can accomplish this task a bit easier by using the EXISTS collection method:
declare
TYPE T2 IS TABLE OF VARCHAR2(32767)
INDEX BY VARCHAR2(32767);
v_t2 t2;
WOUT VARCHAR2(80) := 'zzzz';
i NUMBER;
bFound BOOLEAN;
BEGIN
v_t2('aaaa') := 'aaaa';
v_t2('bbbb') := 'bbbb';
v_t2('cccc') := 'cccc';
v_t2('zzzz') := 'zzzz';
bFound := v_t2.EXISTS(WOUT);
DBMS_OUTPUT.PUT_LINE('bFound=' || CASE WHEN bFOUND THEN 'TRUE' ELSE 'FALSE' END);
END;
The documentation on collection methods can be found here.
Share and enjoy.
You can create special function that checks if such value is inside collection. Something like that:
FUNCTION exist_in_collection( p_table t1, p_text VARCHAR2) RETURN boolean
IS
BEGIN
IF p_table.LAST IS NULL THEN
RETURN FALSE;
ELSE
FOR i IN p_table.FIRST.. p_table.LAST
LOOP
IF p_table(i) = p_text THEN
RETURN TRUE;
END IF;
END LOOP;
RETURN FALSE;
END IF;
END exist_in_collection;
if p_table is not initialized LAST is NULL you will get FALSE. And then you can use this function to check whether the string is inside collection:
IF exist_in_collection(p_table, WOUT) THEN ... END IF;

ORA-06550: line 1, column 7 (PL/SQL: Statement ignored) Error

I am getting following error for the stored procedure and not able to understand the issue (must be from db side) While googling, I found similar issues but couldn't get the solution. Can any one help me please find the error in PROCEDURE ??
Error :-
18:58:50,281 ERROR [STDERR] java.sql.SQLException: ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'SP_DIST_RETAILER_REMAP'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
Stored Prodedure(SP_DIST_RETAILER_REMAP) :-
CREATE OR REPLACE PROCEDURE SMAPRD02.SP_DIST_RETAILER_REMAP (
i_old_dist_code IN VARCHAR2,
i_new_dist_code IN VARCHAR2,
i_territory_remapping IN NUMBER,
i_remapping_reason IN VARCHAR2,
i_trans_doneby_rolename IN VARCHAR2,
i_trans_doneby_id IN NUMBER,
i_trans_dist_rolename IN VARCHAR2,
i_trans_ret_rolename IN VARCHAR2,
i_activity_type IN VARCHAR2,
i_ret_list IN V_ARRAY,
result OUT VARCHAR2,
i_o_query OUT VARCHAR2
)
AS
--i_ret_codes OUT VARCHAR2;
v_dist_count NUMBER;
v_ret_count NUMBER;
v_ret_codes VARCHAR2(10000) := '';
v_flag VARCHAR2(10) := 'true';
v_trans_id NUMBER;
v_query VARCHAR2(10000);
BEGIN
IF i_territory_remapping = 1 then
SELECT count(*) into v_dist_count FROM tblemployee where EMPCODE = i_new_dist_code and circle_code = (select emp.circle_code
from tblemployee emp where emp.empcode = i_old_dist_code) and upper(user_type) like upper('%dist%') and upper(ACCESS_TO) in ('SALES','BOTH') and upper(stage) not in (upper('InActive'));
ELSE
SELECT count(*) into v_dist_count FROM tblemployee where EMPCODE = i_new_dist_code and circle_code = (select emp.circle_code from tblemployee emp
where emp.empcode = i_old_dist_code) and cluster_code = (select emp.cluster_code from tblemployee emp where emp.empcode = i_old_dist_code)
and upper(user_type) like upper('%dist%') and upper(ACCESS_TO) in ('SALES','BOTH') and upper(stage) not in (upper('InActive'));
END IF;
IF v_dist_count =0 THEN
result := 'invalid_new_dist_code';
v_flag := 'false';
ELSIF v_dist_count = 1 THEN
SELECT count(*) into v_ret_count FROM tblretailer t where t.DIST_CODE = i_old_dist_code and (upper(t.ACCESS_TO) = 'SALES' or upper(t.ACCESS_TO) = 'BOTH');
--SELECT count(*) into v_ret_count FROM tblretailer t where t.DIST_CODE = i_old_dist_code and upper(t.ACCESS_TO) = 'SALES' and upper(t.stage) in ('APPROVED','INACTIVE');
IF v_ret_count=i_ret_list.count THEN
IF i_territory_remapping = 1 THEN
result := 'no_ret_left';
v_flag := 'false';
END IF;
ELSE
IF i_territory_remapping != 1 THEN
result := 'ret_left';
v_flag := 'false';
END IF;
END IF;
END IF;
IF i_ret_list is null or i_ret_list.count = 0 THEN
result := 'empty retailers list';
v_flag := 'false';
END IF;
/*FOR i IN i_ret_list.FIRST .. i_ret_list.LAST
LOOP
IF v_ret_codes is null
THEN
v_ret_codes := ''''||i_ret_list(i)||'''';
ELSE
v_ret_codes := v_ret_codes||','''||i_ret_list(i)||'''';
END IF;
IF v_ret_codes is null
THEN
v_ret_codes := i_ret_list(i);
ELSE
v_ret_codes := v_ret_codes||','||i_ret_list(i);
END IF;
END LOOP;
i_ret_codes := v_ret_codes;
v_flag := 'false';
result := 'success';*/
IF v_flag = 'true' THEN
FOR i IN i_ret_list.FIRST .. i_ret_list.LAST
LOOP
IF v_ret_codes is null
THEN
v_ret_codes := ''''||i_ret_list(i)||'''';
ELSE
v_ret_codes := v_ret_codes||','''||i_ret_list(i)||'''';
END IF;
END LOOP;
--i_ret_codes := v_ret_codes;
--update tblretailer set dist_code=i_new_dist_code,DIST_ID=to_number(i_new_dist_code),cluster_code=(select cluster_code from tblemployee where empcode = i_new_dist_code),FOSID='',FOS_CODE='',DSR_ID='',DSR_CODE='',LAST_UPDATED_DATE=sysdate where retcode in (v_ret_codes);
v_query := 'update tblretailer set dist_code='||i_new_dist_code||',DIST_ID=to_number('||i_new_dist_code||'),cluster_code=(select cluster_code from tblemployee where empcode = '||i_new_dist_code||'),FOSID='''',FOS_CODE='''',DSR_ID='''',DSR_CODE='''',LAST_UPDATED_DATE=sysdate where retcode in ('||v_ret_codes||')';
execute immediate (v_query);
--i_query :='update tblretailer set dist_code='||i_new_dist_code||',DIST_ID=to_number('||i_new_dist_code||'),cluster_code=(select cluster_code from tblemployee where empcode = '||i_new_dist_code||'),FOSID='',FOS_CODE='',DSR_ID='',DSR_CODE='',LAST_UPDATED_DATE=sysdate where retcode in ('||v_ret_codes||');';
insert into TBL_TRANSFER_SUP_MASTER(MASTER_ID,TRANS_ID,TRANS_DONEBY_ROLENAME,TRANS_DONEBY_ID,TRANS_FROM_ROLENAME,TRANS_FROM,TRANS_TO_ROLENAME,TRANS_TO,ACTIVITY_CODE,TRANS_DATE,TRANSFER_REASON,LAST_UPDATED_DATE)
values(SUP_MASTER_TRANS_ID_SEQ.nextval,SUP_MASTER_TRANS_ID_SEQ.nextval,i_trans_doneby_rolename,i_trans_doneby_id,i_trans_dist_rolename,i_old_dist_code,i_trans_dist_rolename,i_new_dist_code,'101',sysdate,i_remapping_reason,sysdate) return TRANS_ID into v_trans_id;
FOR i IN i_ret_list.FIRST .. i_ret_list.LAST
LOOP
insert into TBL_TRANSFER_SUP_DTLS(DTLS_ID,TRANS_ID,TRANS_ON_ROLENAME,TRANS_ON_ID,LAST_UPDATED_DATE)
values(SUP_DTLS_ID_SEQ.nextval,v_trans_id,i_trans_ret_rolename,i_ret_list(i),sysdate);
END LOOP;
IF SQL%ROWCOUNT>0 THEN
result := 'success';
ELSE
result := 'failure';
END IF;
--update tblstock set NEW_DIST_CODE_REMAP=i_new_dist_code,REMAP_DATE=sysdate,LAST_UPDATED_DATE=sysdate where (DIST_CODE=i_old_dist_code or NEW_DIST_CODE_REMAP=i_old_dist_code) and RET_CODE in (v_ret_codes);
v_query := 'update tblstock set NEW_DIST_CODE_REMAP='||i_new_dist_code||',REMAP_DATE=sysdate,LAST_UPDATED_DATE=sysdate where (DIST_CODE='||i_old_dist_code||' or NEW_DIST_CODE_REMAP='||i_old_dist_code||') and RET_CODE in ('||v_ret_codes||')';
execute immediate (v_query);
i_o_query := v_query;
insert all into TBL_ACTIVITY_LOG (LOG_ID,TRANS_ID,ACTIVITY_DONEBY_ROLENAME,ACTIVITY_DONEBY_ID,ACTIVITY_REFERENCE_ID,ACTIVITY_CODE,ACTIVITY_DATE)
values(ACTIVITY_LOG_TRANS_ID_SEQ.NEXTVAL,ACTIVITY_LOG_TRANS_ID_SEQ.NEXTVAL,i_trans_doneby_rolename,i_trans_doneby_id,v_trans_id,
act_code,sysdate) select log_config.ACTIVITY_CODE act_code from TBL_ACTIVITY_LOG_CONFIG log_config
where upper(log_config.ACTIVITY_TYPE)= upper(i_activity_type);
END IF;
END;
/
Java Code :-
try{
if(ret_list.size()>0)
ret_code = ret_list.toArray();
con = ConnectionManager.getDirectConnection();
ArrayDescriptor descriptor = ArrayDescriptor.createDescriptor(PropertyLoader.RET_SECONDARY_V_ARRAY,con);
ARRAY array_to_pass = new ARRAY( descriptor,con, ret_code );
cstmt = con.prepareCall("{ call SP_DIST_RETAILER_REMAP(?,?,?,?,?,?,?,?,?,?,?,?)}");
cstmt.setString(1,old_dist_code.trim());
cstmt.setString(2,new_dist_code.trim());
if(territory_remapping)
cstmt.setInt(3,1);
else
cstmt.setInt(3,2);
cstmt.setString(4,remapping_reason);
cstmt.setString(5,userVO.getRolename().trim());
cstmt.setInt(6,userVO.getEmpid());
cstmt.setString(7,PropertyLoader.DISTRIBUOTR_ROLENAME);
cstmt.setString(8,PropertyLoader.RETAILER_ROLENAME);
cstmt.setString(9,PropertyLoader.ACTIVITY_TYPES_RETAILER_REMAPPING);
cstmt.setArray(10,array_to_pass);
cstmt.registerOutParameter(11,Types.VARCHAR);
cstmt.registerOutParameter(12,Types.VARCHAR);
/*cstmt.registerOutParameter(13,Types.VARCHAR);*/
cstmt.execute();
status = cstmt.getString(11);
System.out.println("Remap Update Query "+cstmt.getString(12));
//System.out.println(cstmt.getString(13));
}
If the value stored in PropertyLoader.RET_SECONDARY_V_ARRAY is not "V_ARRAY", then you are using different types; even if they are declared identically (e.g. both are table of number) this will not work.
You're hitting this data type compatibility restriction:
You can assign a collection to a collection variable only if they have
the same data type. Having the same element type is not enough.
You're trying to call the procedure with a parameter that is a different type to the one it's expecting, which is what the error message is telling you.
The procedure which you are using is should be properly declared in the place which you are using it. For an example if it is under a user and in a package then it should be in that order. The username, package and procedurename.