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.
Related
I am noob in PL/SQL I just start learning and I want to create small peace of software that insert data from .CVS file to Oracle database.
And I stuck in part where I grab data from .CVS file.
I my CVS there are three column: Number_Policy,Contact, Agency
Number_Policy,Contact is catch success, but Agency can not be catched and I dont know why
declare
import_file text_io.file_type;
export_file text_io.file_type;
import_file_name varchar2(1000);
export_file_name varchar2(1000);
import_log_file text_io.file_type;
import_log_file_name varchar2(1000);
vec_importovano number;
brojac number;
brojac_redova number;
linebuf varchar2(10000);
p_rbr varchar2(20);
p_polica varchar2(20);
p_banka VARCHAR2(50);
p_kontakt varchar2(20);
kraj_fajla number;
begin
brojac_redova:=0;
import_file_name := :Global.Lokacija_prenosa||:import.naziv_fajla||:Global.Ekstenzija_prenosa;
import_file := text_io.fopen(import_file_name,'r');
delete from zivot_trajni_nalog_ponude where banka is not null;
commit;
kraj_fajla := 0;
while kraj_fajla = 0 loop
begin
brojac_redova:=brojac_redova+1;
text_io.get_line(import_file, linebuf);
if brojac_redova >= 2 then
p_polica:=substr(linebuf, 1, instr(linebuf,';',1,1)-1);
-- message(p_polica);
p_kontakt:=substr(linebuf, instr(linebuf,';',1,1)+1, instr(linebuf,';',1,2) - instr(linebuf,';',1,1)-1);
p_banka:=substr(linebuf, instr(linebuf,';',1,2)+1, instr(linebuf,';',1,3) - instr(linebuf,';',1,2)-1);
-- message(p_banka);
--p_kontakt:=substr(linebuf, instr(linebuf,';',1,1)+1, instr(linebuf,';',1,2) - instr(linebuf,';',1,1)-1);
-- message(p_kontakt);
/*
p_rbr:=substr(linebuf, 1, instr(linebuf,';',1,1)-1);
-- message(p_rbr);
p_polica:=substr(linebuf, instr(linebuf,';',1,1)+1, instr(linebuf,';',1,2) - instr(linebuf,';',1,1)-1);
-- message(p_polica);
p_banka:=substr(linebuf, instr(linebuf,';',1,2)+1, instr(linebuf,';',1,3) - instr(linebuf,';',1,2)-1);
message(p_banka);
p_kontakt:=substr(linebuf, instr(linebuf,';',1,3)+1, instr(linebuf,';',1,4) - instr(linebuf,';',1,3)-1);
message(p_kontakt);
*/
if vec_importovano = 0 then
insert into ZIVOT_TRAJNI_NALOG_PONUDE
(BROJ_POLICE,BROJ_PONUDE)
values(
p_polica,
--p_rbr,
p_kontakt);
-- p_banka);
commit;
end if;
end if;
EXCEPTION WHEN NO_DATA_FOUND THEN kraj_fajla := 1;
end;
end loop;
IF p_polica IS NOT NULL
THEN
update zivot_trajni_nalog_ponude set BROJ_POLICE=rownum;
commit;
END IF;
text_io.fclose(import_file);
message ('Uspjesno zavrseno');
end;
As you can see from code there is error somewhere here
p_banka:=substr(linebuf, instr(linebuf,';',1,2)+1, instr(linebuf,';',1,3) - instr(linebuf,';',1,2)-1);
-- message(p_banka);
After I disable this column the problem is that column p_polica and p_kontakt can't be inserted into database.
If anyone know where I made mistake I would be very thankful for any help.
Looks like linebuf has only two semicolons. This piece of code worked in my short test:
if instr(linebuf,';',1,3) > 0 then
p_banka := substr(linebuf,
instr(linebuf,';',1, 2) + 1,
instr(linebuf,';',1,3) - instr(linebuf,';',1,2)-1);
else
p_banka := substr(linebuf,
instr(linebuf,';',1, 2) + 1);
end if;
I am creating form in which user select "CSV" File and import "CSV" Data into oracle forms Data Block.I have date column when I import date column values into data block then getting following error
"FRM-50026 date must be entered in a format like DD-MON-YYYY"
My Date Column format in "CSV" File:
My Form:
Code:
DECLARE
application Client_OLE2.Obj_Type;
workbooks Client_OLE2.Obj_Type;
workbook Client_OLE2.Obj_Type;
worksheets Client_OLE2.Obj_Type;
worksheet Client_OLE2.Obj_Type;
worksheet2 Client_OLE2.Obj_Type;
cell Client_OLE2.OBJ_TYPE;
args Client_OLE2.OBJ_TYPE;
cell_value varchar2(100);
num_wrkshts NUMBER;
wksht_name VARCHAR2(250);
j integer:=1;
BEGIN
-- Get the name of the file to open
--v_fName := 'D:\MyDevelopment\Forms\Samples\WebUtil\Read_Excel\planets3.xls';
IF ( :BLOCK2.FILE IS NOT NULL ) THEN
-- The following sets up communication with the excel spreadsheet
-- --------------------------------------------------------------
-- Open the OLE application
application := Client_OLE2.create_obj('Excel.Application');
-- Keep the application hidden
Client_OLE2.set_property(application,'Visible','false');
workbooks := Client_OLE2.Get_Obj_Property(application, 'Workbooks');
args := Client_OLE2.CREATE_ARGLIST;
-- Open the selected File
-- ----------------------
Client_OLE2.add_arg(args,:BLOCK2.FILE);
workbook := Client_OLE2.GET_OBJ_PROPERTY(workbooks,'Open',args);
Client_OLE2.destroy_arglist(args);
worksheets := Client_OLE2.GET_OBJ_PROPERTY(workbook, 'Worksheets');
-- Get number of worksheets
-- ------------------------
num_wrkshts := Client_OLE2.GET_NUM_PROPERTY(worksheets, 'Count');
worksheet := Client_OLE2.GET_OBJ_PROPERTY(application,'activesheet');
--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
args:= Client_OLE2.create_arglist;
Client_OLE2.add_arg(args, j);
Client_OLE2.add_arg(args, k);
cell:= Client_OLE2.get_obj_property(worksheet, 'Cells', args);
Client_OLE2.destroy_arglist(args);
cell_value :=Client_OLE2.get_char_property(cell, 'Value');
--Could be done this way also ->
/*if k =1 then
:dept.deptno:=cell_value;
end if;
if k =2 then
:dept.dname:=cell_value;
end if;
if k =3 then
:dept.loc:=cell_value;
end if;
*/
--Less code this way ->
copy(cell_value,name_in('system.cursor_item'));
next_item;
end loop; --for
j:=j+1;
end loop;--main loop
-- Release the Client_OLE2 object handles
IF (cell IS NOT NULL) THEN
Client_OLE2.release_obj(cell);
END IF;
IF (worksheet IS NOT NULL) THEN
Client_OLE2.release_obj(worksheet);
END IF;
IF (worksheets IS NOT NULL) THEN
Client_OLE2.release_obj(worksheets);
END IF;
IF (worksheet2 IS NOT NULL) THEN
Client_OLE2.release_obj(worksheet2);
END IF;
IF (workbook IS NOT NULL) THEN
Client_OLE2.release_obj(workbook);
END IF;
IF (workbooks IS NOT NULL) THEN
Client_OLE2.release_obj(workbooks);
END IF;
Client_OLE2.invoke(application,'Quit');
Client_OLE2.release_obj(application);
ELSE
Message('No File selected.');
message(' ');
RAISE Form_Trigger_Failure;
END IF;
END;
How to solve this problem in Oracle Forms 11g
Would you be able to cast the value before import?
Have a look at this:
oracle convert DD-MON-YY to DD/MM/YYYY
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;
I applied this code in oracle forms 10g on trigger WHEN-BUTTON-PRESSED. This code only save the file on target location.
CODE:
PROCEDURE GEN_EXCEL IS
IN_FILE TEXT_IO.FILE_TYPE;
VC_HEAD Varchar2(32000);
vc_file_path Varchar2(50) := 'C:\';
BEGIN
IN_FILE := TEXT_IO.FOPEN(vc_file_path||'Test'||'.CSV','W');
TEXT_IO.PUT_LINE(IN_FILE,'YOUR_TITLE'||chr(10));
VC_HEAD := 'header1,header2,header3,header4';
TEXT_IO.PUT_LINE(IN_FILE,VC_HEAD);
FOR C1 IN ( SELECT column1, column2, column3, column4
FROM Table_name)
LOOP
TEXT_IO.PUT_LINE(IN_FILE,C1.col1||','||C1.col2||','||C1.col3||','||C1.col4);
END LOOP;
TEXT_IO.FCLOSE(IN_FILE);
MESSAGE('Excel file has been created!');
MESSAGE('Excel file has been created!');
EXCEPTION
WHEN Others THEN
TEXT_IO.FCLOSE(IN_FILE);
MESSAGE('Error while writing file.');
MESSAGE('Error while writing file.');
END;
I want when-button-pressed then direct open CSV file from oracle forms
How to achieve this target?
You can use webutil to do this.
It has a function client_host.
Also instead of duplicating your messages you can put pause after the first message. Then you don't need the second message for a popup of the message.
If you want to read-in your .csv file I've found a suitable solution for my problem.
Maybe it helps you too if I did understand it right what you want.
Reading From File
March 19, 2009
--------------------------------------------------
Declare
vfilename varchar2(500);
in_file Client_Text_IO.File_Type;
linebuf VARCHAR2(1800);
BEGIN
vfilename := client_get_file_name('c:/temp/', File_Filter=>'Comma Dialimeted Files (*.csv)|*.csv|');
in_file := client_Text_IO.Fopen(vfilename, 'r');
GO_BLOCK('Emp');
FIRST_RECORD;
LOOP
Client_Text_IO.Get_Line(in_file, linebuf);
p_output_line(linebuf);
Client_Text_IO.New_Line;
Next_record;
END LOOP;
FIRST_RECORD;
EXCEPTION
WHEN no_data_found THEN
Client_Text_IO.Put_Line('Closing the file...');
Client_Text_IO.Fclose(in_file);
END;
-------------------------------------------------------
PROCEDURE p_output_line(p_line varchar2) IS
vLINE VARCHAR2(4000);
vVALUE VARCHAR2(1000);
vCOMMA_COUNT NUMBER;
vREPORT_DATE DATE;
BEGIN
vLINE := p_line;
vCOMMA_COUNT := LENGTH(vLINE)- LENGTH(REPLACE(vLINE,',','')); -- COUNT THE NUMBER OF COMMAS
FOR I IN 1.. vCOMMA_COUNT+1 LOOP
vVALUE := SUBSTR(vLINE,1,INSTR(vLINE,',')-1); -- IF vLINE = 123,ABC,9877 THEN VVALUE WILL BE 123
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
:DATA.BMK_NAME := vVALUE;
ELSIF I = 2 THEN
vREPORT_DATE := last_day(to_date(vVALUE,'dd-mm-yyyy'));
:DATA.REPORT_DATE := vREPORT_DATE;
ELSIF I = 3 THEN
:DATA.BMK_RETURN := to_number(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;
-----------------------------------------------------------------------
-- notes
1- you must install webutil version 106 or later
2- make sure that you attached and compiled the webutill.pll scucessfuly
I am working on an Oracle procedure that calls another procedure within it. One of my parameters (parm1) can contain one or more values in a comma separated list. How can I loop through these values to pass them one at a time to another procedure?
Here is an example of what I would like it to do:
When Parm1 = 123,312
callProcedure2(123)
callProcedure2(321)
-or-
When Parm1 123
callProcedure2(123)
I think this can be accomplished using a loop but I can't figure out how to get it to use each value as a separated call within the loop.
Any help would be appreciated!
Thanks!
CURSOR V_CUR IS
select regexp_substr(Parm1 ,'[^,]+', 1, level) As str from dual
connect by regexp_substr(Parm1, '[^,]+', 1, level) is not null;
This curor will give you result like this
123
321
Now iterate the cursor and call the procedure in loop.
For i IN V_CUR
LOOP
callProdcedure2(i.str);
END LOOP;
Just loop through substrings:
declare
parm1 varchar2(1000) := '123,234,345,456,567,789,890';
vStartIdx binary_integer;
vEndIdx binary_integer;
vCurValue varchar2(1000);
begin
vStartIdx := 0;
vEndIdx := instr(parm1, ',');
while(vEndIdx > 0) loop
vCurValue := substr(parm1, vStartIdx+1, vEndIdx - vStartIdx - 1);
-- call proc here
dbms_output.put_line('->'||vCurValue||'<-');
vStartIdx := vEndIdx;
vEndIdx := instr(parm1, ',', vStartIdx + 1);
end loop;
-- Call proc here for last part (or in case of single element)
vCurValue := substr(parm1, vStartIdx+1);
dbms_output.put_line('->'||vCurValue||'<-');
end;
There is a utility procedure COMMA_TO_TABLE and array type DBMS_UTILITY.UNCL_ARRAY dedicated for this task. Since Oracle 10g.
It is well document here.
Here is a sample solution:
SET SERVEROUTPUT ON
DECLARE
csvListElm VARCHAR2(4000) := 'elm1, elm2,elm3 ,elm4 , elm5';
csvListTable DBMS_UTILITY.UNCL_ARRAY;
csvListLen BINARY_INTEGER;
currTableName VARCHAR2(222);
BEGIN
DBMS_UTILITY.COMMA_TO_TABLE(csvListElm, csvListLen, csvListTable);
FOR csvElm IN 1..(csvListTable.COUNT - 1) LOOP
dbms_output.put_line('-- CSV element : <'||csvListTable(csvElm)||'>');
dbms_output.put_line('-- Trimmed CSV element: <'||trim(csvListTable(csvElm))||'>');
END LOOP;
END;
/
Sample output:
-- CSV element : <elm1>;
-- Trimmed CSV element: <elm1>;
-- CSV element : < elm2>;
-- Trimmed CSV element: <elm2>;
-- CSV element : <elm3 >;
-- Trimmed CSV element: <elm3>;
-- CSV element : <elm4 >;
-- Trimmed CSV element: <elm4>;
-- CSV element : < elm5>;
-- Trimmed CSV element: <elm5>;
It is possible to use a function that you can use in a for loop (without regexp for ThinkJet):
Create a type and function
CREATE OR REPLACE TYPE t_my_list AS TABLE OF VARCHAR2(100);
CREATE OR REPLACE
FUNCTION cto_table(p_sep in Varchar2, p_list IN VARCHAR2)
RETURN t_my_list
AS
l_string VARCHAR2(32767) := p_list || p_sep;
l_sep_index PLS_INTEGER;
l_index PLS_INTEGER := 1;
l_tab t_my_list := t_my_list();
BEGIN
LOOP
l_sep_index := INSTR(l_string, p_sep, l_index);
EXIT
WHEN l_sep_index = 0;
l_tab.EXTEND;
l_tab(l_tab.COUNT) := TRIM(SUBSTR(l_string,l_index,l_sep_index - l_index));
l_index := l_sep_index + 1;
END LOOP;
RETURN l_tab;
END cto_table;
/
Then how to call it in the for loop:
DECLARE
parm1 varchar2(4000) := '123,234,345,456,567,789,890';
BEGIN
FOR x IN (select * from (table(cto_table(',', parm1)) ) )
LOOP
dbms_output.put_line('callProdcedure2 called with ' || x.COLUMN_VALUE);
callProdcedure2(x.COLUMN_VALUE);
END LOOP;
END;
/
Notice the default name COLUMN_VALUE given by Oracle, which is necessary for the use I want to make of the result.
Result as expected:
callProdcedure2 called with 123
callProdcedure2 called with 234
...