Entering content frame

Function documentation Using Locators Locate the document in its SAP Library structure

Use

Locators are logical pointers to the LOBs in the database.

You can use locators to read and write BLOB and CLOB columns with both JDBC and SQLJ. This is advantageous if you need to copy the contents between table columns of (different) tables, for example. It is also advantageous if you need to determine only the length of the data.

However, you should be aware that there are certain limitations.

Activities

Reading LOBs Using Locators

Locators are independent of the result sets. BLOB and CLOB locators are accessed using instances of java.sql.Blob and java.sql.Clob, which are returned by the getBlob() and getClob() methods of java.sql.ResultSet. A locator is valid as long as the transaction in which it has beencreated lasts. Therefore, it may remain open even if the result set is closed, unless the autocommit mode is enabled.

The contents of the LOB can be read using the getSubString() and getCharacterStream() methods of the Clob object or using the getBinaryStream() and getBytes() of the Blob object. On a particular instance of Blob or Clob, these methods must be invoked at most once. The following example uses a Blob object to read the intro of a song. The contents of the LOB is read using the Blob.getBytes() method.

Example

Reading BLOB with JDBC using a locator

byte[] getIntro(Connection conn, int songId, int bytes) throws SQLException {

   PreparedStatement stmt = conn.prepareStatement("SELECT song FROM songs WHERE id = ?");

   try {

      ResultSet rs = stmt.executeQuery();

      try {

         if (rs.next()) {

            Blob blob = rs.getBlob(1);

            return blob.getBytes(1, bytes);   

         } else {

            return null;

         }

      } finally {

         rs.close();

      }

   } finally {

   stmt.close();

}

 

You can use locators in SQLJ as host variables in an SQLJ single row query, a FETCH statement or an iterator. You can implement the above example using SQLJ as follows:

Example

Reading a BLOB with SQLJ using locators

byte[] getIntro(Connection conn, int songId, int length) throws SQLException {   

 

java.sql.Blob blob = null;

 

   #sql [ctx] { SELECT song

                INTO :blob

                FROM songs

                WHERE id = :songId

};

   return blob.getBytes(1, length);  

}

 

Caution

Currently, only the methods specified by JDBC 2.0 (J2SE 1.3) are supported. They enable reading of the LOB data only. The application must access the Blob and Clob objects through the JDBC interfaces and has no access to the database-specific implementations.

Writing LOBs Using Locators

Data can be written to a BLOB or CLOB columns using the setBlob() and setClob()methods of java.sql.PreparedStatement.

The java.sql.Blob and Clob objects can be used in SQLJ as IN host variables in INSERT and UPDATE statements.

Using Blob and Clob with Open SQL has certain limitations:

·        Open SQL supports only the methods of Blob and Clob as specified in JDBC 2.0. This means, that you cannot write to or construct a Blob or Clob object. Therefore, you can use a Blob and Clob object in an INSERT or UPDATE statement only if you have read it in the same transaction.

·        A particular instance of a Blob or Clob object must not be used repeatedly as the argument of a setBlob() or setClob() method or as an IN host variable in SQLJ. Moreover, if batching is used, a particular instance of Blob or Clob must not be used as a parameter in multiple rows of the same batch. Furthermore, if a locator is used as a parameter in a batch, this parameter must be set with a different locator in every row of the batch and must not be left unchanged.

The following example demonstrates the use of locators for copying the contents of LOB columns.

Example

Writing to a BLOB with JDBC using a locator

private static final int DEFAULT_IMAGE_ID;

...

int newImageId = ...;

 

PreparedStatement select = conn.prepareStatement("SELECT image FROM images WHERE id = ?");

try {

   select.setInt(1, DEFAULT_IMAGE_ID);

   ResultSet rs = select.executeQuery();

   try {

      rs.next();

      Blob image = rs.getBlob(1);

      PreparedStatement insert =

         conn.prepareStatement("INSERT INTO images (id, image) VALUES (?, ?)");

      try {

         insert.setInt(1, newImageId);

         insert.setBlob(2, image);

         insert.executeUpdate();

      } finally {

         insert.close();

      }

   } finally {

      rs.close();

   }

} finally {

   select.close();

}

 

The same example can be implemented using SQLJ as follows.

Example

Writing to a BLOB with SQLJ using a locator

private static final int DEFAULT_IMAGE_ID;

int newImageId = ...;

java.sql.Blob image;

 

#sql [ctx] { SELECT image

          INTO :blob

          FROM images

          WHERE id = DEFAULT_IMAGE_ID

};

 

#sql [ctx] { INSERT INTO images (id, image)

          VALUES (:newImageId, :blob)

};

 

 

Leaving content frame