Importing .csv file into a Oracle Forms application - oracle

I've got a question how to import a .csv file into a Oracle Forms application.
We are using Oracle Forms 11g on a Oracle 12c Database.
Now we want to import a .csv file with the Forms applicationso our customers can import this file and write the data into the database.
My plan is to create an application where the user can import a .csv file with a filechooser. The data from the .csv will be read and an output shows the user the data in this application. Then the user should be able to save it into the database through a button.
I've tried several searches but haven't found the right solution for this kind of problem. The only solutions I've found were a direct import of a .csv file into a database but not through Oracle Forms
Is it even possible to load .csv files in Oracle Forms?
If anyone has a good solution or anything else that might be helpfull i would be thankfull for that.

I've found a suitable solution for me now. Maybe I could do it better but this helps me so far.
I've found the following Blog: http://tfathy.blogspot.de/2009/03/reading-from-file.html
The Code works 100% by copy&paste and helps me from now on to complete the task.
Maybe it might help anyone else too.
Here is the solutioncode:
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

You can just use webutil to show a filechooser to select the file and upload it to the application server. If you use a shared directory between the application server and the db server you can use an external table to show the input of the file to the user. And then after the button you just insert the data from the external table in another table.

Related

I am Getting invalid file operation error though file is present in my local system

create or replace directory MYCSV as 'E:\sqlloader\';
grant read, write on directory MYCSV to public;
declare
F UTL_FILE.FILE_TYPE;
V_LINE VARCHAR2 (1000);
V_id NUMBER(4);
V_NAME VARCHAR2(10);
V_risk VARCHAR2(10);
BEGIN
F := UTL_FILE.FOPEN ('MYCSV', 'testfile.csv', 'R');
IF UTL_FILE.IS_OPEN(F) THEN
LOOP
BEGIN
UTL_FILE.GET_LINE(F, V_LINE, 1000);
IF V_LINE IS NULL THEN
EXIT;
END IF;
V_id := REGEXP_SUBSTR(V_LINE, '[^,]+', 1, 1);
V_NAME := REGEXP_SUBSTR(V_LINE, '[^,]+', 1, 2);
V_risk := REGEXP_SUBSTR(V_LINE, '[^,]+', 1, 3);
INSERT INTO loader_tab VALUES(V_id, V_NAME, V_risk);
COMMIT;
EXCEPTION
WHEN NO_DATA_FOUND THEN
EXIT;
END;
END LOOP;
END IF;
UTL_FILE.FCLOSE(F);
END;
/
CSV file content wherein I need to start loading from 1,a,aa and need to skip first 4 lines:
portal,,
ex portal,,
,,
i_id,i_name,risk
1,a,aa
2,b,bb
3,c,cc
4,d,dd
5,e,ee
6,f,ff
7,g,gg
8,h,hh
9,i,ii
10,j,jj
I want to load the data from excel but I am getting an invalid file operation error. Will someone help with this? Not able to load the data from an excel file. I am Getting invalid file operation error though file is present in my local system.
though file is present in my local system
It won't work unless your local system (I presume you mean your own PC) also runs the database into which you're trying to load data. Oracle directory (probably in 99% of all cases) resides on the database server.
I want to load the data from excel
It won't work either, if that's really an Excel file. Code you posted suggests that it is a comma-separated values file (textual, that is), and yes - it should be such a file, not XLSX.

Downloading files from the database server via APEX

I am trying to find a way to get files from the database server via APEX. I can't find any documentation about this issue.
Can I avoid using the plsql code?
PS: I'm launching APEX on tomcat on different server that db is.
As we talked on the comments, let me show you an example. I write you a lot of thing so take your time...
Upload file
You can have an object in Apex that allows the user to browse for a file to be uploaded. At the end, the user press a button that triggers the action . The button upload submits the page, and the action is after submit for the button itself. Any file upload is stored automatically in apex_application_temp_files ( keep in mind I removed a lot of controls I have regarding format of the file, size, etc ).
First create the directory
create or replace directory yourdirectory as '/your_path' ;
grant read, write on directory yourdirectory to your_user ;
The code in the button:
declare
v_error VARCHAR2(400);
v_filename VARCHAR2(400);
v_name VARCHAR2(400);
v_blob blob;
vodate number(8);
begin
SELECT filename,blob_content,name, to_number(regexp_replace(filename,'[0-9]{4}[0-9]{2}[0-9]{2}'))
INTO v_filename,v_blob,v_name,vodate
FROM apex_application_temp_files
WHERE name = :P2_FILE;
apex_debug.enable ( p_level => 5 );
apex_debug.message(p_message => 'v_filename is '||v_filename||' ', p_level => 5) ;
apex_debug.message(p_message => 'v_name is '||v_name||' ', p_level => 5) ;
apex_debug.message(p_message => 'vodate is '||to_number(substr(v_filename,14,8)) ||' ', p_level => 5) ;
-- insert into filesystem
p_write_blob_to_file(p_name=>v_name);
EXCEPTION
WHEN OTHERS THEN
raise;
end;
The important part here is the code p_write_blob_to_file. This is the code of that procedure, keeping in consideration that in my case p_dir takes a default value.
CREATE OR REPLACE procedure p_write_blob_to_file (p_name IN VARCHAR2, p_dir IN VARCHAR2 default 'your_directory' )
IS
l_blob BLOB;
l_blob_length INTEGER;
l_out_file UTL_FILE.file_type;
l_buffer RAW (32767);
l_chunk_size BINARY_INTEGER := 32767;
l_blob_position INTEGER := 1;
l_file_name varchar2(2000);
v_mime_type varchar2(2000);
BEGIN
-- Retrieve the BLOB for reading
SELECT blob_content, filename, mime_type
INTO l_blob, l_file_name, v_mime_type
FROM apex_application_temp_files
WHERE name = p_name;
-- Retrieve the SIZE of the BLOB
l_blob_length := DBMS_LOB.getlength (l_blob);
-- Open a handle to the location where you are going to write the BLOB
-- to file.
l_out_file :=
UTL_FILE.fopen (p_dir,
l_file_name,
'wb',
l_chunk_size);
-- Write the BLOB to file in chunks
WHILE l_blob_position <= l_blob_length
LOOP
IF l_blob_position + l_chunk_size - 1 > l_blob_length
THEN
l_chunk_size := l_blob_length - l_blob_position + 1;
END IF;
DBMS_LOB.read (l_blob,
l_chunk_size,
l_blob_position,
l_buffer);
UTL_FILE.put_raw (l_out_file, l_buffer, TRUE);
l_blob_position := l_blob_position + l_chunk_size;
END LOOP;
-- Close the file handle
UTL_FILE.fclose (l_out_file);
END p_write_blob_to_file;
/
Download File
In order to download the file, you need the opposite path.
The button or link download must be associated to a component PL/SQL
The button loads the file first from the directory in the server into a column
The button then download the file
I was going to write all the commands here , but you have a find very good example here of both actions:
Load file from directory into column
https://renaps.com/en/blog/how-to/how-to-load-file-content-to-a-blob-field-and-unload-blob-content-to-a-file-on-the-os
Download file
https://oracle-base.com/articles/misc/apex-tips-file-download-from-a-button-or-link#apex-button
Try to experiment with this and let me know any issues you might find. The only tricky thing here is that in Apex you need to pass the name of the file you want to download. So the user must know the name, exactly as it is in the server. What you can't do is provide a graphical interface to the server in order to select the file.

Oracle database loading data from text file to database using UTL_file and dbms

I am trying to upload data from text file to my table using UTL_FILE from SQL PLUS.
the text file name testb.txt contain data:
10,mike
20,bill
30,kim
and in my the table in the database called mytable contain columns (empno, empname)
I tried this code on SQL plus:
declare
filehand utl_file.file_type;
line varchar2(4000);
vempno varchar2(50);
vempname varchar2(50);
begin
filehand := utl_file.fopen('c:\users\myuser\desktop', 'testb.txt', 'r');
loop
utl_file.get_line(filehand, line);
if line is not null then
vempno := substr(line, 1, instr(line, ',')-1);
vempname := substr(line, instr(line, ',')+1, length(line));
dbms_output.put_line(vempno);
dbms_output.put_line(vempname);
insert into mytable (empno, empname) values (vempno, vempname);
commit;
else
exit;
end if;
end loop;
commit;
utl_file.fclose(filehand);
exception
when others then
null;
end:
/
when I run this code I got PL/SQL procedure successfully completed.
but when I see my table nothing change and the data not loaded from the text file to my table.
???
whats wrong in my code and what to do to upload the data from the text file to my table using UTL_file and dbms ??
Please guys help me I really need it.
Thank you very much

Extracting BLOB files from Oracle table with UTL_FILE en masse, some compressed some not

I have a script that extracts documents en masse out of an Oracle BLOB table. This is necessary for a huge rewrite and database conversion from Oracle to SQL where the files are going to be stored in an SQL file table. Since the documents have to sit on the file system, I have to get them out and write them out as files. It works great for MOST of my documents. After lots of banging my head on my desk, I finally figured out it's because there is some logic on the front end system that compresses some of the documents--although I really can't figure out the criteria for it doing that. At any rate, I've searched and searched and can't find any sort of Boolean check to see if they are compressed inside the Oracle BLOB table or not, before I extract them. If I try to decompress them ALL as I'm extracting them, I get an error on the ones that weren't compressed. So now I'm thinking I can run them all with the decompression, and then catch the exception and handle the others by exporting without the decompression. I just can't get my syntax correct in my script. This is a new challenge for me, and I don't have a ton of experience writing scripts of this sort, so please forgive my ignorance. Here's the error I get when I try to decompress all of them, so this is what I'm trying to catch:
ORA-29294: A data error occurred during compression or uncompression.
ORA-06512: at "SYS.UTL_SYS_COMPRESS", line 56
ORA-06512: at "SYS.UTL_SYS_COMPRESS", line 226
ORA-06512: at "SYS.UTL_COMPRESS", line 89
ORA-06512: at line 21
Here is the script:
DECLARE
CURSOR C1 IS Select FILE_ID || '---' || substr(DOCUMENTLOCATION,1,instr (DOCUMENTLOCATION,'.')-1)||'.doc' as FILE_NAME, FILE_BLOB, FILE_ID
From DOCUMENTS d inner join CASEJOURNAL c on d.FILE_ID = c.JOURNALENTRYID where (JOURNAL_ENTRY_TYPE = 117 or JOURNAL_ENTRY_TYPE = 3) AND c.DOCUMENTLOCATION Is Not Null AND d.MIME_TYPE = 'application/msword' AND FILE_ID between 1 and 10000;
v_blob_uncomp BLOB;
v_blob BLOB;
blob_length INTEGER;
out_file UTL_FILE.FILE_TYPE;
v_buffer RAW(32767);
chunk_size BINARY_INTEGER := 32767;
blob_position INTEGER := 1;
filename varchar2(255);
BEGIN
--Select BLOB file into variables
FOR I in C1
LOOP
filename := i.FILE_NAME;
v_blob_uncomp := UTL_COMPRESS.LZ_UNCOMPRESS(i.FILE_BLOB);
v_blob := i.FILE_BLOB;
-- Define the output directory
out_file := UTL_FILE.FOPEN('fileloc',filename,'wb',chunk_size);
--Get length of BLOB file and save to variable.
blob_length := DBMS_LOB.getlength(v_blob);
-- Write the data to the file
WHILE blob_position <= blob_length LOOP
IF blob_position + chunk_size - 1 > blob_length THEN
chunk_size := blob_length - blob_position + 1;
END IF;
DBMS_LOB.read(v_blob_uncomp, chunk_size, blob_position, v_buffer);
UTL_FILE.PUT_RAW(out_file, v_buffer, TRUE);
blob_position := blob_position + chunk_size;
END LOOP;
UTL_FILE.FCLOSE(out_file);
END LOOP;
END;
I know that the script works when I don't decompress any blobs, however the ones that were compressed don't open. It also works when I do the decompress on certain files that I know were compressed. I'm just trying to get this to work within my loop for ALL files somehow. TIA!
When you want to catch a particular Oracle error code in PL/SQL, you basically have two options:
A) catch all exceptions; in the handler, test whether the error message matches the one you are looking for; if so, handle it; if not, re-raise it. This would look something like:
BEGIN
v_blob := := UTL_COMPRESS.LZ_UNCOMPRESS(i.FILE_BLOB);
EXCEPTION
WHEN OTHERS THEN
IF sqlerrm LIKE 'ORA-29294%' THEN
v_blob := i.FILE_BLOB;
ELSE
RAISE;
END IF;
END;
B) declare an exception variable and map it to the specific error code you care about, then catch only that exception. This would look something like this:
DECLARE
compression_error EXCEPTION;
pragma exception_init ( compression_error, -29294 );
BEGIN
v_blob := UTL_COMPRESS.LZ_UNCOMPRESS(i.FILE_BLOB);
EXCEPTION
WHEN compression_error THEN
v_blob := i.FILE_BLOB;
END;
Either way, I'd suggest wrapping this in a function.
I also note that your code shown doesn't reset blob_position to 1 when it starts processing a new BLOB.
Instead of "try and fail" approach you may consider to use magic numbers:
Read few bytes from the beginning of the file, if it starts, lets say with 504B (PK), then there is a fat chance that it would be zip archive.

Oracle Data Backup

I'm using Oracle 11g. I wanted to move certain records from a table to a flat file. Is there are any utility to do the same like sqlldr. I created unix scripts to do the same but it was not doing the purpose. Please Help
You Can use UTL_FILE package for loading all the table data to flat file. Here is the sample code for that
DECLARE
p_file util_file.file_type;
l_table your_table_name.ROWTYPE;
l_delimited VARCHAR2(1) := '|';
BEGIN
p_file := utl_file.Fopen('<file_path>', '<file_name>', 'W');
FOR l_table IN (SELECT *
FROM your_table_name) LOOP
utl_file.Putline(p_file, l_table.col1
||l_delimited
||l_table.col2
||l_delimited
||l_table.col3
||l_delimited
||l_table.col4
||Chr(10));
END LOOP;
utl_file.Fclose_all();
END;
Check Oracle documentation on the package

Resources