📄 jdbcpreparedstatement.java
字号:
/* Copyright (c) 2001-2005, The HSQL Development Group
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the HSQL Development Group nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.hsqldb.jdbc;
import java.io.IOException;
import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
//#ifdef JAVA2
import java.sql.Array;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Ref;
//#endif JAVA2
//#ifdef JDBC3
import java.sql.ParameterMetaData;
//#endif JDBC3
import org.hsqldb.Column;
import org.hsqldb.HsqlDateTime;
import org.hsqldb.HsqlException;
import org.hsqldb.Result;
import org.hsqldb.ResultConstants;
import org.hsqldb.Trace;
import org.hsqldb.Types;
import org.hsqldb.lib.ArrayUtil;
import org.hsqldb.lib.HsqlByteArrayOutputStream;
import org.hsqldb.lib.Iterator;
import org.hsqldb.lib.StringConverter;
import org.hsqldb.types.Binary;
import org.hsqldb.types.JavaObject;
// fredt@users 20020320 - patch 1.7.0 - JDBC 2 support and error trapping
// JDBC 2 methods can now be called from jdk 1.1.x - see javadoc comments
// boucherb@users 20020509 - added "throws SQLException" to all methods where
// it was missing here but specified in the java.sql.PreparedStatement and
// java.sqlCallableStatement interfaces, updated generic documentation to
// JDK 1.4, and added JDBC3 methods and docs
// boucherb@users and fredt@users 20020409/20020505 extensive review and update
// of docs and behaviour to comply with previous and latest java.sql specification
// fredt@users 20030620 - patch 1.7.2 - rewritten to support real prepared statements
// boucherb@users 20030801 - patch 1.7.2 - support for batch execution
// boucherb@users 20030801 - patch 1.7.2 - support for getMetaData and getParameterMetadata
// boucherb@users 20030801 - patch 1.7.2 - updated some setXXX methods
// boucherb@users 200403/4xx - doc 1.7.2 - javadoc updates toward 1.7.2 final
// boucherb@users 200403/4xx - patch 1.7.2 - eliminate eager buffer allocation from setXXXStream/Blob/Clob
/**
* <!-- start generic documentation -->
*
* An object that represents a precompiled SQL statement. <p>
*
* An SQL statement is precompiled and stored in a
* <code>PreparedStatement</code> object. This object can then be used to
* efficiently execute this statement multiple times.
*
* <P><B>Note:</B> The setter methods (<code>setShort</code>,
* <code>setString</code>, and so on) for setting IN parameter values
* must specify types that are compatible with the defined SQL type of
* the input parameter. For instance, if the IN parameter has SQL type
* <code>INTEGER</code>, then the method <code>setInt</code> should be
* used. <p>
*
* If arbitrary parameter type conversions are required, the method
* <code>setObject</code> should be used with a target SQL type.
* <P>
* In the following example of setting a parameter, <code>con</code>
* represents an active connection:
* <PRE>
* PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES
* SET SALARY = ? WHERE ID = ?");
* pstmt.setBigDecimal(1, 153833.00)
* pstmt.setInt(2, 110592)
* </PRE> <p>
* <!-- end generic documentation -->
* <!-- start Release-specific documentation -->
* <div class="ReleaseSpecificDocumentation">
* <h3>HSQLDB-Specific Information:</h3> <p>
*
* Starting with HSQLDB 1.7.2, jdbcPreparedStatement objects are backed by
* a true compiled parameteric representation. Hence, there are now significant
* performance gains to be had by using a jdbcPreparedStatement object in
* preference to a jdbcStatement object, if a short-running SQL statement is
* to be executed more than a small number of times. <p>
*
* Please note, however, that 1.7.2 does not yet provide a sophisticated
* internal statement pooling facility. For this reason, the observation
* above is guaranteed to apply only under certain use patterns. <p>
*
* Specifically, when it can be otherwise avoided, it is to be considered poor
* practice to fully prepare (construct), parameterize, execute, fetch and
* close a jdbcPreparedStatement object for each execution cycle. Indeed, under
* HSQLDB 1.7.2, this practice is likely to be noticably <em>less</em>
* performant for short-running statements than the equivalent process using
* jdbcStatement objects, albeit far more convenient, less error prone and
* certainly much less resource-intensive, especially when large binary and
* character values are involved, due to the optimized parameterization
* facility. <p>
*
* Instead, when developing an application that is not totally oriented toward
* the execution of ad hoc SQL, it is recommended to expend some effort toward
* identifing the SQL statements that are good candidates for regular reuse and
* adapting the structure of the application accordingly. Often, this is done
* by recording the text of candidate SQL statements in an application resource
* object (which has the nice side-benefit of isolating and hiding differences
* in SQL dialects across different drivers) and caching for possible reuse the
* PreparedStatement objects derived from the recorded text. <p>
*
* <b>Multi thread use:</b> <p>
*
* A PreparedStatement object is stateful and should not normally be shared
* by multiple threads. If it has to be shared, the calls to set the
* parameters, calls to add batch statements, the execute call and any
* post-execute calls should be made within a block synchronized on the
* PreparedStatement Object.<p>
*
* <b>JRE 1.1.x Notes:</b> <p>
*
* In general, JDBC 2 support requires Java 1.2 and above, and JDBC3 requires
* Java 1.4 and above. In HSQLDB, support for methods introduced in different
* versions of JDBC depends on the JDK version used for compiling and building
* HSQLDB.<p>
*
* Since 1.7.0, it is possible to build the product so that
* all JDBC 2 methods can be called while executing under the version 1.1.x
* <em>Java Runtime Environment</em><sup><font size="-2">TM</font></sup>.
* However, in addition to requiring explicit casts to the org.hsqldb.jdbcXXX
* interface implementations, some of these method calls require
* <code>int</code> values that are defined only in the JDBC 2 or greater
* version of
* <a href="http://java.sun.com/j2se/1.4/docs/api/java/sql/ResultSet.html">
* <code>ResultSet</code></a> interface. For this reason, when the
* product is compiled under JDK 1.1.x, these values are defined in
* {@link jdbcResultSet jdbcResultSet}.<p>
*
* In a JRE 1.1.x environment, calling JDBC 2 methods that take or return the
* JDBC2-only <code>ResultSet</code> values can be achieved by referring
* to them in parameter specifications and return value comparisons,
* respectively, as follows: <p>
*
* <pre class="JavaCodeExample">
* jdbcResultSet.FETCH_FORWARD
* jdbcResultSet.TYPE_FORWARD_ONLY
* jdbcResultSet.TYPE_SCROLL_INSENSITIVE
* jdbcResultSet.CONCUR_READ_ONLY
* // etc.
* </pre>
*
* However, please note that code written in such a manner will not be
* compatible for use with other JDBC 2 drivers, since they expect and use
* <code>ResultSet</code>, rather than <code>jdbcResultSet</code>. Also
* note, this feature is offered solely as a convenience to developers
* who must work under JDK 1.1.x due to operating constraints, yet wish to
* use some of the more advanced features available under the JDBC 2
* specification.<p>
*
* (fredt@users)<br>
* (boucherb@users)
* </div>
* <!-- end Release-specific documentation -->
*
* @author boucherb@users
* @author fredt@users
* @version 1.7.2
* @see jdbcConnection#prepareStatement
* @see jdbcResultSet
*/
public class jdbcPreparedStatement extends jdbcStatement
implements PreparedStatement {
/** The parameter values for the next non-batch execution. */
protected Object[] parameterValues;
/** The SQL types of the parameters. */
protected int[] parameterTypes;
/** The (IN, IN OUT, or OUT) modes of parameters */
protected int[] parameterModes;
/** Lengths for streams. */
protected int[] streamLengths;
/** Has a stream or CLOB / BLOB parameter value. */
protected boolean hasStreams;
/**
* Description of result set metadata. <p>
*/
protected Result rsmdDescriptor;
/** Description of parameter metadata. */
protected Result pmdDescriptor;
/** This object's one and one ResultSetMetaData object. */
protected jdbcResultSetMetaData rsmd;
// NOTE: pmd is declared as Object to avoid yet another #ifdef.
/** This object's one and only ParameterMetaData object. */
protected Object pmd;
/** The SQL character sequence that this object represents. */
protected String sql;
/**
* The id with which this object's corresponding
* {@link org.hsqldb.CompiledStatement CompiledStatement}
* object is registered in the engine's
* {@link org.hsqldb.CompiledStatementManager CompiledStatementManager}
* object.
*/
protected int statementID;
/**
* Whether this statement generates only a single row update count in
* response to execution.
*/
protected boolean isRowCount;
// fredt@users 20020215 - patch 517028 by peterhudson@users - method defined
// fredt@users 20020215 - patch 517028 by peterhudson@users - method defined
//
// changes by fredt
// SimpleDateFormat objects moved out of methods to improve performance
// this is safe because only one thread at a time should access a
// PreparedStatement object until it has finished executing the statement
// fredt@users 20020215 - patch 517028 by peterhudson@users - method defined
// minor changes by fredt
/**
* <!-- start generic documentation -->
* Sets escape processing on or off. <p>
* <!-- end generic documentation -->
*
* <!-- start release-specific documentation -->
* <div class="ReleaseSpecificDocumentation">
* <h3>HSQLDB-Specific Information:</h3> <p>
*
* Since 1.7.0, the implementation follows the standard
* behaviour by overriding the same method in jdbcStatement
* class. <p>
*
* In other words, calling this method has no effect.
* </div>
* <!-- end release-specific documentation -->
*
* @param enable <code>true</code> to enable escape processing;
* <code>false</code> to disable it
* @exception SQLException if a database access error occurs
*/
public void setEscapeProcessing(boolean enable) throws SQLException {
checkClosed();
}
/**
* <!-- start generic documentation -->
* Executes the SQL statement in this <code>PreparedStatement</code>
* object, which may be any kind of SQL statement.
* Some prepared statements return multiple results; the
* <code>execute</code> method handles these complex statements as well
* as the simpler form of statements handled by the methods
* <code>executeQuery</code>and <code>executeUpdate</code>. <p>
*
* The <code>execute</code> method returns a <code>boolean</code> to
* indicate the form of the first result. You must call either the method
* <code>getResultSet</code> or <code>getUpdateCount</code>
* to retrieve the result; you must call <code>getMoreResults</code> to
* move to any subsequent result(s). <p>
* <!-- end generic documentation -->
*
* <!-- start release-specific documentation -->
* <div class="ReleaseSpecificDocumentation">
* <h3>HSQLDB-Specific Information:</h3> <p>
*
* Including 1.7.2, prepared statements do not generate
* multiple fetchable results. <p>
*
* Following 1.7.2, it will be possible that statements
* generate multiple fetchable results under certain conditions.
* </div>
*
* @return <code>true</code> if the first result is a <code>ResultSet</code>
* object; <code>false</code> if the first result is an update
* count or there is no result
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -