Hello I am trying to add images to table.
I made table:
CREATE TABLE program_images
(
image_id NUMBER,
image_filename VARCHAR2(50),
image BLOB
);
Then made directory where All images are:
Finaly made procedure, which insert images to table:
create or replace
PROCEDURE insert_image_file (p_id NUMBER, p_image_name IN VARCHAR2)
IS
src_file BFILE;
dst_file BLOB;
lgh_file BINARY_INTEGER;
BEGIN
src_file := BFILENAME ('image_DIR', p_image_name);
-- insert a NULL record to lock
INSERT INTO program_images
(image_id, image_filename, image
)
VALUES (p_id, p_image_name, EMPTY_BLOB ()
)
RETURNING image
INTO dst_file;
-- lock record
SELECT image
INTO dst_file
FROM program_images
WHERE image_id = p_id AND image_filename = p_image_name
FOR UPDATE;
-- open the file
DBMS_LOB.fileopen (src_file, DBMS_LOB.file_readonly);
-- determine length
lgh_file := DBMS_LOB.getlength (src_file);
-- read the file
DBMS_LOB.loadfromfile (dst_file, src_file, lgh_file);
-- update the blob field
UPDATE program_images
SET image = dst_file
WHERE image_id = p_id AND image_filename = p_image_name;
-- close file
DBMS_LOB.fileclose (src_file);
END insert_image_file;
Is that when I call procedure: EXECUTE insert_image_file(1,'audi_logo.png'); it says me that "non-existent directory or file for FILEOPEN operation" in procedure what is " DBMS_LOB.fileopen (src_file, DBMS_LOB.file_readonly);" this line.
It was first time I use directories, so maybe I forget something to do?
The image directory name should be all UPPER_CASE, i.e.
src_file := BFILENAME ('IMAGE_DIR', p_image_name);
Per the docs for BFILENAME:
The directory argument is case sensitive. You must ensure that you specify the
directory object name exactly as it exists in the data dictionary.
Related
I found the way here, how to copy a clipboard image to a region, ad it works well. But I didn't find how can I save this picture into my blob field. Which variable contains the image (maybe it is a javascript variable), and how can I refer to it in the SQL expression (e.g. in a dynamic action)?
create a process like this:
declare
doc_size integer;
Upload_blob blob;
begin
--Copy BLOB to Upload_blob variable
select blob_content into Upload_blob from APEX_APPLICATION_TEMP_FILES where name = :FILE_BROWSER;
--Get BLOB size
doc_size := dbms_lob.getlength(Upload_blob);
--Copy data to table MyIMAGES_TBL
if doc_size <= 1000000 then
insert into MyIMAGES_TBL ( IMAGE_NAME, FILENAME, MIME_TYPE, DOC_SIZE, CONTENT ) select :FILE_NAME, filename, mime_type, doc_size, blob_content from APEX_APPLICATION_TEMP_FILES where name = :FILE_BROWSER;
--Delete temp files delete from APEX_APPLICATION_TEMP_FILES where name = :FILE_BROWSER;
else delete from APEX_APPLICATION_TEMP_FILES where name = :FILE_BROWSER;
commit;
raise_application_error(-20001,'Cannot upload pictures bigger than 1MB!');
end if;
exception when others then raise_application_error(-20001,'Error when uploading image!');
end;
I need to update a preexisting BLOB value in table using PL/SQL.
I'm dealing with poor table design, the column should be CLOB and that is not going to change.
The steps I want to perform:
1) select the BLOB
2) convert the BLOB to CLOB
3) modify the CLOB
3) convert the CLOB to BLOB
4) update the BLOB column with the new value
The 4th step I don't know how to do. I was hoping the BLOB could be updated directly but the only examples I find are reading a file into a blob column or using another programming language.
I understand your question, but i think there has to be another problem.
Solution
Just update it..
UPDATE myTable SET myBlobColumn = myBlob WHERE myCondition = 1;
Complete Example
DECLARE
myVarcharVar VARCHAR2(1000);
myClobVar CLOB;
myBlobVar BLOB;
BEGIN
EXECUTE IMMEDIATE 'TRUNCATE TABLE TTEST'; -- ensure out testdata will be correct.
INSERT INTO TTEST (myBlob, myClob, myVarchar) VALUES(utl_raw.cast_to_raw('1111'), '2222', '3333'); -- insert our data
-- Attention: ONLY ONE ROW => NO WHERE-CONDITIONS to simplify the code!
SELECT myVarchar INTO myVarcharVar FROM TTEST;
UPDATE TTEST SET myClob = myVarcharVar;
SELECT myClob INTO myClobVar FROM TTEST;
UPDATE TTest SET myBlob = utl_raw.cast_to_raw(myClobVar);
SELECT myBlob, myClob, myVarchar INTO myBlobVar, myClobVar, myVarcharVar FROM TTest;
dbms_output.put_line('Blob: ' || utl_raw.cast_to_varchar2(myBlobVar));
dbms_output.put_line('Clob: ' || myClobVar);
dbms_output.put_line('Varchar:' || myVarcharVar);
END;
update table_name set column_name = utl_raw.cast_to_raw ('value') where id = 'your_id';
Hi I am new to XML file handling in Oracle. I was lookig at a code which loads XML into a database column from an external file. I have some doubts .
CREATE OR REPLACE DIRECTORY xml_dir AS 'c:temp';
CREATE TABLE xml_tab (
id NUMBER(10),
filename VARCHAR2(100),
xml XMLTYPE
)
/
ALTER TABLE xml_tab ADD (
CONSTRAINT xml_tab_pk PRIMARY KEY (id)
)
/
CREATE SEQUENCE xml_tab_seq;
CREATE OR REPLACE PROCEDURE load_xml (p_dir IN VARCHAR2,
p_filename IN VARCHAR2) AS
l_bfile BFILE := BFILENAME(p_dir, p_filename);
l_clob CLOB;
BEGIN
DBMS_LOB.createtemporary (l_clob, TRUE);
DBMS_LOB.fileopen(l_bfile, DBMS_LOB.file_readonly);
DBMS_LOB.loadfromfile(l_clob, l_bfile, DBMS_LOB.getlength(l_bfile));
DBMS_LOB.fileclose(l_bfile);
INSERT INTO xml_tab (
id,
filename,
xml
)
VALUES (
xml_tab_seq.NEXTVAL,
p_filename,
XMLTYPE.createXML(l_clob)
);
COMMIT;
DBMS_LOB.freetemporary (l_clob);
END;
/
Doubts-
Is it necessary to do it? What's the purpose?DBMS_LOB.createtemporary (l_clob,TRUE)
Instead of doing XMLTYPE.CreateXML(l_clob) can we do XMLTYPE(l_clob)? What's the difference between this two ?
I know these are basic question but I am trying to understand the root cause.
IS it possible to concatenate A1 and A2 from the particular table (for example):
CREATE TABLE MY_SCHEME.CONC_BLOB
(
A1 BLOB,
A1_SORT NUMBER(20),
T_TYPE VARCHAR2(9 BYTE),
A2 BLOB,
A2_SORT NUMBER(20),
A3 VARCHAR2(32 BYTE),
A4 BLOB,
A5 VARCHAR2(8 BYTE)
)
?
How?
BLOBs can be concatenated with the DBMS_LOB package, in particular with the APPEND procedure. But you will need to use some PL/SQL that iterates over the relevant rows and calls the procedure.
I don't quite understand what you mean by next table so I can't give you an example.
Update:
The relevant piece of PL/SQL could look like this:
DECLARE
a1_lob BLOB;
a2_lob BLOB;
BEGIN
SELECT A1, A2 INTO a1_lob, a2_lob
FROM CONC_BLOB
WHERE A1_SORT = 'some value'
FOR UPDATE;
dbms_lob.append(a1_lob, a2_lob);
COMMIT;
END;
FYI: if you intent to use blob to store large text (that's why I suppose you would like to concatenate them) I suggest using CLOB. It will permit you to use || for the best part of concatenations. Unfortunately you could face with the issue of || when the length of clob exceeds 32767
Here is my solution for joining any number of BLOBs into single BLOB using helper table type and stored function:
create or replace type blobs as table of blob;
create or replace function concat_blobs(parts in blobs) return blob
is
temp blob;
begin
if parts is null or parts.count = 0 then
return null;
end if;
dbms_lob.createtemporary(temp, false, dbms_lob.CALL);
for i in parts.first .. parts.last
loop
dbms_lob.append(temp, parts(i));
end loop;
return temp;
end;
-- usage example:
select concat_blobs(blobs(to_blob(hextoraw('CAFE')), to_blob(hextoraw('BABE')))) from dual;
-- bonus
create or replace type raws as table of raw(2000);
create or replace function raws_to_blobs(arg in raws) return blobs
is
res blobs;
begin
select to_blob(column_value) bulk collect into res from table(arg);
return res;
end;
-- usage example:
select concat_blobs(raws_to_blobs(raws(hextoraw('CAFE'), hextoraw('BABE'))) from dual;
See also multiple RAWs concatenation in Oracle 10: Using HEXTORAW to fill in blob data.
Create or replace package body file as
procedure filehandler as
declare
V_PERSON PERSON%ROWTYPE;
FID UTL_FILE.FILE_TYPE;
FOLDER_NAME VARCHAR(50) := 'GID_FILE';
FILE_NAME VARCHAR(50) :='bhanu.txt';
cusor test_persondetails is
select personid, personnum,fullnm from person where rownum<=10;
begin
open test_persondetails;
FID := UTL_FILE.FOPEN (FOLDER_NAME, FILE_NAME, 'A');
fetch test_persondetails into V_person;
DBMS_OUTPUT.PUT_LINE(V_PERSON);
UTL_FILE.PUT_LINE (FID,V_PERSON);
UTL_FILE.FCLOSE (FID);
close test_persondetails;
end test_filehandler;
end test_file;
i am getting some errors related to the fetch statement , can you please suggest me the changes that can be done that code......
You need to tell us which errors you get, as looking at your source there are potentially many of them.
For instance your cursor will select up to ten rows. However you are not executing a loop, so your fetch will hurl TOO_MANY_ROWS if there is more than one row in the PERSON table.
Also, you need to explicitly reference the individual elements of the cursor not the %ROWTYPE variable.
Furthermore, the projection of the query must match the variable you fetch into (number of columns, datatype of columns, etc). It is easier to use the CURSOR FOR syntax, and let Oracle handle it for us. This also solves the TOO_MANY_ROWS problem.
So I would rewrite your code to look like this:
procedure filehandler as
FID UTL_FILE.FILE_TYPE;
FOLDER_NAME VARCHAR(50) := 'GID_FILE';
FILE_NAME VARCHAR(50) :='bhanu.txt';
begin
FID := UTL_FILE.FOPEN (FOLDER_NAME, FILE_NAME, 'A');
for V_PERSON in ( select personid, personnum,fullnm
from person where rownum<=10 )
loop
DBMS_OUTPUT.PUT_LINE(V_PERSON.personid);
UTL_FILE.PUT_LINE (FID,V_PERSON.personid
||' '||V_PERSON.personnum
||' '||V_PERSON.fullnm);
end loop;
UTL_FILE.FCLOSE (FID);
end test_filehandler;
Opening and closing the file for each line is not wrong, just slower than need be.
My guess is that the table contains more than the 3 columns you are selecting, and so trying to fetch those 3 columns into a record whose structure included all the columns of the table will fail. Change the record definition to:
V_PERSON test_persondetails%rowtype;
and move to to after the cursor definition.