Movatterモバイル変換


[0]ホーム

URL:


Go to main content
22/52

11 Accessing and Manipulating Oracle Data

This chapter describes data access inoracle.sql.* formats, as opposed to standard Java formats. Usingoracle.sql.* formats involves casting your result sets and statements toOracleResultSet,OracleStatement,OraclePreparedStatement, andOracleCallableStatement, as appropriate, and using thegetOracleObject,setOracleObject,getXXX, andsetXXX methods of these classes, whereXXX corresponds to the types in theoracle.sql package.

This chapter covers the following topics:

Data Type Mappings

The Oracle JDBC drivers support standard JDBC types as well as Oracle-specific data types. This section documents standard and Oracle-specific SQL-Java default type mappings. This section contains the following topics:

Table of Mappings

Table 11-1 shows the default mappings between SQL data types, JDBC type codes, standard Java types, and Oracle extended types.

The SQL Data Types column lists the SQL types that exist in Oracle Database 11g. The JDBC Type Codes column lists data type codes supported by the JDBC standard and defined in thejava.sql.Types class or by Oracle in theoracle.jdbc.OracleTypes class. For standard type codes, the codes are identical in these two classes.

The Standard Java Types column lists standard types defined in the Java language. The Oracle Extension Java Types column lists theoracle.sql.* Java types that correspond to each SQL data type in the database. These are Oracle extensions that let you retrieve all SQL data in the form of aoracle.sql.* Java type. Manipulating SQL data asoracle.sql.* data types minimizes conversions, improving performance and eliminating conversion losses.

See Also:

"Package oracle.sql"

Table 11-1 Default Mappings Between SQL Types and Java Types

SQL Data TypesJDBC Type CodesStandard Java TypesOracle Extension Java Types
 

STANDARD JDBC TYPES:

  

CHAR

java.sql.Types.CHAR

java.lang.String

oracle.sql.CHAR

VARCHAR2

java.sql.Types.VARCHAR

java.lang.String

oracle.sql.CHAR

LONG

java.sql.Types.LONGVARCHAR

java.lang.String

oracle.sql.CHAR

NUMBER

java.sql.Types.NUMERIC

java.math.BigDecimal

oracle.sql.NUMBER

NUMBER

java.sql.Types.DECIMAL

java.math.BigDecimal

oracle.sql.NUMBER

NUMBER

java.sql.Types.BIT

boolean

oracle.sql.NUMBER

NUMBER

java.sql.Types.TINYINT

byte

oracle.sql.NUMBER

NUMBER

java.sql.Types.SMALLINT

short

oracle.sql.NUMBER

NUMBER

java.sql.Types.INTEGER

int

oracle.sql.NUMBER

NUMBER

java.sql.Types.BIGINT

long

oracle.sql.NUMBER

NUMBER

java.sql.Types.REAL

float

oracle.sql.NUMBER

NUMBER

java.sql.Types.FLOAT

double

oracle.sql.NUMBER

NUMBER

java.sql.Types.DOUBLE

double

oracle.sql.NUMBER

RAW

java.sql.Types.BINARY

byte[]

oracle.sql.RAW

RAW

java.sql.Types.VARBINARY

byte[]

oracle.sql.RAW

LONGRAW

java.sql.Types.LONGVARBINARY

byte[]

oracle.sql.RAW

DATE

java.sql.Types.DATE

java.sql.Date

oracle.sql.DATE

DATE

java.sql.Types.TIME

java.sql.Time

oracle.sql.DATE

TIMESTAMP

java.sql.Types.TIMESTAMP

javal.sql.Timestamp

oracle.sql.TIMESTAMP

BLOB

java.sql.Types.BLOB

java.sql.Blob

oracle.sql.BLOB

CLOB

java.sql.Types.CLOB

java.sql.Clob

oracle.sql.CLOB

user-defined object

java.sql.Types.STRUCT

java.sql.Struct

oracle.sql.STRUCT

user-defined reference

java.sql.Types.REF

java.sql.Ref

oracle.sql.REF

user-defined collection

java.sql.Types.ARRAY

java.sql.Array

oracle.sql.ARRAY

ROWID

java.sql.Types.ROWID

java.sql.RowId

oracle.sql.ROWID

NCLOB

java.sql.Types.NCLOB

java.sql.NClob

oracle.sql.NCLOB

NCHAR

java.sql.Types.NCHAR

java.lang.String

oracle.sql.CHAR

 

ORACLE EXTENSIONS:

  

BFILE

oracle.jdbc.OracleTypes.BFILE

NA

oracle.sql.BFILE

REF CURSOR

oracle.jdbc.OracleTypes.CURSOR

java.sql.ResultSet

oracle.jdbc.OracleResultSet

TIMESTAMP

oracle.jdbc.OracleTypes.TIMESTAMP

java.sql.Timestamp

oracle.sql.TIMESTAMP

TIMESTAMP WITH TIME ZONE

oracle.jdbc.OracleTypes.TIMESTAMPTZ

java.sql.Timestamp

oracle.sql.TIMESTAMPTZ

TIMESTAMP WITH LOCAL TIME ZONE

oracle.jdbc.OracleTypes.TIMESTAMPLTZ

java.sql.Timestamp

oracle.sql.TIMESTAMPLTZ


Note:

For database versions, such as 8.1.7, which do not support theTIMESTAMP data type,TIMESTAMP is mapped toDATE.

See Also :

Notes Regarding Mappings

This section provides further detail regarding mappings forNUMBER and user-defined types.

NUMBER Types

For the different type codes that an OracleNUMBER value can correspond to, call the getter routine that is appropriate for the size of the data for mapping to work properly. For example, callgetByte to get a Javatinyint value for an itemx, where -128 <x < 128.

User-Defined Types

User-defined types, such as objects, object references, and collections, map by default to weak Java types, such asjava.sql.Struct, but alternatively can map to strongly typed custom Java classes. Custom Java classes can implement one of two interfaces:

  • The standardjava.sql.SQLData

  • The Oracle-specificoracle.sql.ORAData

See Also:

"Mapping Oracle Objects" and"Creating and Using Custom Object Classes for Oracle Objects"

Data Conversion Considerations

When JDBC programs retrieveSQL data into Java, you can use standard Java types, or you can use types of theoracle.sql package. This section covers the following topics:

Standard Types Versus Oracle Types

The Oracle data types inoracle.sql store data in the same bit format as used by the database. In versions of the Oracle JDBC drivers prior to Oracle Database 10g, the Oracle data types were generally more efficient. The Oracle Database 10g JDBC drivers were substantially updated. As a result, in most cases the standard Java types are preferred to the data types inoracle.sql. In particular,java.lang.String is much more efficient thanoracle.sql.CHAR.

In general, Oracle recommends that you use the Java standard types. The exceptions to this are:

  • Use theoracle.sql.OraData rather than thejava.sql.SqlData if the OraData functionality better suits your needs.

  • Useoracle.sql.NUMBER rather thanjava.lang.Double if you need to retain the exact values of floating point numbers. OracleNUMBER is a decimal representation and JavaDouble andFloat are binary representations. Conversion from one format to the other can result in slight variations in the actual value represented. Additionally, the range of values that can be represented using the two formats is different.

  • Useoracle.sql.DATE ororacle.sql.TIMESTAMP rather thanjava.sql.Date orjava.sql.Timestamp if you are using JDK 1.5 or earlier versions or require maximum performance. You may also use theoracle.sql data type if you want to read many date values or compute or display only a small percentage. Due to a bug in all versions of Java prior to JDK 1.6, construction ofjava.lang.Date andjava.lang.Timestamp objects is slow, especially in multithreaded environments. This bug is fixed in JDK 1.6.

Note:

If you convert anoracle.sql data type to a Java standard data type, then the benefits of using theoracle.sql data type are lost.

Converting SQL NULL Data

Java represents a SQLNULL datum by the Java valuenull. Java data types fall into two categories: primitive types, such asbyte,int, andfloat, and object types, such as class instances. The primitive types cannot representnull. Instead, they storenull as the value zero, as defined by the JDBC specification. This can lead to ambiguity when you try to interpret your results.

In contrast, Java object types can representnull. The Java language defines an object container type corresponding to every primitive type that can representnull. The object container types must be used as the targets for SQL data to detect SQLNULL without ambiguity.

Testing for NULLs

You cannot use a relational operator to compareNULL values with each other or withother values. For example, the followingSELECT statement does not return any row even if theCOMM column contains one or moreNULL values.

PreparedStatement pstmt = conn.prepareStatement(  "SELECT * FROM EMP WHERE COMM = ?"); pstmt.setNull(1, java.sql.Types.VARCHAR);

Thenext example shows how to compare values for equality when some return values might beNULL. The following code returns all theENAMES from theEMP table that areNULL, if there is no value of 100 forCOMM.

PreparedStatement pstmt = conn.prepareStatement("SELECT ENAME FROM EMP   WHERE COMM =? OR  ((COMM IS NULL) AND (? IS NULL))"); pstmt.setBigDecimal(1, new BigDecimal(100)); pstmt.setNull(2, java.sql.Types.VARCHAR);

Result Set and Statement Extensions

The JDBCStatement objectreturns anOracleResultSet object, typed as ajava.sql.ResultSet. If you want to apply only standard JDBC methods to the object, then keep it as aResultSet type. However, if you want to use the Oracle extensions on the object, then you must cast it toOracleResultSet. All of the Oracle Result Set extensions are in theoracle.jdbc.OracleResultSet interface and all theStatement extensions are in theoracle.jdbc.OracleStatement interface.

For example, assuming you have a standardStatement objectstmt, do the following if you want to use only standard JDBCResultSet methods:

ResultSet rs = stmt.executeQuery("SELECT * FROM emp");

If you need the extended functionality provided by the Oracle extensions to JDBC, you can select the results into a standardResultSet variable and then cast that variable toOracleResultSet later.

Key extensions to the result set and statement classes include thegetOracleObject andsetOracleObject methods, used to access and manipulate data inoracle.sql.* formats.

Comparison of Oracle get and set Methods to Standard JDBC

This section describesget andset methods, particularly the JDBC standardgetObject andsetObject methods and the Oracle-specificgetOracleObject andsetOracleObject methods, and how to access data inoracle.sql.* format compared with Java format.

Although there are specificgetXXX methods for all the Oracle SQL types, you can use the generalget methods for convenience or simplicity, or if you are not certain in advance what type of data you will receive.

This section covers the following topics:

Note:

You cannot qualify a column name with a table name and pass it as a parameter to thegetXXX method. For example:
ResultSet rset = stmt.executeQuery("SELECT emp.deptno, dept.deptno FROM emp, dept");rset.getInt("emp.deptno");

ThegetInt method in the preceding code will throw an exception. To uniquely identify the columns in thegetXXX method, you can either use column index or specify column aliases in the query and use these aliases in thegetXXX method.

Standard getObject Method

The standardgetObject method of a result set or callable statement has a return type ofjava.lang.Object. The class of the object returned is based on its SQL type, as follows:

  • For SQL data types that are not Oracle-specific,getObject returns the default Java type corresponding to the SQL type of the column, following the mapping in the JDBC specification.

  • For Oracle-specific data types,getObject returns an object of the appropriateoracle.sql.* class, such asoracle.sql.ROWID.

  • For Oracle database objects,getObject returns a Java object of the class specified in yourtype map. Type maps specify a mapping from database named types to Java classes. ThegetObject(parameter_index) method uses the default type map of the connection. ThegetObject(parameter_index,map) enables you to pass in a type map. If the type map does not provide a mapping for a particular Oracle object, thengetObject returns anoracle.sql.STRUCT object.

Oracle getOracleObject Method

If you want to retrieve data from a result set or callable statement as anoracle.sql.* object, then you must follow a special process. For a Result Set, you must cast the Result Set itself tooracle.jdbc.OracleResultSet and then callgetOracleObject instead ofgetObject. The same applies toCallableStatement andoracle.jdbc.OracleCallableStatement.

The return type ofgetOracleObject isoracle.sql.Datum. The actual returned object is an instance of the appropriateoracle.sql.* class. The method signature is:

public oracle.sql.Datum getOracleObject(intparameter_index)

When you retrieve data into aDatum variable, you can use the standard Javainstanceof operator to determine whichoracle.sql.* type it really is.

Example: Using getOracleObject with a Result Set

Thefollowing example creates a table that contains a column ofCHAR data and a column containing aBFILE locator. ASELECT statement retrieves the contents of the table as a result set. ThegetOracleObject then retrieves theCHAR data into thechar_datum variable and theBFILE locator into thebfile_datum variable. Note that becausegetOracleObject returns aDatum object, the return values must be cast toCHAR andBFILE, respectively.

stmt.execute ("CREATE TABLE bfile_table (x VARCHAR2 (30), b BFILE)");stmt.execute     ("INSERT INTO bfile_table VALUES ('one', BFILENAME ('TEST_DIR', 'file1'))");ResultSet rset = stmt.executeQuery ("SELECT * FROM bfile_table");while (rset.next ()){   CHAR char_datum = (CHAR) ((OracleResultSet)rset).getOracleObject (1);   BFILE bfile_datum = (BFILE) ((OracleResultSet)rset).getOracleObject (2);   ...}

Example: Using getOracleObject in a Callable Statement

Thefollowing example prepares a call to the proceduremyGetDate, which associates a character string with a date. The program passes "SCOTT" to the prepared call and registers theDATE type as an output parameter. After the call is run,getOracleObject retrieves the date associated with"SCOTT". Note that becausegetOracleObject returns aDatum object, the results are cast toDATE.

OracleCallableStatement cstmt = (OracleCallableStatement)conn.prepareCall                                   ("begin myGetDate (?, ?); end;");cstmt.setString (1, "SCOTT");cstmt.registerOutParameter (2, Types.DATE);cstmt.execute ();DATE date = (DATE) ((OracleCallableStatement)cstmt).getOracleObject (2);...

Summary of getObject and getOracleObject Return Types

Table 11-2 lists the underlying return types for thegetObject andgetOracleObject methods for each Oracle SQL type.

Keep in mind the following when you use these methods:

  • getObjectalways returns data into ajava.lang.Object instance

  • getOracleObject always returns data into anoracle.sql.Datum instance

You must cast the returned object to use any special functionality.

Table 11-2 getObject and getOracleObject Return Types

Oracle SQL TypegetObject Underlying Return TypegetOracleObject Underlying Return Type

CHAR

String

oracle.sql.CHAR

VARCHAR2

String

oracle.sql.CHAR

NCHAR

String

oracle.sql.CHAR

LONG

String

oracle.sql.CHAR

NUMBER

java.math.BigDecimal

oracle.sql.NUMBER

RAW

byte[]

oracle.sql.RAW

LONGRAW

byte[]

oracle.sql.RAW

DATE

java.sql.Date

oracle.sql.DATE

TIMESTAMP

java.sql.TimestampFoot 1 

oracle.sql.TIMESTAMP

TIMESTAMP WITH TIME ZONE

oracle.sql.TIMESTAMPTZ

oracle.sql.TIMESTAMPTZ

TIMESTAMP WITH LOCAL TIME ZONE

oracle.sql.TIMESTAMPLTZ

oracle.sql.TIMESTAMPLTZ

BINARY_FLOAT

java.lang.Float

oracle.sql.BINARY_FLOAT

BINARY_DOUBLE

java.lang.Double

oracle.sql.BINARY_DOUBLE

INTERVAL DAY TO SECOND

oracle.sql.INTERVALDS

oracle.sql.INTERVALDS

INTERVAL YEAR TO MONTH

oracle.sql.INTERVALYM

oracle.sql.INTERVALYM

ROWID

oracle.sql.ROWID

oracle.sql.ROWID

REF CURSOR

java.sql.ResultSet

(not supported)

BLOB

oracle.sql.BLOB

oracle.sql.BLOB

CLOB

oracle.sql.CLOB

oracle.sql.CLOB

NCLOB

java.sql.NClob

oracle.sql.NCLOB

BFILE

oracle.sql.BFILE

oracle.sql.BFILE

Oracle object

class specified in type map

ororacle.sql.STRUCT (if no type map entry)

oracle.sql.STRUCT

Oracle object reference

oracle.sql.REF

oracle.sql.REF

collection (varray or nested table)

oracle.sql.ARRAY

oracle.sql.ARRAY


Footnote 1 ResultSet.getObject returnsjava.sql.Timestamp only if theoracle.jdbc.J2EE13Compliant connection property is set toTRUE, else the method returnsoracle.sql.TIMESTAMP.

Note:

TheResultSet.getObject method returnsjava.sql.Timestamp for theTIMESTAMP SQL type, only when the connection propertyoracle.jdbc.J2EE13Compliant is set toTRUE. This property has to be set when the connection is obtained. If this connection property is not set or if it is set after the connection is obtained, then theResultSet.getObject method returnsoracle.sql.TIMESTAMP for theTIMESTAMP SQL type.

Theoracle.jdbc.J2EE13Compliant connection property can also be set without changing the code in the following ways:

  • Including theojdbc5dms.jar orojdbc6dms.jar files in theCLASSPATH. These files setoracle.jdbc.J2EE13Compliant toTRUE by default. These are specific to the Oracle Application Server release and are not available as part of the general JDBC release. They are located in$ORACLE_HOME/jdbc/lib.

  • Setting the system property by calling thejava command with the flag-Doracle.jdbc.J2EE13Compliant=true. For example,

    java -Doracle.jdbc.J2EE13Compliant=true ...

When theJ2EE13Compliant is set toTRUE the action is as in Table B-3 of the JDBC specification.

See Also:

Table A-1, "Valid SQL Data Type-Java Class Mappings", for information about type compatibility between all SQL and Java types.

Other getXXX Methods

Standard JDBC provides agetXXX for each standard Java type, such asgetByte,getInt,getFloat, and so on. Each of these returns exactly what the method name implies.

In addition, theOracleResultSet andOracleCallableStatement classes provide a full complement ofgetXXX methods corresponding to all theoracle.sql.* types. EachgetXXX method returns anoracle.sql.XXX object. For example,getROWID returns anoracle.sql.ROWID object.

There is no performance advantage in using the specificgetXXX methods. However, they do save you the trouble of casting, because the return type is specific to the object being returned.

This section covers the following topics:

Return Types of getXXX Methods

Refer to the Java doc to knowthe return types for eachgetXXX method and also which are Oracle extensions under Java Development Kit (JDK) 1.6. You must cast the returned object toOracleResultSet orOracleCallableStatement to use methods that are Oracle extensions.

Special Notes about getXXX Methods

This section provides additional details about somegetXXX methods.

getBigDecimal

JDBC 2.0 simplified method signatures for thegetBigDecimal method. The previous input signatures were:

(int columnIndex, int scale) or (String columnName, int scale)

The simplified input signature is:

(int columnIndex) or (String columnName)

Thescale parameter, used to specify the number of digits to the right of the decimal, is no longer necessary. The Oracle JDBC drivers retrieve numeric values with full precision.

getBoolean

Because there is noBOOLEAN database type, when you usegetBoolean a data type conversion always occurs. ThegetBoolean method is supported only for numeric columns. When applied to these columns,getBoolean interprets any zero value asfalse and any other value astrue. When applied to any other sort of column,getBoolean raises the exceptionjava.lang.NumberFormatException.

Data Types For Returned Objects from getObject and getXXX

The return type ofgetObject isjava.lang.Object. The returned value is an instance of a subclass ofjava.lang.Object. Similarly, the return type ofgetOracleObject isoracle.sql.Datum, and the class of the returned value is a subclass oforacle.sql.Datum. You typically cast the returned object to the appropriate class to use particular methods and functionality of that class.

In addition, you have the option of using a specificgetXXX method instead of the genericgetObject orgetOracleObject methods. ThegetXXX methods enable you to avoid casting, because the return type ofgetXXX corresponds to the type of object returned. For example, the return type ofgetCLOB isoracle.sql.CLOB, as opposed tojava.lang.Object.

Example of Casting Return Values

This example assumes that you have fetched data of theNUMBER type as the first column of a result set. Because you want to manipulate theNUMBER data without losing precision, cast your result set toOracleResultSet and usegetOracleObject to return theNUMBER data inoracle.sql.* format. If you do not cast your result set, then you have to usegetObject, which returns your numeric data into a JavaFloat and loses some of the precision of your SQL data.

ThegetOracleObject method returns anoracle.sql.NUMBER object into anoracle.sql.Datum return variable unless you cast the output. Cast thegetOracleObject output tooracle.sql.NUMBER if you want to use aNUMBER return variable and any of the special functionality of that class.

NUMBER x = (NUMBER)ors.getOracleObject(1);

The setObject and setOracleObject Methods

Just as there is a standardgetObject and Oracle-specificgetOracleObject in result sets and callable statements, there are also standardsetObject and Oracle-specificsetOracleObject methods inOraclePreparedStatement andOracleCallableStatement. ThesetOracleObject methods takeoracle.sql.* input parameters.

To bind standard Java types to a prepared statement or callable statement, use thesetObject method, which takes ajava.lang.Object as input. ThesetObject method does support a few of theoracle.sql.* types. However, the method has been implemented so that you can enter instances of theoracle.sql.* classes that correspond to the following JDBC standard types:Blob,Clob,Struct,Ref, andArray.

To bindoracle.sql.* types to a prepared statement or callable statement, use thesetOracleObject method, which takes a subclass oforacle.sql.Datum as input. To usesetOracleObject, you must cast your prepared statement or callable statement toOraclePreparedStatement orOracleCallableStatement.

Example of Using setObject and setOracleObject

For a prepared statement, thesetOracleObject method binds theoracle.sql.CHAR data represented by thecharVal variable to the prepared statement. To bind theoracle.sql.* data, the prepared statement must be cast toOraclePreparedStatement. Similarly, thesetObject method binds the JavaString data represented by the variablestrVal.

PreparedStatement ps= conn.prepareStatement("text_of_prepared_statement");((OraclePreparedStatement)ps).setOracleObject(1,charVal);ps.setObject(2,strVal);

Other setXXX Methods

As with thegetXXX methods, there are several specificsetXXX methods. StandardsetXXX methods are provided for binding standard Java types, and Oracle-specificsetXXX methods are provided for binding Oracle-specific types.

Similarly, there are two forms of thesetNull method:

  • voidsetNull(intparameterIndex,intsqlType)

    This is specified in the standardjava.sql.PreparedStatement interface. This signature takes a parameter index and a SQL type code defined by thejava.sql.Types ororacle.jdbc.OracleTypes class. Use this signature to set an object other than aREF,ARRAY, orSTRUCT toNULL.

  • void setNull(intparameterIndex,intsqlType, Stringsql_type_name)

    With JDBC 2.0, this signature is also specified in the standardjava.sql.PreparedStatement interface. This method takes a SQL type name in addition to a parameter index and a SQL type code. Use this method when the SQL type code isjava.sql.Types.REF,ARRAY, orSTRUCT. If the type code is other thanREF,ARRAY, orSTRUCT, then the given SQL type name is ignored.

Similarly, theregisterOutParameter method has a signature for use withREF,ARRAY, orSTRUCT data:

void registerOutParameter            (intparameterIndex, intsqlType, Stringsql_type_name)

Binding Oracle-specific types using the appropriatesetXXX methods, instead of the methods used for binding standard Java types, may offer some performance advantage.

This section covers the following topics:

Input Data Binding

There are three way to bind data for input:

  • Direct binding where the data itself is placed in a bind buffer

  • Stream binding where the data is streamed

  • LOB binding where a temporary lob is created, the data placed in the LOB using the LOB APIs, and the bytes of the LOB locator are placed in the bind buffer

The three kinds of binding have some differences in performance and have an impact on batching. Direct binding is fast and batching is fine. Stream binding is slower, may require multiple round trips, and turns batching off. LOB binding is very slow and requires many round trips. Batching works, but might be a bad idea. They also have different size limits, depending on the type of the SQL statement.

For SQL parameters, the length of standard parameter types, such asRAW andVARCHAR2, is fixed by the size of the target column. For PL/SQL parameters, the size is limited to a fixed number of bytes, which is 32766.

In Oracle Database 10g release 2 (10.2), certain changes were made to thesetString,setCharacterStream,setAsciiStream,setBytes, andsetBinaryStream methods ofPreparedStatement. The original behavior of these APIs were:

  • setString: Direct bind of characters

  • setCharacterStream: Stream bind of characters

  • setAsciiStream: Stream bind of bytes

  • setBytes: Direct bind of bytes

  • setBinaryStream: Stream bind of bytes

Starting from Oracle Database 10g release 2 (10.2), automatic switching between binding modes, based on the data size and on the type of the SQL statement is provided.

setBytes and setBinaryStream

For SQL, direct bind is used for size up to 2000 and stream bind for larger.

For PL/SQL direct bind is used for size up to 32766 and LOB bind is used for larger.

setString, setCharacterStream, and setAsciiStream

For SQL, direct bind is used up to 32766 Java characters and stream bind is used for larger. This is independent of character set.

For PL/SQL, you must be careful about the byte size of the character data in the database character set or the national character set depending on the setting of the form of use parameter. Direct bind is used for data where the byte length is less than 32766 and LOB bind is used for larger.

For fixed length character sets, multiply the length of the Java character data by the fixed character size in bytes and compare that to the restrictive values. For variable length character sets, there are three cases based on the Java character length, as follows:

  • If character length is less than 32766 divided by the maximum character size, then direct bind is used.

  • If character length is greater than 32766 divided by the minimum character size, then LOB bind is used.

  • If character length is in between and if the actual length of the converted bytes is less than 32766, then direct bind is used, else LOB bind is used.

Note:

When a PL/SQL procedure is embedded in a SQL statement, the binding action is different. Refer to"Data Interface for LOBs" for more information.

The server-side internal driver has the following additional limitations:

  • setString,setCharacterStream, andsetASCIIStream APIs are not supported for SQL CLOB columns when the data size in characters is over 4000 bytes

  • setBytes andsetBinaryStream APIs are not supported for SQL BLOB columns when the data size is over 2000 bytes

Important:

Do not use these APIs with the server-side internal driver, without careful checking of the datasize in client code.

See Also:

JDBC Release Notes for further discussion and possible workarounds

Method setFixedCHAR for Binding CHAR Data into WHERE Clauses

CHAR data in the database is padded to the column width. This leads to a limitation in using thesetCHAR method to bind character data into theWHERE clause of aSELECT statement. The character data in theWHERE clause must also be padded to the column width to produce a match in theSELECT statement. This is especially troublesome if you do not know the column width.

To remedy this, Oracle has added thesetFixedCHAR method to theOraclePreparedStatement class. This method runs a non-padded comparison.

Note:

  • Remember to cast your prepared statement object toOraclePreparedStatement to use thesetFixedCHAR method.

  • There is no need to usesetFixedCHAR for anINSERT statement. The database always automatically pads the data to the column width as it inserts it.

Example

The following example demonstrates the difference between thesetCHAR andsetFixedCHAR methods.

/* Schema is : create table my_table (col1 char(10)); insert into my_table values ('JDBC');*/ PreparedStatement pstmt = conn.prepareStatement                     ("select count(*) from my_table where col1 = ?"); pstmt.setString (1, "JDBC");  // Set the Bind Value runQuery (pstmt);             // This will print " No of rows are 0" CHAR ch = new CHAR("JDBC      ", null); ((OraclePreparedStatement)pstmt).setCHAR(1, ch); // Pad it to 10 bytes runQuery (pstmt);             // This will print "No of rows are 1" ((OraclePreparedStatement)pstmt).setFixedCHAR(1, "JDBC");  runQuery (pstmt);            // This will print "No of rows are 1"  void runQuery (PreparedStatement ps) {       // Run the Query   ResultSet rs = pstmt.executeQuery ();   while (rs.next())     System.out.println("No of rows are " + rs.getInt(1));      rs.close();   rs = null; }

Using Result Set Metadata Extensions

Theoracle.jdbc.OracleResultSetMetaData interface is JDBC 2.0-compliant but does not implement thegetSchemaName andgetTableName methods because Oracle Database does not make this feasible..

The following code snippet uses several of the methods in theOracleResultSetMetadata interface to retrieve the number of columns from theEMP table and the numerical type and SQL type name of each column:

DatabaseMetaData dbmd = conn.getMetaData();ResultSet rset = dbmd.getTables("", "SCOTT", "EMP", null); while (rset.next()) {   OracleResultSetMetaData orsmd = ((OracleResultSet)rset).getMetaData();   int numColumns = orsmd.getColumnCount();   System.out.println("Num of columns = " + numColumns);   for (int i=0; i<numColumns; i++)   {     System.out.print ("Column Name=" + orsmd.getColumnName (i+1));     System.out.print (" Type=" + orsmd.getColumnType (i + 1) );     System.out.println (" Type Name=" + orsmd.getColumnTypeName (i + 1));  }}

The program returns the following output:

Num of columns = 5Column Name=TABLE_CAT Type=12 Type Name=VARCHAR2Column Name=TABLE_SCHEM Type=12 Type Name=VARCHAR2Column Name=TABLE_NAME Type=12 Type Name=VARCHAR2Column Name=TABLE_TYPE Type=12 Type Name=VARCHAR2Column Name=TABLE_REMARKS Type=12 Type Name=VARCHAR2

Using SQL CALL and CALL INTO Statements

You can use the CALL statement to execute a routine from within SQL.

Note:

A routine is a procedure or a function that is standalone or is defined within a type or package. You must haveEXECUTE privilege on the standalone routine or on the type or package in which the routine is defined. Refer to the "Oracle Database SQL Language Reference" for more information about using theCALL statement.

You can execute a routine in two ways:

  • By issuing a call to the routine itself by name or by using theroutine_clause

  • By using anobject_access_expression inside the type of an expression

You can specify one or more arguments to the routine, if the routine takes arguments. You can use positional, named, or mixed notation for argument.

CALL INTO Statement

TheINTO clause applies only to calls to functions. You can use the following types of variables with this clause:

  • Host variable

  • Indicator variable

PL/SQL Blocks

The basic unit in PL/SQL is a block. All PL/SQL programs are made up of blocks, which can be nested within each other. A PL/SQL block has three parts: a declarative part, an executable part, and an exception-handling part. You get the following advantages by using PL/SQL blocks in your application:

  • Better performance

  • Higher productivity

  • Full portability

  • Tight integration with Oracle

  • Tight security


[8]ページ先頭

©2009-2025 Movatter.jp