Images and Oracle BLOB data are easy to add to a Oracle table. There are
two ways to load BLOBs and CLOBs into the database. The first method uses
PL/SQL and the DBMS_LOB package and the BFILE datatype to transfer external LOB
files into the database internal LOB structures. The second uses the Oracle
Call Interface (OCI) to perform the same function. Let's look at the first
method.
To load external LOB data into internal LOB storage using PL/SQL alone you must first use a table containing BFILE locators for the files to allow Oracle to access them.
To load external LOB data into internal LOB storage using PL/SQL alone you must first use a table containing BFILE locators for the files to allow Oracle to access them.
Notice
in the above code that no LOB storage clause is specified. This is because all
that is stored in the database is a locator value for the BFILE consisting of
an internal DIRECTORY specification and a file name. The BFILE locators are
loaded into the table using the BFILENAME function and a standard insert
statement.
An
example of this process is shown here in Listing 4.
commit;
TIP:
Using a host command to perform a single column directory
listing into a file (for example on NT: dir /B >file.lis), then using the
UTL_FILE package to read the contents of the created file into the DBMS_SQL
package to build the INSERT commands on the fly, an entire directory of LOB
datafiles can be loaded at one time into a BFILE table and then on into the
internal LOB storage table. For an example see Listing 5.
bfile_dir IN VARCHAR2
, bfile_lis IN VARCHAR2
, bfile_int_dir VARCHAR2
)
AS
cur INTEGER;
bfile_int VARCHAR2(100);
sql_com VARCHAR2(2000);
file_proc INTEGER;
file_hand UTL_FILE.file_type;
file_buff VARCHAR2(1022);
file_type VARCHAR2(4);
BEGIN
bfile_int := UPPER(bfile_int_dir);
file_hand := UTL_FILE.fopen(bfile_dir
, bfile_lis
, 'R'
);
LOOP
BEGIN
UTL_FILE.get_line(file_hand
, file_buff
);
cur := DBMS_SQL.open_cursor;
file_type := SUBSTR(file_buff
, INSTR(file_buff
, '.'
) + 1
, 3
);
file_type := UPPER(file_type);
IF file_type = 'GIF'
THEN
file_type := 'GIF';
ELSIF file_type = 'JPG'
THEN
file_type := 'JPEG';
END IF;
sql_com :=
'INSERT INTO xx_images_tbl '
|| CHR(10)
|| 'VALUES (xx_images_tbl_seq.NEXTVAL,'
|| CHR(39)
|| CHR(39)
|| ', bfilename('
|| CHR(39)
|| bfile_int
|| CHR(39)
|| ','
|| CHR(39)
|| file_buff
|| CHR(39)
|| ') ,'
|| CHR(39)
|| file_type
|| CHR(39)
|| ')';
DBMS_OUTPUT.put_line(sql_com);
DBMS_SQL.parse(cur
, sql_com
, DBMS_SQL.v7
);
file_proc := DBMS_SQL.EXECUTE(cur);
DBMS_SQL.close_cursor(cur);
EXCEPTION
WHEN NO_DATA_FOUND
THEN
EXIT;
END;
END LOOP;
UTL_FILE.fclose(file_hand);
END;
/
Once
the BFILE locators are set in the BFILE table we can use the DBMS_LOB package
to read the external LOB (BFILE) into an internal LOB (BLOB, CLOB or NCLOB).
This is shown in Listing
6. The SELECT from the TEMP_BLOB table initializes the
internal LOB values so they can be used, otherwise an error will be returned.
AS
ID NUMBER;
image1 BLOB;
LOCATOR BFILE;
bfile_len NUMBER;
bf_desc VARCHAR2(30);
bf_name VARCHAR2(30);
bf_dir VARCHAR2(30);
bf_typ VARCHAR2(4);
ctr INTEGER;
CURSOR get_id
IS
SELECT file_id
, file_desc
, file_type
FROM xx_images_tbl;
BEGIN
OPEN get_id;
LOOP
FETCH get_id
INTO ID
, bf_desc
, bf_typ;
EXIT WHEN get_id%NOTFOUND;
DBMS_OUTPUT.put_line('ID: ' || TO_CHAR(ID));
SELECT file_loc
INTO LOCATOR
FROM xx_images_tbl
WHERE file_id = ID;
DBMS_LOB.filegetname(LOCATOR
, bf_dir
, bf_name
);
DBMS_OUTPUT.put_line('Dir: ' || bf_dir);
DBMS_LOB.fileopen(LOCATOR
, DBMS_LOB.file_readonly
);
bfile_len := DBMS_LOB.getlength(LOCATOR);
DBMS_OUTPUT.put_line('ID: ' || TO_CHAR(ID) || ' length: ' || TO_CHAR(bfile_len));
SELECT temp_blob
INTO image1
FROM temp_blob;
bfile_len := DBMS_LOB.getlength(LOCATOR);
DBMS_LOB.loadfromfile(image1
, LOCATOR
, bfile_len
, 1
, 1
);
INSERT INTO xx_images_tbl
VALUES (ID
, bf_desc
, image1
, bf_typ
);
DBMS_OUTPUT.put_line(bf_desc || ' Length: ' || TO_CHAR(bfile_len) || ' Name: ' || bf_name || ' Dir: ' || bf_dir || ' ' || bf_typ);
DBMS_LOB.fileclose(LOCATOR);
END LOOP;
END;
/
/
By
enforcing a naming standard on the external LOB files the loading procedure in
Listing 6.6 could be modified to place BLOB types into BLOBs, CLOB types into
CLOBs and NCLOB types into NCLOBs based on the file type values that are parsed
from the file extensions in Listing 5. Between the procedure in Listing 5 and
the one shown in Listing 6 the example tables in Listings 1 and 3 are populated
with LOB values located in a specific directory.
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.