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

📄 jtdsstatement.java

📁 第三方的SQL Server and Sybase的jdbc dirver,速度更快
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
     * @param spName     optional stored procedure name     * @param params     optional parameters     * @param returnKeys whether the statement returns generated keys     * @param update     whether the caller is {@link #executeUpdate}     * @param useCursor  whether the requested result set type or concurrency     *                   or connection properties request usage of a cursor     * @return <code>true</code> if the first result is a result set     * @throws SQLException if an error condition occurs     */    protected boolean executeSQL(String sql,                                 String spName,                                 ParamInfo[] params,                                 boolean returnKeys,                                 boolean update,                                 boolean useCursor)            throws SQLException {        String warningMessage = null;        //        // For SQL Server, try to open a cursor result set if required        // (and possible).        //        if (connection.getServerType() == Driver.SQLSERVER && !update && useCursor) {            try {                currentResult = new MSCursorResultSet(this, sql, spName,                        params, resultSetType, resultSetConcurrency);                return true;            } 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();            }        }        //        // We are talking to a Sybase server or we could not open a cursor        // or we did not have a SELECT so just execute the SQL normally.        //        tds.executeSQL(sql, spName, params, false, queryTimeout, maxRows,                maxFieldSize, true);        if (warningMessage != null) {            // Update warning chain if cursor was downgraded            addWarning(new SQLWarning(Messages.get(                    "warning.cursordowngraded", warningMessage), "01000"));        }        if (processResults(returnKeys, update)) {            Object nextResult = resultQueue.removeFirst();            // Next result is an update count            if (nextResult instanceof Integer) {                updateCount = ((Integer) nextResult).intValue();                return false;            }            // Next result is a ResultSet. Set currentResult and remove it.            currentResult = (JtdsResultSet) nextResult;            return true;        } else {            return false;        }    }    /**     * Queue up update counts into {@link #resultQueue} until the end of the     * response is reached or a <code>ResultSet</code> is encountered. Calling     * <code>processResults</code> while a <code>ResultSet</code> is open will     * not close it, but will consume all remaining rows.     *     * @param returnKeys <code>true</code> if a generated keys     *                   <code>ResultSet</code> is expected     * @param update     <code>true</code> if the method is called from within     *                   <code>executeUpdate</code>     * @return           <code>true</code> if there are any results,     *                   <code>false</code> otherwise     * @throws SQLException if an error condition occurs     */    private boolean processResults(boolean returnKeys, boolean update) throws SQLException {        if (!resultQueue.isEmpty()) {            throw new IllegalStateException(                    "There should be no queued results.");        }        while (!tds.isEndOfResponse()) {            if (!tds.getMoreResults()) {                if (tds.isUpdateCount()) {                    if (update && connection.isLastUpdateCount()) {                        resultQueue.clear();                    }                    resultQueue.addLast(new Integer(tds.getUpdateCount()));                }            } else {                if (returnKeys) {                    // This had better be the generated key                    // FIXME We could use SELECT @@IDENTITY AS jTDS_SOMETHING and check the column name to make sure                    if (tds.getNextRow()) {                        genKeyResultSet = new CachedResultSet(this,                                tds.getColumns(),                                tds.getRowData());                    }                } else {                    if (update && resultQueue.isEmpty()) {                        // Throw exception but queue up any previous ones                        SQLException ex = new SQLException(                                Messages.get("error.statement.nocount"), "07000");                        ex.setNextException(messages.exceptions);                        throw ex;                    }                    resultQueue.add(new JtdsResultSet(                            this,                            ResultSet.TYPE_FORWARD_ONLY,                            ResultSet.CONCUR_READ_ONLY,                            tds.getColumns()));                    break;                }            }        }        // Check for server side errors        getMessages().checkErrors();        return !resultQueue.isEmpty();    }    /**     * Cache as many results as possible (up to the first     * <code>ResultSet</code>). Called by <code>ResultSet</code>s when the     * end is reached.     */    protected void cacheResults() throws SQLException {        // Cache results        processResults(false, false);    }    /**     * Initialize the <code>Statement</code>, by cleaning up all queued and     * unprocessed results. Called by all execute methods.     *     * @throws SQLException if an error occurs     */    protected void initialize() throws SQLException {        updateCount = -1;        resultQueue.clear();        genKeyResultSet = null;        tds.clearResponseQueue();        // FIXME Should old exceptions found now be thrown instead of lost?        messages.exceptions = null;        messages.clearWarnings();        closeAllResultSets();    }    /**     * Implements the common functionality for plain statement {@link #execute}     * and {#link #executeUpdate}: basic checks, cleaning up of previous     * results, setting up and executing the query and loading the first     * results.     *     * @param sql    an SQL <code>INSERT</code>, <code>UPDATE</code> or     *               <code>DELETE</code> statement or an SQL statement that     *               returns nothing, such as an SQL DDL statement     * @param autoGeneratedKeys a flag indicating whether auto-generated keys     *               should be made available for retrieval     * @param update boolean flag indicating whether the caller is     *               {@link #executeUpdate} -- in this case an exception is     *               thrown if the first result is not an update count and no     *               cursor is created (direct execution)     * @return <code>true</code> if the first result is a     *         <code>ResultSet</code>, <code>false</code> if it's an update     *         count     * @see #execute     * @see #executeUpdate     */    private boolean executeImpl(String sql, int autoGeneratedKeys, boolean update)            throws SQLException {        checkOpen();        initialize();        if (sql == null || sql.length() == 0) {            throw new SQLException(Messages.get("error.generic.nosql"), "HY000");        }        boolean returnKeys;        String sqlWord = "";        if (escapeProcessing) {            String tmp[] = SQLParser.parse(sql, null, connection, false);            if (tmp[1].length() != 0) {                throw new SQLException(                        Messages.get("error.statement.badsql"), "07000");            }            sql = tmp[0];            sqlWord = tmp[2];        } else {            // Escape processing turned off so            // see if we can extract "insert" from start of statement            sql = sql.trim();            if (sql.length() > 5) {                sqlWord = sql.substring(0,6).toLowerCase();            }        }        if (autoGeneratedKeys == RETURN_GENERATED_KEYS) {            returnKeys = sqlWord.equals("insert");        } else if (autoGeneratedKeys == NO_GENERATED_KEYS) {            returnKeys = false;        } else {            throw new SQLException(                    Messages.get("error.generic.badoption",                            Integer.toString(autoGeneratedKeys),                            "autoGeneratedKeys"),                    "HY092");        }        if (returnKeys) {            if (connection.getServerType() == Driver.SQLSERVER                    && connection.getDatabaseMajorVersion() >= 8) {                sql += " SELECT SCOPE_IDENTITY() AS ID";            } else {                sql += " SELECT @@IDENTITY AS ID";            }        }        return executeSQL(sql, null, null, returnKeys, update,                !update && useCursor(returnKeys, 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     * <code>useCursors</code> connection property has been set, the first     * word in the SQL query is either SELECT or EXEC/EXECUTE and no generated     * keys are returned.     *     * @param returnKeys indicates whether keys will be returned by the query     * @param sqlWord    the first word in the SQL query; can be     *                   <code>null</code> if the caller is     *                   {@link #executeQuery}     * @return <code>true</code> if a cursor should be used, <code>false</code>     *         if not     */    protected boolean useCursor(boolean returnKeys, String sqlWord) {        return (resultSetType != ResultSet.TYPE_FORWARD_ONLY                    || resultSetConcurrency != ResultSet.CONCUR_READ_ONLY                    || connection.getUseCursors()                    || cursorName != null)                && !returnKeys                && (sqlWord == null || sqlWord.equals("select") || sqlWord.startsWith("exec"));    }// ------------------ java.sql.Statement methods ----------------------    public int getFetchDirection() throws SQLException {        checkOpen();        return this.fetchDirection;    }    public int getFetchSize() throws SQLException {        checkOpen();        return this.fetchSize;    }    public int getMaxFieldSize() throws SQLException {        checkOpen();        return this.maxFieldSize;    }    public int getMaxRows() throws SQLException {        checkOpen();        return this.maxRows;    }    public int getQueryTimeout() throws SQLException {        checkOpen();        return this.queryTimeout;    }    public int getResultSetConcurrency() throws SQLException {        checkOpen();        return this.resultSetConcurrency;    }    public int getResultSetHoldability() throws SQLException {        checkOpen();        return JtdsResultSet.HOLD_CURSORS_OVER_COMMIT;    }    public int getResultSetType() throws SQLException {        checkOpen();        return resultSetType;    }    public int getUpdateCount() throws SQLException {        checkOpen();        return updateCount;    }    public void cancel() throws SQLException {        checkOpen();        if (tds != null) {            tds.cancel();        }    }    public void clearBatch() throws SQLException {        checkOpen();        if (batchValues != null) {            batchValues.clear();        }    }    public void clearWarnings() throws SQLException {        checkOpen();        messages.clearWarnings();    }    public void close() throws SQLException {        if (!closed) {            try {                closeAllResultSets();            } finally {                SQLException releaseEx = null;                try {                    if (!connection.isClosed()) {                        connection.releaseTds(tds);                    }                    // Check for server side errors                    tds.getMessages().checkErrors();                } catch (SQLException ex) {                    // Remember any exception thrown                    releaseEx = ex;                } finally {                    // Clean up everything                    closed = true;                    tds = null;                    connection.removeStatement(this);                    connection = null;                    // Re-throw any caught exception                    if (releaseEx != null) {                        throw releaseEx;                    }                }            }        }    }    public boolean getMoreResults() throws SQLException {        checkOpen();        return getMoreResults(CLOSE_ALL_RESULTS);    }    /**     * Execute batch of SQL Statements.     * <p/>     * The JDBC3 standard says that for a server which does not continue     * processing a batch once the first error has occurred (e.g. SQL Server),     * the returned array will never contain <code>EXECUTE_FAILED</code> in any     * of the elements. If a failure has occurred the array length will be less     * than the count of statements in the batch. For those servers that do     * continue to execute a batch containing an error (e.g. Sybase), elements     * may contain <code>EXECUTE_FAILED</code>. Note: even here the array     * length may also be shorter than the statement count if a serious error     * has prevented the rest of the batch from being executed. In addition,     * when executing batched stored procedures, Sybase will also stop after     * the first error.     *     * @return update counts as an <code>int[]</code>     */    public int[] executeBatch()            throws SQLException, BatchUpdateException {        checkOpen();        initialize();

⌨️ 快捷键说明

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