net.sourceforge.jtds.jdbc

Class JtdsStatement

Implemented Interfaces:
java.sql.Statement
Known Direct Subclasses:
JtdsPreparedStatement

public class JtdsStatement
extends java.lang.Object
implements java.sql.Statement

jTDS implementation of the java.sql.Statement interface.

NB. As allowed by the JDBC standard and like most other drivers, this implementation only allows one open result set at a time.

Implementation notes:

I experimented with allowing multiple open result sets as supported by the origianal jTDS but rejected this approach for the following reasons:

  1. It is more difficult to ensure that there are no memory leaks and that cursors are closed if multiple open sets are allowed.
  2. The use of one result set allows cursor and non cursor result sets to be derived from exeuteQuery() or execute() and getResultSet() in the same way that other drivers do.
In the event of an IO failure the setClosed() method forces this statement and associated result set to close preventing the propogation of errors. This class includes a finalize method which increases the chances of the statement being closed tidly in a pooled environment where the user has forgotten to explicitly close the statement before it goes out of scope.
Version:
$Id: JtdsStatement.java,v 1.64 2007/07/12 21:03:23 bheineman Exp $
Author:
Mike Hutchinson
See Also:
java.sql.Statement, java.sql.Connection.createStatement(), java.sql.ResultSet

Field Summary

(package private) static int
BOOLEAN
(package private) static int
CLOSE_ALL_RESULTS
(package private) static int
CLOSE_CURRENT_RESULT
(package private) static int
DATALINK
(package private) static int
DEFAULT_FETCH_SIZE
(package private) static Integer
EXECUTE_FAILED
(package private) static int
KEEP_CURRENT_RESULT
(package private) static int
NO_GENERATED_KEYS
(package private) static int
RETURN_GENERATED_KEYS
(package private) static Integer
SUCCESS_NO_INFO
protected ArrayList
batchValues
Batched SQL Statement array.
protected boolean
closed
True if this statement is closed.
protected ColInfo[]
colMetaData
The cached column meta data.
protected ConnectionJDBC2
connection
The connection owning this statement object.
protected JtdsResultSet
currentResult
The current ResultSet.
protected String
cursorName
The cursor name to be used for positioned updates.
protected boolean
escapeProcessing
True if SQL statements should be preprocessed.
protected int
fetchDirection
The fetch direction for result sets.
protected int
fetchSize
The fetch size (default 100, only used by cursor ResultSets).
protected JtdsResultSet
genKeyResultSet
Dummy result set for getGeneratedKeys.
protected int
maxFieldSize
The maximum field size (not used at present).
protected int
maxRows
The maximum number of rows to return (not used at present).
protected SQLDiagnostic
messages
SQL Diagnostic exceptions and warnings.
protected ArrayList
openResultSets
List of open result sets.
protected int
queryTimeout
The read query timeout in seconds
protected LinkedList
resultQueue
List of queued results (update counts, possibly followed by a ResultSet).
protected int
resultSetConcurrency
The concurrency of result sets created by this statement.
protected int
resultSetType
The type of result sets created by this statement.
protected TdsCore
tds
The TDS object used for server access.
private int
updateCount
The current update count.

Constructor Summary

JtdsStatement(ConnectionJDBC2 connection, int resultSetType, int resultSetConcurrency)
Construct a new Statement object.

Method Summary

void
addBatch(String sql)
(package private) void
addWarning(SQLWarning w)
Add an SQLWarning object to the statment warnings list.
protected void
cacheResults()
Cache as many results as possible (up to the first ResultSet).
void
cancel()
protected void
checkCursorException(SQLException e)
Check that the exception is caused by the failure to open a cursor and not by a more serious SQL error.
protected void
checkOpen()
Check that this statement is still open.
void
clearBatch()
void
clearWarnings()
void
close()
(package private) void
closeAllResultSets()
Close all result sets.
(package private) void
closeCurrentResultSet()
Close current result set (if any).
boolean
execute(String sql)
boolean
execute(String sql, String[] columnNames)
boolean
execute(String sql, int autoGeneratedKeys)
boolean
execute(String sql, int[] columnIndexes)
int[]
executeBatch()
Execute batch of SQL Statements.
private boolean
executeImpl(String sql, int autoGeneratedKeys, boolean update)
Implements the common functionality for plain statement execute and {#link #executeUpdate}: basic checks, cleaning up of previous results, setting up and executing the query and loading the first results.
protected SQLException
executeMSBatch(int size, int executeSize, ArrayList counts)
Execute the SQL batch on a MS server.
ResultSet
executeQuery(String sql)
protected boolean
executeSQL(String sql, String spName, ParamInfo[] params, boolean returnKeys, boolean update, boolean useCursor)
Executes any type of SQL.
protected ResultSet
executeSQLQuery(String sql, String spName, ParamInfo[] params, boolean useCursor)
Executes SQL to obtain a result set.
protected SQLException
executeSybaseBatch(int size, int executeSize, ArrayList counts)
Execute the SQL batch on a Sybase server.
int
executeUpdate(String sql)
int
executeUpdate(String sql, String[] columnNames)
int
executeUpdate(String sql, int autoGeneratedKeys)
int
executeUpdate(String sql, int[] columnIndexes)
protected void
finalize()
Called when this object goes out of scope to close any ResultSet object and this statement.
Connection
getConnection()
(package private) int
getDefaultFetchSize()
Retrieve the default fetch size for this statement.
int
getFetchDirection()
int
getFetchSize()
ResultSet
getGeneratedKeys()
int
getMaxFieldSize()
int
getMaxRows()
(package private) SQLDiagnostic
getMessages()
Get the statement's warnings list.
boolean
getMoreResults()
boolean
getMoreResults(int current)
int
getQueryTimeout()
ResultSet
getResultSet()
int
getResultSetConcurrency()
int
getResultSetHoldability()
int
getResultSetType()
(package private) TdsCore
getTds()
Get the Statement's TDS object.
int
getUpdateCount()
SQLWarning
getWarnings()
protected void
initialize()
Initialize the Statement, by cleaning up all queued and unprocessed results.
(package private) static void
notImplemented(String method)
Report that user tried to call a method which has not been implemented.
private boolean
processResults(boolean returnKeys, boolean update)
Queue up update counts into resultQueue until the end of the response is reached or a ResultSet is encountered.
void
setCursorName(String name)
void
setEscapeProcessing(boolean enable)
void
setFetchDirection(int direction)
void
setFetchSize(int rows)
void
setMaxFieldSize(int max)
void
setMaxRows(int max)
void
setQueryTimeout(int seconds)
protected boolean
useCursor(boolean returnKeys, String sqlWord)
Determines whether a cursor should be used based on the requested result set type and concurrency, whether a cursor name has been set, the useCursors connection property has been set, the first word in the SQL query is either SELECT or EXEC/EXECUTE and no generated keys are returned.

Field Details

BOOLEAN

(package private) static final int BOOLEAN
Field Value:
16

CLOSE_ALL_RESULTS

(package private) static final int CLOSE_ALL_RESULTS
Field Value:
3

CLOSE_CURRENT_RESULT

(package private) static final int CLOSE_CURRENT_RESULT
Field Value:
1

DATALINK

(package private) static final int DATALINK
Field Value:
70

DEFAULT_FETCH_SIZE

(package private) static final int DEFAULT_FETCH_SIZE
Field Value:
100

EXECUTE_FAILED

(package private) static final Integer EXECUTE_FAILED

KEEP_CURRENT_RESULT

(package private) static final int KEEP_CURRENT_RESULT
Field Value:
2

NO_GENERATED_KEYS

(package private) static final int NO_GENERATED_KEYS
Field Value:
2

RETURN_GENERATED_KEYS

(package private) static final int RETURN_GENERATED_KEYS
Field Value:
1

SUCCESS_NO_INFO

(package private) static final Integer SUCCESS_NO_INFO

batchValues

protected ArrayList batchValues
Batched SQL Statement array.

closed

protected boolean closed
True if this statement is closed.

colMetaData

protected ColInfo[] colMetaData
The cached column meta data.

connection

protected ConnectionJDBC2 connection
The connection owning this statement object.

currentResult

protected JtdsResultSet currentResult
The current ResultSet.

cursorName

protected String cursorName
The cursor name to be used for positioned updates.

escapeProcessing

protected boolean escapeProcessing
True if SQL statements should be preprocessed.

fetchDirection

protected int fetchDirection
The fetch direction for result sets.

fetchSize

protected int fetchSize
The fetch size (default 100, only used by cursor ResultSets).

genKeyResultSet

protected JtdsResultSet genKeyResultSet
Dummy result set for getGeneratedKeys.

maxFieldSize

protected int maxFieldSize
The maximum field size (not used at present).

maxRows

protected int maxRows
The maximum number of rows to return (not used at present).

messages

protected final SQLDiagnostic messages
SQL Diagnostic exceptions and warnings.

openResultSets

protected ArrayList openResultSets
List of open result sets.

queryTimeout

protected int queryTimeout
The read query timeout in seconds

resultQueue

protected final LinkedList resultQueue
List of queued results (update counts, possibly followed by a ResultSet).

resultSetConcurrency

protected int resultSetConcurrency
The concurrency of result sets created by this statement.

resultSetType

protected int resultSetType
The type of result sets created by this statement.

tds

protected TdsCore tds
The TDS object used for server access.

updateCount

private int updateCount
The current update count.

Constructor Details

JtdsStatement

(package private)  JtdsStatement(ConnectionJDBC2 connection,
                                 int resultSetType,
                                 int resultSetConcurrency)
            throws SQLException
Construct a new Statement object.
Parameters:
connection - The parent connection.
resultSetType - The result set type for example TYPE_FORWARD_ONLY.
resultSetConcurrency - The concurrency for example CONCUR_READ_ONLY.

Method Details

addBatch

public void addBatch(String sql)
            throws SQLException

addWarning

(package private)  void addWarning(SQLWarning w)
Add an SQLWarning object to the statment warnings list.
Parameters:
w - The SQLWarning to add.

cacheResults

protected void cacheResults()
            throws SQLException
Cache as many results as possible (up to the first ResultSet). Called by ResultSets when the end is reached.

cancel

public void cancel()
            throws SQLException

checkCursorException

protected void checkCursorException(SQLException e)
            throws SQLException
Check that the exception is caused by the failure to open a cursor and not by a more serious SQL error.
Parameters:
e - the exception returned by the cursor class

checkOpen

protected void checkOpen()
            throws SQLException
Check that this statement is still open.

clearBatch

public void clearBatch()
            throws SQLException

clearWarnings

public void clearWarnings()
            throws SQLException

close

public void close()
            throws SQLException

closeAllResultSets

(package private)  void closeAllResultSets()
            throws SQLException
Close all result sets.

closeCurrentResultSet

(package private)  void closeCurrentResultSet()
            throws SQLException
Close current result set (if any).

execute

public boolean execute(String sql)
            throws SQLException

execute

public boolean execute(String sql,
                       String[] columnNames)
            throws SQLException

execute

public boolean execute(String sql,
                       int autoGeneratedKeys)
            throws SQLException

execute

public boolean execute(String sql,
                       int[] columnIndexes)
            throws SQLException

executeBatch

public int[] executeBatch()
            throws SQLException,
                   BatchUpdateException
Execute batch of SQL Statements.

The JDBC3 standard says that the behaviour of this method must be consistent for any DBMS. As Sybase (and to a lesser extent SQL Server) will sometimes continue after a batch execution error, the only way to comply with the standard is to always return an array of update counts the same size as the batch list. Slots in the array beyond the last executed statement are set to EXECUTE_FAILED.

Returns:
update counts as an int[]

executeImpl

private boolean executeImpl(String sql,
                            int autoGeneratedKeys,
                            boolean update)
            throws SQLException
Implements the common functionality for plain statement execute and {#link #executeUpdate}: basic checks, cleaning up of previous results, setting up and executing the query and loading the first results.
Parameters:
sql - an SQL INSERT, UPDATE or DELETE statement or an SQL statement that returns nothing, such as an SQL DDL statement
autoGeneratedKeys - a flag indicating whether auto-generated keys should be made available for retrieval
update - boolean flag indicating whether the caller is executeUpdate -- in this case an exception is thrown if the first result is not an update count and no cursor is created (direct execution)
Returns:
true if the first result is a ResultSet, false if it's an update count
See Also:
execute, executeUpdate

executeMSBatch

protected SQLException executeMSBatch(int size,
                                      int executeSize,
                                      ArrayList counts)
            throws SQLException
Execute the SQL batch on a MS server.
Parameters:
size - the total size of the batch
executeSize - the maximum number of statements to send in one request
counts - the returned update counts
Returns:
chained exceptions linked to a SQLException

executeQuery

public ResultSet executeQuery(String sql)
            throws SQLException

executeSQL

protected boolean executeSQL(String sql,
                             String spName,
                             ParamInfo[] params,
                             boolean returnKeys,
                             boolean update,
                             boolean useCursor)
            throws SQLException
Executes any type of SQL.
Parameters:
sql - the SQL statement to execute
spName - optional stored procedure name
params - optional parameters
returnKeys - whether the statement returns generated keys
update - whether the caller is executeUpdate
useCursor - whether the requested result set type or concurrency or connection properties request usage of a cursor
Returns:
true if the first result is a result set

executeSQLQuery

protected ResultSet executeSQLQuery(String sql,
                                    String spName,
                                    ParamInfo[] params,
                                    boolean useCursor)
            throws SQLException
Executes SQL to obtain a result set.
Parameters:
sql - the SQL statement to execute
spName - optional stored procedure name
params - optional parameters
useCursor - whether a cursor should be created for the SQL
Returns:
the result set generated by the query

executeSybaseBatch

protected SQLException executeSybaseBatch(int size,
                                          int executeSize,
                                          ArrayList counts)
            throws SQLException
Execute the SQL batch on a Sybase server.

Sybase needs to have the SQL concatenated into one TDS language packet. This method will be overriden for PreparedStatements.

Parameters:
size - the total size of the batch
executeSize - the maximum number of statements to send in one request
counts - the returned update counts
Returns:
chained exceptions linked to a SQLException

executeUpdate

public int executeUpdate(String sql)
            throws SQLException

executeUpdate

public int executeUpdate(String sql,
                         String[] columnNames)
            throws SQLException

executeUpdate

public int executeUpdate(String sql,
                         int autoGeneratedKeys)
            throws SQLException

executeUpdate

public int executeUpdate(String sql,
                         int[] columnIndexes)
            throws SQLException

finalize

protected void finalize()
            throws Throwable
Called when this object goes out of scope to close any ResultSet object and this statement.

getConnection

public Connection getConnection()
            throws SQLException

getDefaultFetchSize

(package private)  int getDefaultFetchSize()
Retrieve the default fetch size for this statement.
Returns:
the default fetch size for a new ResultSet

getFetchDirection

public int getFetchDirection()
            throws SQLException

getFetchSize

public int getFetchSize()
            throws SQLException

getGeneratedKeys

public ResultSet getGeneratedKeys()
            throws SQLException

getMaxFieldSize

public int getMaxFieldSize()
            throws SQLException

getMaxRows

public int getMaxRows()
            throws SQLException

getMessages

(package private)  SQLDiagnostic getMessages()
Get the statement's warnings list.
Returns:
The warnings list as a SQLDiagnostic.

getMoreResults

public boolean getMoreResults()
            throws SQLException

getMoreResults

public boolean getMoreResults(int current)
            throws SQLException

getQueryTimeout

public int getQueryTimeout()
            throws SQLException

getResultSet

public ResultSet getResultSet()
            throws SQLException

getResultSetConcurrency

public int getResultSetConcurrency()
            throws SQLException

getResultSetHoldability

public int getResultSetHoldability()
            throws SQLException

getResultSetType

public int getResultSetType()
            throws SQLException

getTds

(package private)  TdsCore getTds()
Get the Statement's TDS object.
Returns:
The TDS support as a TdsCore Object.

getUpdateCount

public int getUpdateCount()
            throws SQLException

getWarnings

public SQLWarning getWarnings()
            throws SQLException

initialize

protected void initialize()
            throws SQLException
Initialize the Statement, by cleaning up all queued and unprocessed results. Called by all execute methods.

notImplemented

(package private) static void notImplemented(String method)
            throws SQLException
Report that user tried to call a method which has not been implemented.
Parameters:
method - The method name to report in the error message.

processResults

private boolean processResults(boolean returnKeys,
                               boolean update)
            throws SQLException
Queue up update counts into resultQueue until the end of the response is reached or a ResultSet is encountered. Calling processResults while a ResultSet is open will not close it, but will consume all remaining rows.
Parameters:
returnKeys - true if a generated keys ResultSet is expected
update - true if the method is called from within executeUpdate
Returns:
true if there are any results, false otherwise

setCursorName

public void setCursorName(String name)
            throws SQLException

setEscapeProcessing

public void setEscapeProcessing(boolean enable)
            throws SQLException

setFetchDirection

public void setFetchDirection(int direction)
            throws SQLException

setFetchSize

public void setFetchSize(int rows)
            throws SQLException

setMaxFieldSize

public void setMaxFieldSize(int max)
            throws SQLException

setMaxRows

public void setMaxRows(int max)
            throws SQLException

setQueryTimeout

public void setQueryTimeout(int seconds)
            throws SQLException

useCursor

protected boolean useCursor(boolean returnKeys,
                            String sqlWord)
Determines whether a cursor should be used based on the requested result set type and concurrency, whether a cursor name has been set, the useCursors connection property has been set, the first word in the SQL query is either SELECT or EXEC/EXECUTE and no generated keys are returned.
Returns:
true if a cursor should be used, false if not

Generated on September 18 2009