how can we get the value of of VARRAY from IN Parameter in procedure - sql

I am new to PL/SQL... In Varray how can i get multiple value from IN parameter..... else Is there another ways to get the values...
I want to interate the values through VArray... if any other options then its fine..
coding:
CREATE OR REPLACE
PROCEDURE dynamic_query_build(
vr_plan_sku_id IN VARCHAR2 )
IS
type plan_sku_id_array IS VARRAY(999) OF VARCHAR2(5000);
plan_sku_id plan_sku_id_array;
total INTEGER;
vrx_plan_sku_id VARCHAR2(3000);
BEGIN
vrx_plan_sku_id:= REPLACE(vr_plan_sku_id,',',chr(39)||','||chr(39));
plan_sku_id := plan_sku_id_array(chr(39)||vrx_plan_sku_id||chr(39));
total := plan_sku_id.count;
FOR i IN 1 .. total
LOOP
dbms_output.put_line(plan_sku_id(i));
END LOOP;
EXCEPTION
WHEN OTHERS THEN
raise_application_error(-20001,'An error was encountered - '||SQLCODE||' -ERROR- '||SQLERRM);
END dynamic_query_build;
Execution:
set serveroutput on;
declare
vr_plan_sku_id varchar2(200) := '5863314,5863315';
BEGIN
dynamic_query_build(vr_plan_sku_id);
END;
/
My Output:
anonymous block completed
'5863314','5863315'
Expected output:
5863314
5863315
now it is considering as single value....

I created anonymous block with procedure dynamic_query_build. Added there code, that will split VARCHAR2 variable into varray.
I think, the key to your question is this line - plan_sku_id.EXTEND();
You can extend varray dynamically, but only till it reaches defined maximum (in your case - 999).
DECLARE
vr_plan_sku_id varchar2(200) := '5863314,5863315';
PROCEDURE dynamic_query_build(
vr_plan_sku_id IN VARCHAR2 )
IS
type plan_sku_id_array IS VARRAY(999) OF VARCHAR2(5000);
plan_sku_id plan_sku_id_array;
total INTEGER;
position PLS_INTEGER := 0;
last_position PLS_INTEGER := 1;
tmp VARCHAR2(5000);
counter PLS_INTEGER := 1;
BEGIN
plan_sku_id := plan_sku_id_array();
LOOP
position := INSTR(vr_plan_sku_id, ',', last_position);
IF position > 0 THEN
tmp := SUBSTR(vr_plan_sku_id, last_position, position - last_position);
last_position := position + 1;
ELSE
tmp := SUBSTR(vr_plan_sku_id, last_position);
END IF;
plan_sku_id.EXTEND();
plan_sku_id(counter) := tmp;
counter := counter + 1;
EXIT WHEN position = 0 OR counter > 10;
END LOOP;
total := plan_sku_id.count;
FOR i IN 1 .. total
LOOP
dbms_output.put_line(plan_sku_id(i));
END LOOP;
EXCEPTION
WHEN OTHERS THEN
raise_application_error(-20001,'An error was encountered - '||SQLCODE||' -ERROR- '||SQLERRM);
END dynamic_query_build;
BEGIN
dynamic_query_build(vr_plan_sku_id);
END;
/

Put a replace in the dbms_output statement this will eliminate the quotes from the string
....
dbms_output.put_line replace (replace (plan_sku_id(i), '''' ))',',chr(10);
.....

Related

Change from Default Date to preferred date in this DBMS_SQL?

This code is from the proposed solution:
https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:9541646100346616701
My query is 'select * from table'
The second column is a DATE and this routine writes it as appears in my IDE session ('DD-MON-YY');
How can I report the values in DATE columns to 'YYYY-MM-DD'?
procedure clob_maker(p_query varchar2) is
l_theCursor integer default dbms_sql.open_cursor;
l_columnValue varchar2(4000);
l_status integer;
l_descTbl dbms_sql.desc_tab;
l_colCnt number;
n number := 0;
l_data clob;
begin
dbms_sql.parse( l_theCursor, p_query, dbms_sql.native );
dbms_sql.describe_columns( l_theCursor, l_colCnt, l_descTbl );
for i in 1 .. l_colCnt loop
dbms_sql.define_column(l_theCursor, i, l_columnValue, 4000);
end loop;
l_status := dbms_sql.execute(l_theCursor);
while ( dbms_sql.fetch_rows(l_theCursor) > 0 ) loop
for i in 1 .. l_colCnt loop
dbms_sql.column_value( l_theCursor, i, l_columnValue );
--dbms_output.put_line(l_columnValue); --this puts every column on a separate line
l_data := l_data || l_columnValue ||',';
end loop;
dbms_output.put_line(l_data);
n := n + 1;
end loop;
--dbms_output.put_line(l_data);
end clob_maker;
clob_maker('select * from mlb_catcher_birthdays fetch first 10 rows only');
The default format in which dates are represented is controlled by NLS parameter ns_date_format. You can just change this parameter at session level:
alter session set nls_date_format = 'YYYY-MM-DD';
You could also use TO_CHAR(), with the same format specifier as second argument - but this does not fit very well to your use case, since you would then need to check the datatype of each column before printing its value.

plsql reading text file in an array

When I run this portion of my code, which is inside a package, I get an error (specifically at the l_cnt := 1_cnt + 1 line for some reason and the code crashes. What could I be doing wrong? I am trying to read in a file of certs. Here's what I have so far:
v_certList arr_claims_t := arr_claims_t();
v_certLst VARCHAR2(2000);
f UTL_FILE.FILE_TYPE;
s VARCHAR2(200);
-- used for looping
l_cnt simple_integer := 0;
/*cop procedure*/
PROCEDURE COP_DATALOAD_V2 AS
arr_claims arr_claims_t;
arr_sql arr_sql_t;
BEGIN
f := UTL_FILE.FOPEN('V_COP',
'certs_file.txt',
'R',
2500);
-- populata our v_certlist of arr_claims_t
loop
utl_file.get_line(f, s);
v_certList.extend();
l_cnt := l_cnt+1;
v_certList(l_cnt) := s;
end loop;
exception
when no_data_found then
utl_file.fclose(f);
I want the array to be succesfuly populated given a text file (and I understand this is not the best practice but this is what I will have to do for now)
I figured out the error! The s that it was reading in was too big for the array. This was because empty spaces in the files was included.
v_certList.extend(1);
l_cnt := l_cnt + 1;
v_certList(l_cnt) := substr(s,
0,
10)
This fixed it for me.

how to find multiple of a number using goto sql statement?

Write a PL/SQL block to display the multiples of a Given Number
without including multiples of 10 for a given range (Start Value and
End Value), using GOTO.
This is my try, but I couldn't place the goto statement in correct place:
declare
start_value number; end_value number; n number;
result;
begin
start_value:=&start_value;
end_value:=&end_value;
n :=&n;
for x in start_value..end_value loop
<<calc>>
if((x mod n)=0 and (x mod 10)!=0) then
dbms_output.put_line(x);
end if;
goto calc;
end loop;
end;
First off, this is a really bad assignment. Teaching you to use GOTO's is like teaching a naval architect to build ships without watertight bulkheads - it's Just Wrong. (sigh) But, oh well...
DECLARE
start_value NUMBER;
end_value NUMBER;
n NUMBER;
BEGIN
start_value := &start_value;
end_value := &end_value;
n := &n;
FOR x IN start_value..end_value LOOP
IF MOD(x, 10) = 0 THEN
GOTO skip_calc;
END IF;
DBMS_OUTPUT.PUT_LINE(n * x);
<<skip_calc>>
NULL;
END LOOP;
END;
The way this would normally be written is:
DECLARE
start_value NUMBER;
end_value NUMBER;
n NUMBER;
BEGIN
start_value := &start_value;
end_value := &end_value;
n := &n;
FOR x IN start_value..end_value LOOP
IF MOD(x, 10) <> 0 THEN
DBMS_OUTPUT.PUT_LINE(n * x);
END IF;
END LOOP;
END;
Shorter and easier to read.

Oracle PL/SQL: Error returned without value on function

I'm trying to create a function that will compute for factorial but it returns an error when I do a SELECT FACTORIAL('1') FROM DUAL;
It returns the heinous error:function returned without value. I tried adding an exception but it seems that it doesn't work either. Care to help?
CREATE OR REPLACE FUNCTION FACTORIAL(p_factorial INTEGER)
RETURN NUMBER
AS var_fnumber number(2);
ctr number(2);
var_contain number(2) := 1;
BEGIN
FOR ctr in 1..p_factorial
LOOP
BEGIN
var_contain := var_contain * ctr;
DBMS_OUTPUT.put_line(var_contain);
EXCEPTION
WHEN OTHERS THEN
RETURN 0;
END;
END LOOP;
END; --FACTORIAL;
/
You MUST return something in a function.
SQL> CREATE OR REPLACE
2 FUNCTION FACTORIAL(
3 p_factorial INTEGER)
4 RETURN NUMBER
5 AS
6 var_fnumber NUMBER(2);
7 ctr NUMBER(2);
8 var_contain NUMBER(2) := 1;
9 BEGIN
10 FOR ctr IN 1..p_factorial
11 LOOP
12 BEGIN
13 var_contain := var_contain * ctr;
14 END;
15 END LOOP;
16 RETURN var_contain;
17 END;
18 /
Function created.
SQL>
SQL> SELECT factorial(2) FROM dual
2 /
FACTORIAL(2)
------------
2
For more details, read http://lalitkumarb.wordpress.com/2014/05/01/ora-06503-plsql-function-returned-without-value/
CREATE OR REPLACE FUNCTION FACTORIAL(p_factorial INTEGER)
RETURN NUMBER
AS var_fnumber number;
ctr number;
var_contain number := 1;
BEGIN
FOR ctr in 1..p_factorial
LOOP
BEGIN
var_contain := var_contain * ctr;
EXCEPTION
WHEN OTHERS THEN
RETURN 0;
RETURN var_contain;
END;
END LOOP;
RETURN var_contain;
END; --FACTORIAL;
/
Was gonna say that I found it. Thank you for the answers.
As for the reason why I used varchar2, I wasn't finalizing it yet.
modified your code try this:
create or replace
FUNCTION FACTORIAL(p_factorial INTEGER)
RETURN VARCHAR2
AS
var_contain varchar2(50):= 1;
BEGIN
FOR ctr in 1..p_factorial
LOOP
var_contain := var_contain * ctr;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
RETURN O;
return var_contain;

Sum of Digits in Pl/SQL (Error In extracting Digits)

I have Written Following Code :
DECLARE
n integer;
s integer;
d integer;
BEGIN
n:=&n;
while n!=0 loop
d:=mod(n,10);
s:=s+d;
n:=n/10;
end loop;
dbms_output.put_line('output :'||s);
end;
/
Input Value : 1234
Output Value : 4321 (Perfect What I want)
But When I Tried with following (I found incorrect output)
Input value : 5678
Output : 88761
Expected Output : 8765
The code you provided didn't work for me but the error is because it is rounding this operation:
n:=n/10;
If you change it to this it should work:
n:=floor(n/10); OR n:=trunc(n/10);
However it's not working for me, I needed to add something to s:=s+d. Here's my code:
DECLARE
n INTEGER;
s INTEGER:= 0;
d INTEGER;
i INTEGER:= 0;
BEGIN
n:= 5678;
i:= length(to_char(n))-1;
WHILE n!=0 LOOP
d:=mod(n,10);
s:=s+(d*power(10,i));
i := i - 1;
n:= trunc(n/10);
END LOOP;
dbms_output.put_line('output :'||s);
END;
/
You should initialize s and a few more changes.
DECLARE
n INTEGER;
s integer := 0;
d integer;
BEGIN
n:=&n;
while n!=0 loop
d:=mod(n,10);
s:=(s*10)+d;
n:=floor(n/10);
end loop;
dbms_output.put_line('output :'||s);
END;
/