How to pass LOBs as parameters from Java to a Database Stored Procedure.

Date: 12-May-2003

Objective

After reading this document, you should be able to:

  • Create LOB(Large OBject) objects in a Java program and pass it as a parameter to a database stored procedure.
    This document illustrates the same by giving the code snippet and description.
  • Run the sample using the instructions provided.

Software Requirements

  • JDK1.3.x or above This can be downloaded from here.
  • Oracle9i Database Release 2 or later. This can be downloaded from here.
  • Oracle9i JDBC Driver. This can be downloaded from here.

Note: Oracle JDBC Driver is available with Oracle Database/client installation. If you have a database/client installation,
you need not download JDBC driver separately.

Description

LOBs or Large Objects, are designed to support the unstructured data that cannot be decomposed into standard components i.e they can't be broken down into any finer structure in terms of database storage. LOBs can store unstructured data and is optimized for large amounts of data such as text, graphic images, still video clips, full motion video, and sound waveforms. They provide a uniform way of accessing large unstructured data within the database or outside.

With Oracle 8 and above, there can be multiple LOB columns in a database table, which can also be of different types. The storage capacity of LOBs is upto 4GB.

Oracle supports the following two types of LOBs.

  • BLOB, CLOB, and NCLOB: These are stored in the database either in-line in the table or in a separate segment or tablespace.
    • BLOBs can store large amounts of binary data typically graphic images and pictures.
    • CLOBs can store large amounts of character data and are useful for storing unstructured XML documents.
    • NCLOB: consists of character data that corresponds to the national character set defined for the Oracle database.
  • BFILEs: These are stored as operating system files.
    • BFILE is a LOB whose value is composed of binary ("raw") data, and is stored outside the database tablespaces in a server-side operating system file.

Sample Scenario:
Lets assume a story table in the database having two columns, an id and a CLOB. The story text is stored in the CLOB column. A stored procedure updates the story table in the database. It accepts two input parameters: id and CLOB. Below is an example SQL code snippet:

Database preparation:

CREATE TABLE stories (id NUMBER(4), story CLOB);
INSERT INTO stories VALUES(1, EMPTY_CLOB());
COMMIT;

-- The following procedure updates the CLOB in the table.
CREATE OR REPLACE PROCEDURE updateStory(id NUMBER, colValue  IN CLOB) IS
 BEGIN
    UPDATE stories s SET  s.story = colValue

    WHERE s.id = id ;
    COMMIT;
 -- Exception handling.
  -- EXCEPTION
   --   WHEN OTHERS THEN
    -- <process exception here>
 END updateStory;
/
 	


We shall now look into different ways of passing CLOB to a database stored procedure. We can create and manipulate CLOB object in two ways:
With and without streaming the data. Data streaming is always recommended for large amount of data.

Below is the code snippet for both the ways.

Without Streaming the data and using oracle.sql.CLOB class

    .............
    .............
    
    // Using Oracle implementation of CLOB 
    import oracle.sql.CLOB;
    // IO Imports

    import java.io.Writer;
	
    /*
     * This method uses temporary clob to create the CLOB object.
     */
    private static CLOB getCLOB( String clobData )
                    throws Exception {
      CLOB tempClob = null;

      try {
        //  create a new temporary CLOB
        tempClob = CLOB.createTemporary( conn, true, CLOB.DURATION_SESSION );

        // Open the temporary CLOB in readwrite mode to enable writing
        tempClob.open( CLOB.MODE_READWRITE );

        // Get the output stream to write

        Writer tempClobWriter = tempClob.getCharacterOutputStream(  );

        // Write the data into the temporary CLOB
        tempClobWriter.write( clobData );

        // Flush and close the stream
        tempClobWriter.flush(  );
        tempClobWriter.close(  );

        // Close the temporary CLOB
        tempClob.close(  );

      } catch ( Exception exp ) {
	         // Free CLOB object
          tempClob.freeTemporary( );
          // do something
      }
      return tempClob;      

    }					
					

 

Calling the database procedure by using the above getCLOB method:

    ..............................
    ..............................
      CallableStatement cs = null;
      oracle.sql.CLOB clob = null;
      String clobData = null;
      .......................
      .......................
  
      // read the file whose content has to be passed as CLOB.
      String lineSep = System.getProperty("line.separator");
      BufferedReader br = new BufferedReader(new FileReader(filename));
      String nextLine = "";
      StringBuffer sb = new StringBuffer();
      while ((nextLine = br.readLine()) != null) {

        sb.append(nextLine);
        sb.append(lineSep);
      }
      // convert to string
      clobData = sb.toString();

      // call Stored DB procedure for updating clob column
      cs = (CallableStatement)
            conn.prepareCall( "begin updateStory(?,?); end;" ); 

      // Create the CLOB object from the getCLOB method listed above.
      clob = getCLOB(clobData);

      // Bind the columns values
      cs.setObject(1, "1" );

      cs.setObject(2, clob );

      ............................
      ............................

Creating CLOB object by streaming the data

    ..............................
    ..............................
  public void callUpdateUsingStream(String id, String filename )
       throws SQLException, FileNotFoundException {

    CallableStatement cs = null;
    .....................
    .....................
      conn.setAutoCommit(false);
      String fileName =  filename;


      // Open the sample file as a stream
      File file = new File(fileName);
      FileInputStream fin = new FileInputStream(file);

      // Call Stored DB procedure for updating clob column
      cs = (CallableStatement)
                  conn.prepareCall( "begin updateStory(?,?); end;" ); 
      // set id.
      cs.setObject(1, id );

      // use setAsciiStream to set the clob parameter.
      cs.setAsciiStream(2,fin,(int)file.length());

      cs.execute();
      conn.setAutoCommit(true);


    ............................
    ............................

Source Code:

Click here to see the full runnable source code.

Running the Java class

  • Copy the full source code to a directory and save it as TestCLob.java
  • Run the SQL script listed above to create the table and the stored procedure as SCOTT user in the database.
  • Edit TestClob.java and change the getConnection() method to use your own database parameters.
    // Connect to the database.
    conn = DriverManager.getConnection
    ("jdbc:oracle:thin:@<hostname>:<port>:<sid>",
    "scott", "tiger");
  • From a command prompt in the copied directory, set the classpath to include the
    Oracle JDBC driver class: classes12.zip or classes12.jar
  • Compile the TestClob class.
    Example:
    javac -d . TestClob.java
  • Run the class by giving values to the parameters.
    java TestClob <id> <filename> <flag>
    • <id> String value that denotes the id of the record to be updated.
    • <filename> String value that denotes the file to be uploaded as content in the clob column.
    • <flag> String value, can be either "true" or "False".
      "false" will use non-streaming way to update the CLOB using callUpdate() method.
      "true" will use streaming way to update thr CLOB using callUpdateUsingStreaming()method.
      Example:
      java TestClob "1" "d:\text.txt" "false"
  • Check the file size and the CLOB size in the database to verify the updated data by running the following query:
    SQL> SELECT DBMS_LOB.GETLENGTH(story) FROM stories

Resources

Sample Application References on OTN:

Summary

This document has tried to explain and illustrate how to create CLOB objects from a Java program and pass it to a database stored procedure.


Please enter your comments about this sample in the OTN Sample Code Discussion Forum.

E-mail this page
Printer View Printer View