DBMS_SQL.COLUMN_VALUE throwing - > PL/SQL: numeric or value error: character string buffer too small error - plsql

I am trying to dynamically execute a SQL in anonymous block and fetch the records using ':::' delimiter for external program.
It is failing when more than 13-15 records are fetched.
declare
mysql varchar2(3000) := 'select sid,username,status,event,p1,p2,p3 from v$session where rownum<30';
col DBMS_SQL.DESC_TAB;
data varchar2(4000);
state boolean;
function sqlformat ( col in DBMS_SQL.DESC_TAB, col_cnt number, indx number) return varchar2 AS
begin
if indx = col_cnt then
data := col(indx).col_name;
else
data := col(indx).col_name||':::';
end if;
return data;
end sqlformat;
function sqlexecute ( mysql IN varchar2) return boolean AS
handle number;
col_cnt number;
col DBMS_SQL.DESC_TAB;
v_exec number;
output varchar2(4000);
begin
handle := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(handle, mysql, DBMS_SQL.NATIVE);
v_exec := DBMS_SQL.EXECUTE(handle);
DBMS_SQL.DESCRIBE_COLUMNS(handle, col_cnt, col);
FOR indx in 1..col_cnt
loop
data := sqlformat(col,col_cnt,indx);
DBMS_SQL.define_column(handle, indx, col(indx).col_name,4000);
output := output||data;
end loop;
dbms_output.put_line(output);
dbms_output.NEW_LINE();
while DBMS_SQL.fetch_rows(handle) > 0
loop
state:=True;
output := NULL;
data :=NULL;
FOR indx in 1..col_cnt
loop
DBMS_SQL.COLUMN_VALUE(handle, indx, col(indx).col_name);
data := sqlformat(col,col_cnt,indx);
output := output||data;
dbms_output.NEW_LINE();
end loop;
dbms_output.put_line(output);
end loop;
return state;
end;
begin
state :=sqlexecute(mysql);
end;
/
`SID:::USERNAME:::STATUS:::EVENT:::P1:::P2:::P3`
`1::::::ACTIVE:::rdbms ipc message:::100:::0:::0`
`3::::::ACTIVE:::rdbms ipc message:::300:::0:::0`
`4::::::ACTIVE:::rdbms ipc message:::300:::0:::0`
`5::::::ACTIVE:::DIAG idle wait:::3:::1:::0`
`6::::::ACTIVE:::watchdog main loop:::0:::20:::0`
`7::::::ACTIVE:::rdbms ipc message:::180000:::0:::0`
`8::::::ACTIVE:::rdbms ipc message:::100:::0:::0`
`9::::::ACTIVE:::rdbms ipc message:::300:::0:::0`
`10::::::ACTIVE:::ASM background timer:::0:::0:::0`
`11::::::ACTIVE:::Space Manager: slave idle wait:::1:::0:::0`
`13::::::ACTIVE:::class slave wait:::0:::0:::0`
`15::::::ACTIVE:::rdbms ipc message:::30000:::0:::0`
`17::::::ACTIVE:::Space Manager: slave idle wait:::2:::0:::0`
declare
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at "SYS.DBMS_SQL", line 1795
ORA-06512: at line 41
ORA-06512: at line 51

I suggest to try insert substr in each string objects to understand which variabile get the error:
data := substr(col(indx).col_name,1,4000);
data := substr(col(indx).col_name||':::',1,4000);
output := substr(output||data,1,4000);
output := substr(output||data,1,4000);
Thank you

Related

ORA-06502: PL/SQL: numeric or value error: NULL index table key value ORA-06512: at "OJC.JC_MASTER", line 129

I'm trying to run an interface in ODI 11g. When I call the procedure I get this error :
ODI-1228: Task START_JC (Procedure) fails on the target ORACLE connection OJC.
Caused By: java.sql.SQLException: ORA-06502: PL/SQL: numeric or value error: NULL index table key value
ORA-06512: at "OJC.JC_MASTER", line 129
ORA-06512: at "OJC.JC_MASTER", line 689
ORA-06512: at line 9
the sql code
PROCEDURE string_to_aa_parameter_type (
p_string VARCHAR2,
p_out_aa_parameter_values IN OUT aa_parameter_type
)
AS
v_start INTEGER := 1;
v_pos INTEGER := 0;
v_counter INTEGER := 0;
v_temp_parameter_name VARCHAR2 (4000);
v_temp_parameter_value VARCHAR2 (4000);
BEGIN
IF p_string IS NULL
THEN
RETURN;
END IF;
-- determine first chuck of string
v_pos := INSTR (p_string, '=', v_start);
-- while there are chunks left, loop
WHILE (v_pos != 0)
LOOP
v_counter := v_counter + 1;
-- create array
IF MOD (v_counter, 2) = 1
THEN
v_temp_parameter_name :=
SUBSTR (p_string, v_start, v_pos - v_start);
v_start := v_pos + 1;
v_pos := INSTR (p_string, ';', v_start);
ELSE
v_temp_parameter_value :=
SUBSTR (p_string, v_start, v_pos - v_start);
p_out_aa_parameter_values (trim(v_temp_parameter_name)) :=
trim(v_temp_parameter_value);
v_start := v_pos + 1;
v_pos := INSTR (p_string, '=', v_start);
END IF;
END LOOP;
-- IN THE FOLLOWING LINE I GET THE ERROR
v_temp_parameter_value := SUBSTR (p_string, v_start);
p_out_aa_parameter_values (trim(v_temp_parameter_name)) :=
trim(v_temp_parameter_value);
END;
Can someone help me in figuring out that the problem is ?
You'll get that error if p_string is a not-null value which doesn't contain an equals sign at all, or with any semicolon-delimited part that starts with an equals sign. It's thrown by the line after the one you indicated (or the equivalent line inside the loop, if p_string has a final semicolon).
If there is no equals sign at all then
v_pos := INSTR (p_string, '=', v_start);
gives zero, which means you don't go through the loop at all; which means when you get to that final assignment v_temp_parameter_name has never been set.
If there is a key/value pair with no key, say p_string is 'x=y;=z' you do go into the loop, and with that example the first key/value pair is added to the array; but then v_start and v_pos end up as the same value (5 in this case, both pointing to the second =). The the next time round the loop:
v_temp_parameter_name :=
SUBSTR (p_string, v_start, v_pos - v_start);
evaluates to SUBSTR(p_string, 5, 0) (where the third argument is zero because those two variables are the same), which is always going to be an empty string, or null.
There is no actual error yet, so it evaluates v_pos again, and either gets zero or non-zero, depending on whether there is a terminating semicolon.
If it's non-zero then it goes round the loop again; if it's zero it drops out. Either way it has a last stab at getting the matching value - it doesn't matter if that is set to anything or not. When it tries to add the element to the array, though, the name is still null, and you get that error, from whichever of the two array assignments it hits.
You could do additional testing and handling inside the procedure to spot and discard null keys, but
i didn't write the procedure,i have to run it . It is supposed to be syntax correct
So you need to figure out why the Java code is passing a value which the procedure can't handle - i.e. why it is sending incomplete key/value pairs.

getting wrong number or types of arguments in call to procedure

I am trying to call a procedure using below code and getting
wrong number or types of arguments in call to procedure
The issue could be with the record type being passed as parameter , but I couldn't see any issue with that .
DECLARE
p_status VARCHAR2 (4) := 'S';
p_id NUMBER := 123456;
p_py_id NUMBER := 513;
p_type NUMBER := 1;
p_date_time DATE := TO_DATE ('10/01/2018 23:50:42', 'DD/MM/YYYY HH24:MI:SS');
p_os_pay NUMBER := 0;
p_ind VARCHAR2 (2) := 'Y';
p_confirm VARCHAR2 (2) := 'Y';
p_year NUMBER := 2018;
p_reason VARCHAR2 (5) := NULL;
p_currrpay NUMBER := 1517;
p_details pkg.g_r_type;
BEGIN
p_details.pro_code := 'AB';
p_details.inst_type := '1';
p_details.pay_date := TO_DATE ('19/10/2016 00:00:00', 'DD/MM/YYYY HH24:MI:SS');
p_details.pay_amt := 5000;
p_details.h_code := 'ABCD';
p_details.pay_ind := 'N';
p_details.c_code := 123456;
p_details.c_year := 8;
pkg.procedure_info ( p_status,
p_id,
p_py_id,
p_type,
p_date_time,
p_os_pay,
p_ind,
p_confirm,
p_year,
p_reason,
p_details,
p_currrpay
);
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (SQLERRM);
END;
/
Below is the package description :
CREATE OR REPLACE package pkg
as
type g_r_type is record (
pro_code varchar2 (2)
,inst_type varchar2 (1)
,pay_date date
,pay_amt number (13, 2)
,h_code varchar2 (4)
,pay_ind varchar2 (1)
,c_code number(6)
,c_year number(2)
);
procedure procedure_info (
p_status in varchar2
,p_id in number
,p_py_id in number
,p_type in number
,p_date_time in date
,p_os_pay in number
,p_ind in varchar2
,p_confirm in varchar2
,p_year in number
,p_failure_reason in varchar2
,p_details in g_r_type
,p_currrpay in number
);
end pkg;
/
I have cross checked the datatypes, length and number of arguments , but couldn't find the issue.
Make sure your package scripts end with a / at the very end of the text file, as the first char of the line (and last non blank).
If your package was created successfully, you should get a message:
package created successfully
Then if your package's Body is:
package body created successfully
To make sure your package is correctly created on the database:
This query should help:
Select * from all_source where name='PKG';
And for the body:
Select *
from all_source
where name='PKG'
and type='PACKAGE BODY';

Passsing two VARRAYS to a Procedure to pass them to a Index-By table

I try to pass two VARRAYs into a Procedure but when call it to test it I don't get any kind of respond from my database.
CREATE OR REPLACE PACKAGE PKG_TEST AS
TYPE PNO IS VARRAY(20) OF VARCHAR(20);
TYPE QTY IS VARRAY(20) OF INTEGER;
TYPE indexTest IS TABLE OF NUMBER INDEX BY VARCHAR2(20);
PROCEDURE blatest(i_PNO IN PNO, i_QTY IN QTY);
END PKG_TEST;
/
CREATE OR REPLACE PACKAGE BODY PKG_TEST AS
PROCEDURE blatest(i_PNO IN PNO , i_QTY IN QTY)
IS
V_COUNT_PNO INTEGER;
V_COUNT_QTY INTEGER;
bla_list indexTest;
name VARCHAR(20);
BEGIN
V_COUNT_PNO := i_PNO.COUNT;
V_COUNT_QTY := i_QTY.COUNT;
IF V_COUNT_PNO = V_COUNT_QTY THEN
FOR I IN 1..V_COUNT_PNO LOOP
bla_list(i_PNO(I)) := i_QTY(I);
END LOOP;
name := bla_list.FIRST;
WHILE name IS NOT null LOOP
dbms_output.put_line('Name: ' || name || ' is ' || TO_CHAR(bla_list(name)));
name := bla_list.NEXT(name);
END LOOP;
ELSE
dbms_output.put_line('Amount of Variables is not identical!');
END IF;
END blatest;
END PKG_TEST;
/
PKG_TEST.blatest(PKG_TEST.PNO('P123','P124'), PKG_TEST.QTY(2,3));
/
And if there is any easier way to fill in a Index-By table I dynamicly I am more than happy to read this ^^. Thanks in advance!
Call it as below, then you will get response:
set serveroutput on;
BEGIN
pkg_test.blatest (pkg_test.pno ('P123', 'P124'), pkg_test.qty (2, 3));
END;

insert clob datatypefrom sql server

I have the below code to insert clob datatype from SQL server to Oracle Database using DBlink.
I m currently facing the error :
ORA-06502: PL/SQL: numeric or value error: invalid LOB locator specified: ORA-22275
ORA-06512: at "SYS.DBMS_LOB", line 639. Can you please help me what could be the issue with the code?
declare
v_REGION_CODE CLOB ;
l_clob CLOB;
c integer;
nr integer;
BEGIN
DBMS_LOB.CREATETEMPORARY(l_clob,true);
EXECUTE IMMEDIATE 'TRUNCATE TABLE SVQ_DI_XLS_COUNTRY_POP_DETAILS';
c := DBMS_HS_PASSTHROUGH.OPEN_CURSOR#PPRLEG;
DBMS_HS_PASSTHROUGH.PARSE#PPRLEG(c,' SELECT "REGION CODE" FROM TBL_SVQ_DI_XLS_COUNTRY_POP_DETAILS');
LOOP
nr := DBMS_HS_PASSTHROUGH.FETCH_ROW#PPRLEG(c);
EXIT
WHEN nr = 0;
DBMS_HS_PASSTHROUGH.GET_VALUE#PPRLEG(c, 1 , v_REGION_CODE ) ;
FOR i IN 1..10
LOOP
INSERT INTO SVQ_DI_XLS_COUNTRY_POP_DETAILS (REGION_CODE) VALUES (empty_clob()) --Insert an "empty clob" (not insert null)
RETURNING REGION_CODE INTO l_clob;
FOR i IN 1..100
LOOP
dbms_lob.append(l_clob, v_REGION_CODE);
--dbms_lob.append(l_clob, 'string chunk to be inserted (maximum 4000 characters at a time)');
END LOOP;
END LOOP;`enter code here`
END LOOP;
DBMS_HS_PASSTHROUGH.CLOSE_CURSOR#PPRLEG(c);
COMMIT;
END;

Oracle PL/SQL SUBSTR error

i need to convert a varchar to an array using pl/sql, but when i use the SUBSTR function, i get this error:
Error report -
ORA-06550: line 12, column 3:
PLS-00330: invalid use of type name or subtype name
ORA-06550: line 12, column 3:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
this is my code:
SET SERVEROUTPUT ON;
DECLARE
v_string varchar2(20) := 'hello';
type array_string is varray(5) of varchar2(10);
v_length number;
cnt number;
v_char char(1);
BEGIN
v_length := length(v_string);
while (cnt < v_length)
loop
v_char := SUBSTR(v_string, cnt, 1);
array_string(cnt) := v_char;
cnt := cnt + 1;
end loop;
END;
when i (partially) type 'SUBSTR' it autocompletes to SUBSTR(SQLERRM, 1, 64) so it should know the command, right?
what am i doing wrong? im pretty new at pl/sql
regards,
You must initialize variable cnt before using it in substr.
You must use variable name instead of type name in array_string(cnt).
You must extend your varray before writing new value to it.
In oracle environment, the starting index for varrays is always 1.
Your cnt is starting from 0. So the during the first time execution of the loop, the
a_string(cnt) := v_char;
cnt is 0.
Initialize cnt as 1, and run the loop for
while (cnt < 5)
This will remove the error you are getting

Resources