PLSQL - 2 FOR loops on nested tables - oracle

PLSQL - 2 FOR loops on nested tables, one after the other, the second loop isn't performed while the nested table of the first loop is empty.
Follow is the code snippet:
type prod_seq_array is table of wiz_customer_hp_product.product_seq%type;
c_prod_add_arr prod_seq_array := prod_seq_array ();
c_prod_drop_arr prod_seq_array := prod_seq_array (1234,5678);
FOR i IN c_prod_add_arr.FIRST .. c_prod_add_arr.LAST LOOP
mydebug2.debug_out(fp,'shira2 ' ||wo_prod_rec_1.product_seq);
if v_prod_seq = c_prod_add_arr(i) then
v_status := 'C';
ins_hp_prod_svc;
v_drop_wo_date := v_add_date;
exit;
end if;
END LOOP;
FOR i IN c_prod_drop_arr.FIRST .. c_prod_drop_arr.LAST LOOP
if v_prod_seq = c_prod_drop_arr(i) then
v_status := 'C';
del_hp_prod_svc_hist ;
v_drop_wo_date := v_drop_date;
exit;
end if;
END LOOP;

I understand that FOR loop on empty nested table will throw exception so I added the following condition before each FOR loop
if c_prod_add_arr.count > 0
FOR i IN c_prod_add_arr.FIRST .. c_prod_add_arr.LAST LOOP
if v_prod_seq = c_prod_add_arr(i) then
v_status := 'C';
ins_hp_prod_svc;
v_drop_wo_date := v_add_date;
exit;
end if;
END LOOP;
end if;

Related

Unable to get dbms_sql.column_value

I'm trying to read a query from a table and process it with DBMS_SQL package. It parses correctly. I can also see the columns, which occurs in a query. But I'm not able to fetch results. In debug mode It throws the exception while trying to getting dbms_sql.column_value (please see the code below).
/*--------------------------------------------------------------------------------------------------------------------*/
PROCEDURE MY_PROC( nCSV_EXP_CFG_ID IN NUMBER,nN1 IN NUMBER DEFAULT null )
/*--------------------------------------------------------------------------------------------------------------------*/
as
l_ntt_desc_tab dbms_sql.desc_tab;
nCursorId INTEGER;
nColCnt INTEGER;
nRowCnt INTEGER;
rCSV_EXP_CFG CSV_EXP_CFG%ROWTYPE;
TYPE rowArray IS VARRAY(20) OF VARCHAR2(255);
colVal rowArray;
BEGIN
SELECT * INTO rCSV_EXP_CFG
FROM CSV_EXP_CFG
WHERE
CSV_EXP_CFG_ID = nCSV_EXP_CFG_ID;
nCursorId:=dbms_sql.open_cursor;
dbms_sql.parse(nCursorId, rCSV_EXP_CFG.EXPORT_TABLE, dbms_sql.native);
IF nN1 IS NOT NULL THEN DBMS_SQL.BIND_VARIABLE (nCursorId, 'n1', nN1); END IF;
dbms_sql.describe_columns(nCursorId, nColCnt, l_ntt_desc_tab);
FOR i IN 1..nColCnt LOOP
DBMS_OUTPUT.PUT_LINE( l_ntt_desc_tab(i).col_name);
--DBMS_SQL.DEFINE_COLUMN(nCursorId, i, colVal(i), 255);
END LOOP;
nRowCnt:=dbms_sql.execute(nCursorId);
LOOP
EXIT WHEN dbms_sql.fetch_rows(nCursorId) = 0;
FOR i IN 1..nColCnt LOOP
--here I'm getting the exception
dbms_sql.column_value(nCursorId, i, colVal(i));
END LOOP;
END LOOP;
Dbms_sql.close_cursor(nCursorId);
EXCEPTION WHEN OTHERS THEN
NULL;
END MY_PROC;
What am I doing wrong?

PLSQL Exception handling in GET_FILE

Trying to handle exception if the input file received has invalid records or no data. The below exception runs in loop even though the input file has only 1 record.
LOOP
BEGIN
UTL_FILE.GET_LINE(a_UIN_input_file,a_UIN_file);
a_rec := substr(a_uin_file,1,9);
EXCEPTION
WHEN NO_DATA_FOUND THEN
a_error_file := utl_file.fopen('TAMUOUT','PWT_TEST5_ERROR.txt','w');
utl_file.put_line(a_error_file,'Bad UIN Read ' ||SQLERRM||'\n');
utl_file.fclose(a_error_file);
-- EXIT;
END;
END LOOP;
FOR rec IN get_details_4_uin_c(a_rec) LOOP
a_pidm :=fwt_get_pidm_from_uin(a_rec);
a_bill_hours := fwt_get_enrolled_hours(a_pidm,in_term_code);
utl_file.put_line(a_out_file,a_parm,
autoflush=>TRUE);
END LOOP;
utl_file.fclose(a_uin_input_file);
UTL_FILE.GET_LINE raises the NO_DATA_FOUND exception when you have reached the end of the file and then keep on trying to read more.
So your exception handler for NO_DATA_FOUND should exit the loop. But within the loop, if you read a line successfully, then run your loop on that.
I believe the code believe will help you get to your solution.
BEGIN
LOOP
BEGIN
UTL_FILE.get_line (a_uin_input_file, a_uin_file);
a_rec := SUBSTR (a_uin_file, 1, 9);
FOR rec IN get_details_4_uin_c (a_rec)
LOOP
a_pidm := fwt_get_pidm_from_uin (a_rec);
a_bill_hours := fwt_get_enrolled_hours (a_pidm, in_term_code);
UTL_FILE.put_line (a_out_file, a_parm, autoflush => TRUE);
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
UTL_FILE.fclose (a_uin_input_file);
EXIT;
END;
END LOOP;
END;

Error ORA-06502 WHEN-BUTTON-PRESSED oracle forms

I am trying to show data from "CSV" File to Oracle forms. I am using Client_Text_IO procedure to read data from "CSV" file with comma separated into Data Block.
I have one column in which some data empty and have some data. If I open file in excel then:
No. 6 column some rows are empty:
No.6 column some rows have data:
When I open file in notepad then:
6,6,6000000116,HH00000471,Abdul akbar,,1610223056753
You can see after "ABDUL AKBAR" there are 2 commas due to empty data
With data in notepad:
6,6,6000000189,HH00000544,Raishma bibi,Gul akbar,1610216789294
When I run procedure then I getting following error on 6th column:
CODE:
PROCEDURE p_output_line(p_line varchar2) IS
vLINE VARCHAR2(4000);
vVALUE VARCHAR2(1000);
vCOMMA_COUNT NUMBER;
BEGIN
vLINE := p_line;
vCOMMA_COUNT := LENGTH(vLINE)- LENGTH(REPLACE(vLINE,',',''));
FOR I IN 1.. vCOMMA_COUNT+1 LOOP
vVALUE := SUBSTR(vLINE,1,INSTR(vLINE,',')-1);
IF vVALUE IS NULL THEN
vVALUE := vLINE;
END IF;
vLINE := SUBSTR(vLINE,INSTR(vLINE,',')+1) ; -- CHANGE 123,ABC,9877 TO BE ABC,9877
IF I = 1 THEN
:WE_GROUP_HOF_K.CLIENTID := vVALUE;
END IF;
IF I = 2 THEN
:WE_GROUP_HOF_K.PROJECTID := vVALUE;
END IF;
IF I = 3 THEN
:WE_GROUP_HOF_K.GROUP_HOF_ID := vVALUE;
END IF;
IF I = 4 THEN
:WE_GROUP_HOF_K.NRSP_HOFID := vVALUE;
END IF;
IF I = 5 THEN
:WE_GROUP_HOF_K.HOF_NAME := vVALUE;
END IF;
IF I = 6 THEN
:WE_GROUP_HOF_K.FATHER_NAME := vVALUE;
END IF;
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
MESSAGE('Please Check the data type is appropriate on you excel file');
MESSAGE('Please Check the data type is appropriate on you excel file');
END;
Because it is empty your counts don't work.
Use a split function to split your data.
Split function
Also in your when no_data_found exception you should put pause; after your message, then there is no need to put it twice.

webutil how to read word file into an oracle forms Data Block

I apply procedure "application Client_OLE2.Obj_Type". Read word file and enter data into oracle forms Data Block.
I created this form:
This code did not enter data into block. Please suggest me if any wrong in this code
Code:
declare
arg_list client_ole2.list_type;
document client_ole2.obj_type;
documents client_ole2.obj_type;
application client_ole2.obj_type;
wordvalue VARCHAR2(100);
j integer:=1;
BEGIN
IF ( :BLOCK2.FILE IS NOT NULL ) THEN
application := client_OLE2.CREATE_OBJ('WORD.APPLICATION');
Client_OLE2.set_property(application,'Visible','false');
arg_list := client_ole2.create_arglist;
documents := client_ole2.invoke_obj (application, 'documents');
client_ole2.add_arg (arg_list, :BLOCK2.FILE);
document := client_ole2.invoke_obj (documents, 'Open', arg_list);
client_ole2.destroy_arglist (arg_list);
--Go to the first record
go_block('WE_GROUP_HOF_K');
first_record;
loop
If :system.record_status <> 'NEW' then
create_record;
end if;
for k in 1..1 loop
arg_list:= Client_OLE2.create_arglist;
Client_OLE2.add_arg(arg_list, j);
Client_OLE2.add_arg(arg_list, k);
document:= Client_OLE2.get_obj_property(documents, '', arg_list);
Client_OLE2.destroy_arglist(arg_list);
wordvalue := Client_OLE2.get_char_property(document, 'Value');
if k =1 then
:we_group_hof_k.clientid:=wordvalue;
end if;
end loop; --for
j:=j+1;
end loop;
client_ole2.RELEASE_OBJ (documents);
END IF;
exception
when others then
message(SQLERRM);
message(SQLERRM);
end;
To Load BLOB file to Oracle Forms Block, Simply do this :
declare
v_file_path varchar2(2000);
begin
v_file_path :=Get_file_name(select_file=>True);
if v_file_path is not null then
initialize_container('Block.Item',v_file_path );
End if;
end;

loop counter case in oracle procedure

Is there any loop counter in procedure.
How to handle below case.
BEGIN
FOR recAnnLang IN getLang(var_non_subscribe)
LOOP
// if loop 1 recAnnLangCode.Ann_Lang assign to var1
var1 := recAnnLangCode.Ann_Lang;
// if loop 2 recAnnLangCode.Ann_Lang assign to var2
var2 := recAnnLangCode.Ann_Lang;
// if loop 3 recAnnLangCode.Ann_Lang assign to var2
var3 := recAnnLangCode.Ann_Lang;
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('Debug :: Inside Exception because data not found ' );
END;
DECLARE n_counter NUMBER := 0;
BEGIN
LOOP
n_counter := n_counter + 1;
DBMS_OUTPUT.PUT_LINE(n_counter);
IF n_counter = 5 THEN
EXIT;
END IF;
END LOOP;
END;
I did it like this.
maybe you are looking for something like
declare
type a_type is table of recAnnLang.Ann_Lang%type index by pls_integer;
val a_type;
begin
for recAnnLang in getLang(var_non_subscribe) loop
val(nvl(val.last, 0) + 1) := recAnnLang.Ann_Lang;
end loop;
for i in 1 .. val.last loop
dbms_output.put_line(val(i));
end loop;
end;
maybe,if getlang is an explicit cursor,you may think of using rownum in the cursor query select clause and use it as the counter.

Resources