How to declare Windows path in Oracle PLSQL - oracle

I need to burn a blob column from an image that is saved in windows.
How do I declare the image path in Oracle PLSQL?
Ex:
DECLARE
dest_lob BLOB;
-- this line report ORA22285 "non-existent directory or file for %s operation"
src_lob BFILE := BFILENAME('MY_DIR', 'C:\Users\gus\Desktop\image.jpg');
BEGIN
INSERT INTO teste_gustavo_blob VALUES(2, EMPTY_BLOB())
RETURNING imagem INTO dest_lob;
DBMS_LOB.OPEN(src_lob, DBMS_LOB.LOB_READONLY);
DBMS_LOB.LoadFromFile( DEST_LOB => dest_lob,
SRC_LOB => src_lob,
AMOUNT => DBMS_LOB.GETLENGTH(src_lob) );
DBMS_LOB.CLOSE(src_lob);
COMMIT;
END;
Note: I'm trying to insert a record into a table through a Windows machine using SQLDeveloper. The database is on a remote server.

the path needs to be part of the directory object definition, and the file name is just that - just the file name. Example;
CREATE DIRECTORY MY_DIR AS 'C:\Users\gus\Desktop';
..
BFILENAME('MY_DIR', 'image.jpg');
Note that the directory is created on the server not your local machine. So if you are trying to create a file on a local machine, this will not work in pl/sql. PL/sql runs on the server, not the client. In that case, you need to code a client.

The database can only see directories which are local to it. It cannot see files on your PC (unless the database is running on that PC). So you cannot load your file through PL/SQL.
However, you say you are using SQL Developer. You can load a BLOB by editing the table's data in the Table Navigator. Click on the Data tab then edit the cell (the BLOB column of the row you want to load the file into). Use the Local Data > Load option to upload your file. That Jeff Smith has publish a detailed step-by-step guide on his blog.

I had a similar problem recently. I needed to dev test a feature and I needed a PDF file in my DB. I read few questions here and formulated an answer. I inserted a row manually with SQL and changed the file manually after that.
The SQL:
insert into ATTACHMENT_TABLE (id, file_content) values
(1, utl_raw.cast_to_raw('some dummy text'));
Using DBeaver, I edited the row and loaded the file from my windows PC. The end result is a row which contains the PDF file I wanted.

Related

Using UTL_FILE in ADW

Is there anyway I can use UTL_FILE in Autonomous Database to an Object Storage or another Cloud storage? I am asking that because we can't use OS files in ADB.
Here an example of the line but in on-premise env. :
UTL_FILE.PUT_LINE(v_file, 'col1,col2,col3');
Filesystem directories are supported, and documented here. Any file you put in the filesystem will count against your storage, just to make sure you are aware.
You can use UTIL_FILE to write to the database file system followed by DBMS_CLOUD.PUT_OBJECT to copy that file a bucket in object store. Use DBMS_CLOUD.DELETE_FILE to delete the file from the database object store if needed. I do it all the time and it works well.
My guess is the p_dir is a parameter to a PL/SQL procedure. If that's the case, p_dir should be set to a value equal to a valid database directory object. DATA_PUMP_DIR exists by default in ADW, so it could be something like this:
BEGIN
my_file_proc(
p_file => 'my_file.csv',
p_dir => 'DATA_PUMP_DIR');
END;

What is the most efficient way to upload binary (BLOB) content just using sqlplus

My use case is to deliver and install binary files into Oracle tables.
The files are available locally on my site and must be installed at several client sites only by using sqlplus.
I currently do this by locally using a Python script that loads the files and then generates a sql script with blocks like the following one.
The scripts are then distributed to the clients and run using sqlplus.
This method works, but has the following disavantages:
the sql scripts can be really big if many and/or large binary files must be uploaded
running the sql scripts can be quite slow if and/or binary files must be uploaded
I was wondering, if someone came up with a better solution or would now how to improve this?
example.sql
DECLARE
l BLOB;
PROCEDURE i(t IN VARCHAR2) IS BEGIN dbms_lob.append(l, utl_encode.base64_decode(utl_raw.cast_to_raw(t))); END i;
BEGIN
dbms_lob.createtemporary(lob_loc=>l, cache=>FALSE, dur=>dbms_lob.session);
i('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');
i('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');
INSERT INTO BinaryResources (filename, mimeType, content) VALUES ('DOC.JPG', 'image/jpeg', l);
dbms_lob.freetemporary(lob_loc=>l);
END;
/
Your python script should make a connection to an Oracle instance. Then your python script can parse (i.e., prepare) the SQL statement text INSERT INTO BinaryResources (filename, mimeType, content) VALUES (?, ?, ?).
Then you bind placeholder values to the cursor (a string, a string, a blob). You create a blob with whatever python-Oracle provider functions are provided.
Use the array insert execute method after filling an array that is at least 2-4k in size.

How to open PDF File From oracle forms 11g?

I am using Oracle Database 11gR2 with Oracle Forms 11gR2. I have PDF File Saved on Server Machine. I created button with Name "HELP" Manual PDF File. Now i want when user click on button on their local machine then PDF File open from server machine.
I found this code:
host('rundll32 url.dll,FileProtocolHandler c:\file_name.pdf');
Is this code run correctly? Oracle Forms 11g
You can create such a Procedure within your form :
Procedure Pr_Print( i_document varchar2 ) Is
pl_id paramlist;
pl_list paramlist;
my_rep_server varchar2(500);
Begin
pl_list := Get_Parameter_List('tmpdata');
if not Id_Null(pl_list) then
Destroy_Parameter_List(pl_list);
end if;
pl_list := Create_Parameter_List('tmpdata');
set_report_object_property('RP2RRO', report_filename, i_document );
set_report_object_property('RP2RRO', report_server, my_rep_server);
add_parameter(pl_id, 'column1', text_parameter, :col1 );
add_parameter(pl_id, 'column2', text_parameter, :col2 );
rp2rro.rp2rro_run_product(reports, i_document, synchronous, runtime,
filesystem, pl_id, null);
End;
where rp2rro.rp2rro_run_product is a method coming from rp2rro.pll ( a binary library module supplied by Oracle ),
assuming you have col1 and col2 text fields in it.
And call it from a button's WHEN-BUTTON-PRESSED trigger with the code :
Pr_Print('myDocument');
P.S. the library rp2rro.pll should be installed and configured within the application server, too. Since Reports 11g runs on app. server as a web-based application.
I think you can use WEB.SHOW_DOCUMENT(url,’_blank’); in your WHEN-BUTTON-PRESSED trigger

dbms_datapump.get_dumpfile_info can't read directory when compiled in stored procedure

I'm creating a stored procedure to load (impdp) a Datapump database dump.
I am trying to get the dump file's creation date (to compare with the date of a previously loaded dump), using DBMS_DATAPUMP.GET_DUMPFILE_INFO, like in this example.
When running in an anonymous block (like below), it runs fine, outputting the dump file's creation date. However, when this same block is adapted and compiled in a stored procedure, I get the ORA-39087 error (Directory name is invalid).
DECLARE
dumpfile VARCHAR2(256) := 'my_file.dp';
dir VARCHAR2(30) := 'MY_DIR';
info ku$_dumpfile_info;
ft NUMBER;
BEGIN
sys.dbms_datapump.get_dumpfile_info(dumpfile, dir, info, ft);
FOR rec IN (SELECT * FROM TABLE (info) WHERE item_code = 6 ) LOOP
dbms_output.put_line(rec.value);
END LOOP;
END;
The directory exists. The name is valid. When I run
SELECT * FROM datapump_dir_objs;
with the same user, I can see that the user has READ and WRITE privileges on the directory. Oracle version is 11g Release 11.2.0.4.0.
Any light on what I am doing wrong?
Thanks in advance.
The problem was that the READ and WRITE privileges on the directory were added via a role. By default, anonymous blocks are executed with the current user's privileges, but stored procedures are not.
I added AUTHID CURRENT_USER to the procedure's header and managed to access my directory.
Thanks to Alex Poole for the insight.

Oracle: export a table with blobs to an .sql file that can be imported again

I have a table "Images" with two fields:
Name VARCHAR2
Data BLOB
I would like to export that table to a .sql file which I could import on another system. I tried to do so using the "Database unload" assistant of Oracle SQL Developer. However the generated file does just have the content for the names in it but not the data. Thus after importing I would end up with all the names but the data field would be null everywhere.
I'd really prefer it just to be one file (I saw some examples that included dumping the data to one file per field on the fs...)
Is it possible to generate such a script with SQL Developer? or is there any other way/tool to do so?
I don't think this is possible with SQL Developer (but then I don't use it very often).
The SQL client I am using - SQL Workbench/J - can do this.
There are several ways to export this data.
Generate a proprietary script
It can create a SQL script that uses a special (tool specific) notation to reference an external file, something like:
INSERT INTO images
(name, data)
VALUES
('foobar', {$blobfile='blob_r1_c2.data'});
The above statement can only be executed with SQL Workbench again. It is not compatible with any other SQL client.
Use utl_raw
Another alternative is to use a "blob literal", but due to Oracle's limit on 4000 bytes for a character literal, this only works for really small blob values:
INSERT INTO images
(name, data)
VALUES
('foobar', to_blob(utl_raw.cast_to_raw('......')));
where the character literal for the cast_to_raw call would contain the hex values of the BLOB. As this requires 2 characters per "blob byte", you can't handle BLOBs larger than 2000 bytes with that. But that syntax would work for nearly all Oracle SQL tools (if they can handle scripts with very long lines).
SQL*Loader input file
The third alternative is to export the data into a text file that can be imported using SQL*Loader:
The text file would contain something like this:
NAME DATA
foobar blob_r1_c2.data
Together with the following SQL*Loader control file:
OPTIONS (skip=1)
LOAD DATA CHARACTERSET 'WE8ISO8859P15'
INFILE 'images.txt'
APPEND
INTO TABLE IMAGES
FIELDS TERMINATED BY '\t' TRAILING NULLCOLS
(
NAME,
lob_file_data FILLER,
DATA LOBFILE(lob_file_data) TERMINATED BY EOF
)
This can be loaded using SQL*Loader and is thus doesn't need SQL Workbench to import the data.
More details are in the manual
Edit
As Alex has pointed out in his comment, you can also use a DataPump export - but that requires that you have access to the file system on the server. The above solutions all store the data on the client.
If you absolutely need to use a single .sql file to import the BLOB you can generate the script using PL/SQL:
set serveroutput on
declare
lob_in blob;
i integer := 0;
lob_size integer;
buffer_size integer := 1000;
buffer raw(32767);
begin
select
data, dbms_lob.getlength(data)
into lob_in, lob_size
from images
where name = 'example.png';
for i in 0 .. (lob_size / buffer_size) loop
buffer := dbms_lob.substr(lob_in, buffer_size, i * buffer_size + 1);
dbms_output.put('dbms_lob.append(lob_out, hextoraw(''');
dbms_output.put(rawtohex(buffer));
dbms_output.put_line('''));');
end loop;
end;
Its output will be the BLOB's content encoded like:
dbms_lob.append(lob_out, hextoraw('FFD8FFE0...0000'));
dbms_lob.append(lob_out, hextoraw('00000000...0000'));
...
dbms_lob.append(lob_out, hextoraw('007FFFD9'));
Which you can load into an already inserted row with PL/SQL:
declare
lob_out blob;
begin
select data into lob_out
from images
where name = 'example.png'
for update;
dbms_lob.append(lob_out, hextoraw('FFD8FFE0...0000'));
dbms_lob.append(lob_out, hextoraw('00000000...0000'));
...
dbms_lob.append(lob_out, hextoraw('007FFFD9'));
end;
Just remember the resulting .sql file will be huge.
Thx for your answer. I used the third alternative.
First I downloaded SQL Workbench/J. Then I used the following command to make an export:
WbExport -type=text -file='c:\temp\Images' delimiter='|' -decimal=',' -sourcetable=Images -formatfile=oracle;
This produced a Images.txt file and many Images_r*_c2.data files and a Images.ctl file.
I could then use the following command to import:
sqlldr myuser#myhost/mypassword control=Images.ctl
This is definitely possible in SQL developer.
First you need to export the table in the source location choosing
appropriate table(s).
Tools > Database Export
Select output format as loader rather than insert , excel which we
normally use.
Following these steps would create sqlldr control files and data files and also the create table ddl if you chose the option.You can use them to import(sqlldr) data in the destination.
This is a better solution and is portable in terms of extraction and distribution . It gives the flexibility of delivering components to be deployed through code repositories.
Here is a link that explains it step by step.
Exporting Multiple BLOBs with Oracle SQL Developer
SQL workbench uses a special file format for blob data, in addition to .sql. If you can accept such files, an even simpler solution is to use Oracle's Original import and export. (It is deprecated, but unlike Oracle's DataPump, it does not require access rights on the server.)
Here is a nice tutorial on the export part.

Resources