OraLobEditor - Edit Oracle LOB (BLOB, CLOB) data »

Download OraLobEditor Free Trial »

Form http://www.dba-oracle.com/t_storing_insert_photo_pictures_tables.htm

Storing pictures and photos in Oracle tables


Photographs and pictures and Oracle BLOB data and 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. 

 

create table graphics_table (
  bfile_id number,
  bfile_desc varchar2(30),
  bfile_loc bfile,
  bfile_type varchar2(4))
  TABLESPACE appl_data
  storage (initial 1m next 1m pctincrease 0)
 /
Listing 3: Example Use of BFILE datatype in a Table

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.

 

SQL> INSERT INTO graphics_table
  2  VALUES(4,'April Book of Days Woodcut',bfilename('GIF_FILES','APRIL.JPG'),'JPEG');
1 row created.
SQL> INSERT INTO graphics_table
  2  VALUES(8,'August Book of Days Woodcut',bfilename('GIF_FILES','AUGUST.JPG'),'JPEG');
1 row created.
SQL> INSERT INTO graphics_table
  2  VALUES(13,'Benzene Molecule',bfilename('GIF_FILES','BENZNE.GIF'),'GIF');
1 row created.
.
.
.
SQL> INSERT INTO graphics_table
  2  VALUES(30,'',bfilename('GIF_FILES','SHAPIROS.GIF'),'GIF');
1 row created.
SQL> INSERT INTO graphics_table
  2  VALUES(31,'',bfilename('GIF_FILES','SODF5.GIF'),'GIF');
1 row created.
SQL> INSERT INTO graphics_table
  2  VALUES(32,'',bfilename('GIF_FILES','WAVRA-CL.GIF'),'GIF');
1 row created.
SQL> commit;
Commit complete.
Listing 4: Example Set of INSERT Commands to Load BFILE Locators Manually

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.

 

CREATE  OR REPLACE PROCEDURE get_bfiles(
                                        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 graphics_table '||CHR(10)||
             'VALUES (graphics_table_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;
/
Listing 5: Example Procedure for Loading BFILE Locators based on an External File List

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.

 

CREATE OR REPLACE PROCEDURE load_lob 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 bfile_id,bfile_desc,bfile_type FROM graphics_table;
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 bfile_loc INTO locator FROM graphics_table WHERE bfile_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 internal_graphics 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;
/
Listing 6: Example Procedure to Load BFILE values into Internal LOBs

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.