⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jtdsstatement.java

📁 第三方的SQL Server and Sybase的jdbc dirver,速度更快
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
// jTDS JDBC Driver for Microsoft SQL Server and Sybase// Copyright (C) 2004 The jTDS Project//// This library is free software; you can redistribute it and/or// modify it under the terms of the GNU Lesser General Public// License as published by the Free Software Foundation; either// version 2.1 of the License, or (at your option) any later version.//// This library is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU// Lesser General Public License for more details.//// You should have received a copy of the GNU Lesser General Public// License along with this library; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA//package net.sourceforge.jtds.jdbc;import java.sql.BatchUpdateException;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.SQLWarning;import java.sql.Types;import java.util.ArrayList;import java.util.LinkedList;/** * jTDS implementation of the java.sql.Statement interface.<p> * NB. As allowed by the JDBC standard and like most other drivers, * this implementation only allows one open result set at a time. * <p> * Implementation notes: * <p> * I experimented with allowing multiple open result sets as supported * by the origianal jTDS but rejected this approach for the following * reasons: * <ol> * <li>It is more difficult to ensure that there are no memory leaks and that *     cursors are closed if multiple open sets are allowed. * <li>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. * </ol> * 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. * * @see java.sql.Statement * @see java.sql.Connection#createStatement * @see java.sql.ResultSet * * @author Mike Hutchinson * @version $Id: JtdsStatement.java,v 1.48 2005/06/15 14:56:58 alin_sinpalean Exp $ */public class JtdsStatement implements java.sql.Statement {    /*     * Constants used for backwards compatibility with JDK 1.3     */    static final int RETURN_GENERATED_KEYS = 1;    static final int NO_GENERATED_KEYS = 2;    static final int CLOSE_CURRENT_RESULT = 1;    static final int KEEP_CURRENT_RESULT = 2;    static final int CLOSE_ALL_RESULTS = 3;    static final int BOOLEAN = 16;    static final int DATALINK = 70;    static final Integer SUCCESS_NO_INFO = new Integer(-2);    static final Integer EXECUTE_FAILED = new Integer(-3);    /** The connection owning this statement object. */    protected ConnectionJDBC2 connection;    /** The TDS object used for server access. */    protected TdsCore tds;    /** The read query timeout in seconds */    protected int queryTimeout;    /** The current <code>ResultSet</code>. */    protected JtdsResultSet currentResult;    /** The current update count. */    private int updateCount = -1;    /** The fetch direction for result sets. */    protected int fetchDirection = ResultSet.FETCH_FORWARD;    /** The type of result sets created by this statement. */    protected int resultSetType = ResultSet.TYPE_FORWARD_ONLY;    /** The concurrency of result sets created by this statement. */    protected int resultSetConcurrency = ResultSet.CONCUR_READ_ONLY;    /** The fetch size (default 100, only used by cursor     * <code>ResultSet</code>s).     */    protected int fetchSize = 100;    /** The cursor name to be used for positioned updates. */    protected String cursorName;    /** True if this statement is closed. */    protected boolean closed;    /** The maximum field size (not used at present). */    protected int maxFieldSize;    /** The maximum number of rows to return (not used at present). */    protected int maxRows;    /** True if SQL statements should be preprocessed. */    protected boolean escapeProcessing = true;    /** SQL Diagnostic exceptions and warnings. */    protected final SQLDiagnostic messages;    /** Batched SQL Statement array. */    protected ArrayList batchValues;    /** Dummy result set for getGeneratedKeys. */    protected JtdsResultSet genKeyResultSet;    /**     * List of queued results (update counts, possibly followed by a     * <code>ResultSet</code>).     */    protected final LinkedList resultQueue = new LinkedList();    /** List of open result sets. */    protected ArrayList openResultSets;    /** The cached column meta data. */    protected ColInfo[] colMetaData;    /**     * Construct a new Statement object.     *     * @param connection The parent connection.     * @param resultSetType The result set type for example TYPE_FORWARD_ONLY.     * @param resultSetConcurrency The concurrency for example CONCUR_READ_ONLY.     */    JtdsStatement(ConnectionJDBC2 connection,                  int resultSetType,                  int resultSetConcurrency) throws SQLException {        //        // This is a good point to do common validation of the result set type        //        if (resultSetType < ResultSet.TYPE_FORWARD_ONLY                || resultSetType > ResultSet.TYPE_SCROLL_SENSITIVE + 1) {            String method;            if (this instanceof JtdsCallableStatement) {                method = "prepareCall";            } else if (this instanceof JtdsPreparedStatement) {                method = "prepareStatement";            } else {                method = "createStatement";            }            throw new SQLException(                       Messages.get("error.generic.badparam",                               "resultSetType",                               method),                    "HY092");        }        //        // Ditto for the result set concurrency        //        if (resultSetConcurrency < ResultSet.CONCUR_READ_ONLY                || resultSetConcurrency > ResultSet.CONCUR_UPDATABLE + 2) {                String method;                if (this instanceof JtdsCallableStatement) {                    method = "prepareCall";                } else if (this instanceof JtdsPreparedStatement) {                    method = "prepareStatement";                } else {                    method = "createStatement";                }                throw new SQLException(                        Messages.get("error.generic.badparam",                                "resultSetConcurrency",                                method),                        "HY092");        }        this.connection = connection;        this.resultSetType = resultSetType;        this.resultSetConcurrency = resultSetConcurrency;        this.tds = connection.getCachedTds();        if (this.tds == null) {            this.messages = new SQLDiagnostic(connection.getServerType());            this.tds = new TdsCore(this.connection, messages);        } else {            this.messages = tds.getMessages();        }    }    /**     * Called when this object goes out of scope to close any     * <code>ResultSet</code> object and this statement.     */    protected void finalize() {       try {           close();       } catch (SQLException e) {           // Ignore errors       }   }    /**     * Get the Statement's TDS object.     *     * @return The TDS support as a <code>TdsCore</core> Object.     */    TdsCore getTds() {        return tds;    }    /**     * Get the statement's warnings list.     *     * @return The warnings list as a <code>SQLDiagnostic</code>.     */    SQLDiagnostic getMessages() {        return messages;    }    /**     * Check that this statement is still open.     *     * @throws SQLException if statement closed.     */    protected void checkOpen() throws SQLException {        if (closed || connection == null || connection.isClosed()) {            throw new SQLException(                    Messages.get("error.generic.closed", "Statement"), "HY010");        }    }    /**     * Report that user tried to call a method which has not been implemented.     *     * @param method The method name to report in the error message.     * @throws SQLException     */    static void notImplemented(String method) throws SQLException {        throw new SQLException(                Messages.get("error.generic.notimp", method), "HYC00");    }    /**     * Close current result set (if any).     */    void closeCurrentResultSet() throws SQLException {        try {            if (currentResult != null) {                currentResult.close();            }//        } catch (SQLException e) {            // Ignore        } finally {            currentResult = null;        }    }    /**     * Close all result sets.     */    void closeAllResultSets() throws SQLException {        try {            if (openResultSets != null) {                for (int i = 0; i < openResultSets.size(); i++) {                    JtdsResultSet rs = (JtdsResultSet) openResultSets.get(i);                    if (rs != null) {                        rs.close();                    }                }            }            closeCurrentResultSet();        } finally {            openResultSets = null;        }    }    /**     * Add an SQLWarning object to the statment warnings list.     *     * @param w The SQLWarning to add.     */    void addWarning(SQLWarning w) {        messages.addWarning(w);    }    /**     * This method should be over-ridden by any sub-classes that place values     * other than <code>String</code>s into the <code>batchValues</code> list     * to handle execution properly.     *     * @param value SQL <code>String</code> or list of parameters to execute     * @param last  <code>true</code> if this is the last query/parameter list     *              in the batch     */    protected void executeBatchOther(Object value, boolean last)            throws SQLException {        throw new SQLException(                Messages.get("error.statement.badbatch",                        value.toString()), "HYC00");    }    /**     * Executes SQL to obtain a result set.     *     * @param sql       the SQL statement to execute     * @param spName    optional stored procedure name     * @param params    optional parameters     * @param useCursor whether a cursor should be created for the SQL     * @return the result set generated by the query     */    protected ResultSet executeSQLQuery(String sql,                                        String spName,                                        ParamInfo[] params,                                        boolean useCursor)            throws SQLException {        String warningMessage = null;        //        // Try to open a cursor result set if required        //        if (useCursor) {            try {                if (connection.getServerType() == Driver.SQLSERVER) {                    currentResult =                            new MSCursorResultSet(this,                                    sql,                                    spName,                                    params,                                    resultSetType,                                    resultSetConcurrency);                    return currentResult;                } else {                    // Use client side cursor for Sybase                    currentResult =                        new CachedResultSet(this,                                sql,                                spName,                                params,                                resultSetType,                                resultSetConcurrency);                    return currentResult;                }            } catch (SQLException e) {                if (connection == null || connection.isClosed()                        || "HYT00".equals(e.getSQLState())) {                    // Serious error or timeout so return exception to caller                    throw e;                }                warningMessage = '[' + e.getSQLState() + "] " + e.getMessage();            }        }        //        // Could not open a cursor (or was not requested) so try a direct select        //        if (spName != null                && connection.getUseMetadataCache()                && connection.getPrepareSql() == TdsCore.PREPARE                && colMetaData != null                && connection.getServerType() == Driver.SQLSERVER) {            // There is cached meta data available for this            // prepared statement            tds.setColumns(colMetaData);            tds.executeSQL(sql, spName, params, true, queryTimeout, maxRows,                    maxFieldSize, true);        } else {            tds.executeSQL(sql, spName, params, false, queryTimeout, maxRows,                    maxFieldSize, true);        }        // Update warning chain if cursor was downgraded before processing results        if (warningMessage != null) {            addWarning(new SQLWarning(                    Messages.get("warning.cursordowngraded", warningMessage), "01000"));        }        // Ignore update counts preceding the result set. All drivers seem to        // do this.        while (!tds.getMoreResults() && !tds.isEndOfResponse());        // check for server side errors        messages.checkErrors();        if (tds.isResultSet()) {            currentResult = new JtdsResultSet(this,                                              ResultSet.TYPE_FORWARD_ONLY,                                              ResultSet.CONCUR_READ_ONLY,                                              tds.getColumns());        } else {            throw new SQLException(                    Messages.get("error.statement.noresult"), "24000");        }        return currentResult;    }    /**     * Executes any type of SQL.     *     * @param sql        the SQL statement to execute

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -