📄 preparedstatement_base.java
字号:
//
// Copyright 1998,1999 CDS Networks, Inc., Medford Oregon
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. 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.
// 3. All advertising materials mentioning features or use of this software
// must display the following acknowledgement:
// This product includes software developed by CDS Networks, Inc.
// 4. The name of CDS Networks, Inc. may not be used to endorse or promote
// products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY CDS NETWORKS, INC. ``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 CDS NETWORKS, INC. 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 com.internetcds.jdbc.tds;
import java.sql.*;
import java.math.BigDecimal;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.Calendar;
import java.io.*;
/**
* <P>A SQL statement is pre-compiled and stored in a
* PreparedStatement object. This object can then be used to
* efficiently execute this statement multiple times.
*
* <P><B>Note:</B> The setXXX methods 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
* Integer then setInt should be used.
*
* <p>If arbitrary parameter type conversions are required then the
* setObject method should be used with a target SQL type.
*
* @author Craig Spannring
* @author The FreeTDS project
* @version $Id: PreparedStatement_base.java,v 1.1 2003/04/29 18:07:50 sinisa Exp $
*
* @see Connection#prepareStatement
* @see ResultSet
*/
public class PreparedStatement_base
extends com.internetcds.jdbc.tds.Statement
implements PreparedStatementHelper
{
public static final String cvsVersion = "$Id: PreparedStatement_base.java,v 1.1 2003/04/29 18:07:50 sinisa Exp $";
String rawQueryString = null;
Vector procedureCache = null;
ParameterListItem[] parameterList = null;
public PreparedStatement_base(
java.sql.Connection conn_,
Tds tds_,
String sql)
throws SQLException
{
super(conn_, tds_);
rawQueryString = sql;
int i;
int numberOfParameters = ParameterUtils.countParameters(rawQueryString);
parameterList = new ParameterListItem[numberOfParameters];
for(i=0; i<numberOfParameters; i++)
{
parameterList[i] = new ParameterListItem();
}
procedureCache = new Vector();
}
protected void NotImplemented() throws java.sql.SQLException
{
throw new SQLException("Not Implemented");
}
/**
* <P>In general, parameter values remain in force for repeated use of a
* Statement. Setting a parameter value automatically clears its
* previous value. However, in some cases it is useful to immediately
* release the resources used by the current parameter values; this can
* be done by calling clearParameters.
*
* @exception SQLException if a database-access error occurs.
*/
public void clearParameters() throws SQLException
{
int i;
for(i=0; i<parameterList.length; i++)
{
parameterList[i].clear();
}
}
public void dropAllProcedures()
{
procedureCache = null;
procedureCache = new Vector();
}
/**
* Some prepared statements return multiple results; the execute
* method handles these complex statements as well as the simpler
* form of statements handled by executeQuery and executeUpdate.
*
* @exception SQLException if a database-access error occurs.
* @see Statement#execute
*/
public boolean execute() throws SQLException
{
//
// TDS can handle prepared statements by creating a temporary
// procedure. Since procedure must have the datatype specified
// in the procedure declaration we will have to defer creating
// the actual procedure until the statement is executed. By
// that time we know all the types of all of the parameters.
//
Procedure procedure = null;
boolean result = false;
closeResults();
updateCount = -2;
// First make sure the caller has filled in all the parameters.
ParameterUtils.verifyThatParametersAreSet(parameterList);
// Find a stored procedure that is compatible with this set of
// parameters if one exists.
procedure = findCompatibleStoredProcedure();
// if we don't have a suitable match then create a new
// temporary stored procedure
if (procedure == null)
{
// create the stored procedure
procedure = new Procedure(rawQueryString,
tds.getUniqueProcedureName(),
parameterList, tds);
// store it in the procedureCache
procedureCache.addElement(procedure);
// create it on the SQLServer.
submitProcedure(procedure);
}
result = executeCall(procedure.getProcedureName(),
procedure.getParameterList(), // formal params
parameterList); // actual params
return result;
}
protected boolean executeCall(
String name,
ParameterListItem[] formalParameterList,
ParameterListItem[] actualParameterList)
throws SQLException
{
boolean result;
boolean wasCanceled = false;
try
{
SQLException exception = null;
PacketResult tmp = null;
// execute the stored procedure.
tds.executeProcedure(name,
formalParameterList,
actualParameterList,
this,
timeout);
while (tds.isErrorPacket() || tds.isMessagePacket())
{
tmp = tds.processSubPacket();
exception = warningChain.addOrReturn((PacketMsgResult)tmp);
if (exception != null)
{
throw exception;
}
}
while(tds.isDoneInProc())
{
tmp = tds.processSubPacket();
}
if (tds.isProcId())
{
tmp = tds.processSubPacket();
}
if (tds.isResultSet())
{
result = true;
}
else
{
result = false;
boolean done = false;
do
{
tmp = tds.processSubPacket();
if (tmp instanceof PacketEndTokenResult)
{
done = ! ((PacketEndTokenResult)tmp).moreResults();
wasCanceled = wasCanceled
|| ((PacketEndTokenResult)tmp).wasCanceled();
updateCount = ((PacketEndTokenResult)tmp).getRowCount();
}
else if (tmp.getPacketType()
== TdsDefinitions.TDS_RET_STAT_TOKEN)
{
// nop
}
else
{
throw new SQLException("Protocol confusion"
+ "Found a "
+ tmp.getClass().getName()
+ " (packet type 0x"
+ Integer.toHexString(tmp.getPacketType()
& 0xff)
+ ")");
}
} while (!done);
}
}
catch(TdsException e)
{
e.printStackTrace();
throw new SQLException(e.getMessage());
}
catch(java.io.IOException e)
{
e.printStackTrace();
throw new SQLException(e.getMessage());
}
if (wasCanceled)
{
throw new SQLException("Query was canceled or timed out.");
}
return result;
}
private Procedure findCompatibleStoredProcedure()
throws SQLException
{
Procedure procedure = null;
int i;
for(i=0; i<procedureCache.size(); i++)
{
Procedure tmp = (Procedure)procedureCache.elementAt(i);
if (tmp.compatibleParameters(parameterList))
{
procedure = tmp;
if (!tmp.hasLobParameters())
{
break;
}
}
}
return procedure;
}
private void submitProcedure(Procedure proc)
throws SQLException
{
String sql = proc.getPreparedSqlString();
tds.submitProcedure(sql, warningChain);
}
/**
* A prepared SQL query is executed and its ResultSet is returned.
*
* @return a ResultSet that contains the data produced by the
* query; never null
* @exception SQLException if a database-access error occurs.
*/
public java.sql.ResultSet executeQuery() throws SQLException
{
if (execute())
{
startResultSet();
}
else
{
throw new SQLException("Was expecting a result set");
}
return results;
}
/**
* Execute a SQL INSERT, UPDATE or DELETE statement. In addition,
* SQL statements that return nothing such as SQL DDL statements
* can be executed.
*
* @return either the row count for INSERT, UPDATE or DELETE; or 0
* for SQL statements that return nothing
* @exception SQLException if a database-access error occurs.
*/
public int executeUpdate() throws SQLException
{
closeResults();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -