Unloading and Loading BFILE Data Types

The BFILE data type has two pieces of information stored in it: the directory object for the file and the name of the file within that directory object.

You can unload BFILE columns using the ORACLE_DATAPUMP access driver by storing the directory object name and the file name in two columns in the external table. The procedure DBMS_LOB.FILEGETNAME will return both parts of the name. However, because this is a procedure, it cannot be used in a SELECT statement. Instead, two functions are needed. The first will return the name of the directory object, and the second will return the name of the file.

The steps in the following extended example demonstrate the unloading and loading of BFILE data types.

  1. Create a function to extract the directory object for a BFILE column. Note that if the column is NULL, then NULL is returned.
    SQL> CREATE FUNCTION get_dir_name (bf BFILE) RETURN VARCHAR2 IS
      2  DIR_ALIAS VARCHAR2(255);
      3  FILE_NAME VARCHAR2(255);
      4  BEGIN
      5    IF bf is NULL
      6    THEN
      7      RETURN NULL;
      8    ELSE
      9      DBMS_LOB.FILEGETNAME (bf, dir_alias, file_name);
     10      RETURN dir_alias;
     11    END IF;
     12  END;
     13  /
    
    Function created.
    
  2. Create a function to extract the file name for a BFILE column.
    SQL> CREATE FUNCTION get_file_name (bf BFILE) RETURN VARCHAR2 is
      2  dir_alias VARCHAR2(255);
      3  file_name VARCHAR2(255);
      4  BEGIN
      5    IF bf is NULL
      6    THEN
      7      RETURN NULL;
      8    ELSE
      9      DBMS_LOB.FILEGETNAME (bf, dir_alias, file_name);
     10      RETURN file_name;
     11    END IF;
     12  END;
     13  /
    
    Function created.
    
  3. You can then add a row with a NULL value for the BFILE column, as follows:
    SQL> INSERT INTO PRINT_MEDIA (product_id, ad_id, ad_graphic)
      2  VALUES (3515, 12001, NULL);
    
    1 row created.
    

    You can use the newly created functions to populate an external table. Note that the functions should set columns ad_graphic_dir and ad_graphic_file to NULL if the BFILE column is NULL.

  4. Create an external table to contain the data from the print_media table. Use the get_dir_name and get_file_name functions to get the components of the BFILE column.
    SQL> CREATE TABLE print_media_xt
      2  ORGANIZATION EXTERNAL
      3  (
      4    TYPE oracle_datapump
      5    DEFAULT DIRECTORY def_dir1
      6    LOCATION ('pm_xt.dmp')
      7  ) AS
      8  SELECT product_id, ad_id,
      9         get_dir_name (ad_graphic) ad_graphic_dir,
     10         get_file_name(ad_graphic) ad_graphic_file
     11  FROM print_media;
    
    Table created.
    
  5. Create a function to load a BFILE column from the data that is in the external table. This function will return NULL if the ad_graphic_dir column in the external table is NULL.
    SQL> CREATE FUNCTION get_bfile (dir VARCHAR2, file VARCHAR2) RETURN
    BFILE is
      2  bf BFILE;
      3  BEGIN
      4    IF dir IS NULL
      5    THEN
      6      RETURN NULL;
      7    ELSE
      8      RETURN BFILENAME(dir,file);
      9    END IF;
     10  END;
     11  /
    
    Function created.
    
  6. The get_bfile function can be used to populate a new table containing a BFILE column.
    SQL> CREATE TABLE print_media_int AS
      2  SELECT product_id, ad_id,
      3         get_bfile (ad_graphic_dir, ad_graphic_file) ad_graphic
      4  FROM print_media_xt;
    
    Table created.
    
  7. The data in the columns of the newly loaded table should match the data in the columns of the print_media table.
    SQL> SELECT product_id, ad_id,
      2         get_dir_name(ad_graphic),
      3         get_file_name(ad_graphic)
      4  FROM print_media_int
      5  MINUS
      6  SELECT product_id, ad_id,
      7         get_dir_name(ad_graphic),
      8         get_file_name(ad_graphic)
      9  FROM print_media;
    
    no rows selected