📄 embedstatement.java
字号:
boolean executeHoldable = getExecuteHoldable(); a.setResultSetHoldability(executeHoldable); //reset the activation to clear warnings //and clear existing result sets in case this has been cached a.reset(); a.setMaxRows(maxRows); ResultSet resultsToWrap = ps.execute(a, executeQuery, executeUpdate, false); addWarning(a.getWarnings()); if (resultsToWrap.returnsRows()) { EmbedResultSet lresults = factory.newEmbedResultSet(getEmbedConnection(), resultsToWrap, forMetaData, this, ps.isAtomic()); results = lresults; // Set up the finalization of the ResultSet to // mark the activation as unused. It will be // closed sometime later by the connection // outside of finalization. if (a.isSingleExecution()) lresults.finalizeActivation = a; updateCount = -1; retval = true; } else { // Only applipable for an insert statement, which does not return rows. //the auto-generated keys resultset will be null if used for non-insert statement if (a.getAutoGeneratedKeysResultsetMode() && (resultsToWrap.getAutoGeneratedKeysResultset() != null)) { resultsToWrap.getAutoGeneratedKeysResultset().open(); autoGeneratedKeysResultSet = factory.newEmbedResultSet(getEmbedConnection(), resultsToWrap.getAutoGeneratedKeysResultset(), false, this, ps.isAtomic()); } updateCount = resultsToWrap.modifiedRowCount(); resultsToWrap.finish(); // Don't need the result set any more results = null; // note that we have none. boolean haveDynamicResults = false; if (a.getDynamicResults() != null) { haveDynamicResults = processDynamicResults(a.getDynamicResults(), a.getMaxDynamicResults()); } if (!haveDynamicResults) { if (a.isSingleExecution()) { a.close(); } if (!forMetaData) commitIfNeeded(); else { if (lcc.getActivationCount() > 1) { // we do not want to commit here as there seems to be other // statements/resultSets currently opened for this connection. } else { commitIfNeeded(); // we can legitimately commit } } } retval = haveDynamicResults; } } catch (Throwable t) { if (a.isSingleExecution()) { try { a.close(); } catch (Throwable tt) {;} } throw handleException(t); } finally { restoreContextStack(); } return retval; } } /** * Add a SQLWarning to this Statement object. * If the Statement already has a SQLWarning then it * is added to the end of the chain. * * @see #getWarnings() */ final void addWarning(SQLWarning sw) { if (sw != null) { if (warnings == null) warnings = sw; else warnings.setNextException(sw); } } /* package */ public String getSQLText() { // no need to synchronize - accessing a reference is atomic // synchronized (getConnectionSynchronization()) return SQLText; } public ParameterValueSet getParameterValueSet() { return pvs; } //check the status of this statement, if it has already been closed, //we throw an exception, need to be called by every public method protected final void checkStatus() throws SQLException { if (!active) throw newSQLException(SQLState.ALREADY_CLOSED, "Statement"); } /** A heavier weight version of checkStatus() that ensures the application's Connection object is still open. This is to stop errors or unexpected behaviour when a [Prepared]Statement object is used after the application has been closed. In particular to ensure that a Statement obtained from a PooledConnection cannot be used after the application has closed its connection (as the underlying Connection is still active). To avoid this heavier weight check on every method of [Prepared]Statement it is only used on those methods that would end up using the database's connection to read or modify data. E.g. execute*(), but not setXXX, etc. */ protected final void checkExecStatus() throws SQLException { // getConnection() checks if the Statement is closed if (!getConnection().isClosed()) return; throw Util.noCurrentConnection(); } /** Close and clear all result sets associated with this statement from the last execution. */ void clearResultSets() throws SQLException { SQLException sqle = null; try { // Are there results? // outside of the lower try/finally since results will // setup and restore themselves. if (results != null) { results.close(); results = null; } } catch (SQLException s1) { sqle = s1; } try { if (autoGeneratedKeysResultSet != null) { autoGeneratedKeysResultSet.close(); autoGeneratedKeysResultSet = null; } } catch (SQLException sauto) { if (sqle == null) sqle = sauto; else sqle.setNextException(sauto); } // close all the dynamic result sets. if (dynamicResults != null) { for (int i = 0; i < dynamicResults.length; i++) { EmbedResultSet lrs = dynamicResults[i]; if (lrs == null) continue; try { if (!lrs.isClosed) lrs.close(); } catch (SQLException sdynamic) { if (sqle == null) sqle = sdynamic; else sqle.setNextException(sdynamic); } } dynamicResults = null; } /* We don't reset statement to null because PreparedStatement relies on it being there for subsequent (post-close) execution requests. There is no close method on database statement objects. */ updateCount = -1; // reset field if (sqle != null) throw sqle; } /** Check to see if a statement requires to be executed via a callable statement. */ void checkRequiresCallableStatement(Activation activation) throws SQLException { ParameterValueSet pvs = activation.getParameterValueSet(); if (pvs == null) return; if (pvs.checkNoDeclaredOutputParameters()) { try { activation.close(); } catch (StandardException se) { } throw newSQLException(SQLState.REQUIRES_CALLABLE_STATEMENT, SQLText); } } /** Transfer my batch of Statements to a newly created Statement. */ public void transferBatch(EmbedStatement other) throws SQLException { synchronized (getConnectionSynchronization()) { other.batchStatements = batchStatements; batchStatements = null; } } /** * Set the application statement for this Statement. */ public final void setApplicationStatement(EngineStatement s) { this.applicationStatement = s; } private EmbedResultSet[] dynamicResults; private int currentDynamicResultSet; private boolean processDynamicResults(java.sql.ResultSet[][] holder, int maxDynamicResultSets) throws SQLException { EmbedResultSet[] sorted = new EmbedResultSet[holder.length]; int actualCount = 0; for (int i = 0; i < holder.length; i++) { java.sql.ResultSet[] param = holder[i]; if (param[0] == null) continue; java.sql.ResultSet rs = param[0]; param[0] = null; // ignore non-cloudscape result sets or results sets from another connection if (!(rs instanceof EmbedResultSet)) continue; EmbedResultSet lrs = (EmbedResultSet) rs; if (lrs.getEmbedConnection().rootConnection != getEmbedConnection().rootConnection) continue; // ignore closed result sets. if (lrs.isClosed) continue; lrs.setDynamicResultSet(this); sorted[actualCount++] = lrs; } if (actualCount != 0) { // results are defined to be ordered according to their creation if (actualCount != 1) { java.util.Arrays.sort(sorted, 0, actualCount); } dynamicResults = sorted; if (actualCount > maxDynamicResultSets) { addWarning(StandardException.newWarning(SQLState.LANG_TOO_MANY_DYNAMIC_RESULTS_RETURNED)); for (int i = maxDynamicResultSets; i < actualCount; i++) { sorted[i].close(); sorted[i] = null; } actualCount = maxDynamicResultSets; } updateCount = -1; results = sorted[0]; currentDynamicResultSet = 0; // 0100C is not returned for procedures written in Java, from the SQL2003 spec. // getWarnings(StandardException.newWarning(SQLState.LANG_DYNAMIC_RESULTS_RETURNED)); return true; } return false; } /** Callback on the statement when one of its result sets is closed. This allows the statement to control when it completes and hence when it commits in auto commit mode. Must have connection synchronization and setupContextStack(), this is required for the call to commitIfNeeded(). */ void resultSetClosing(EmbedResultSet closingLRS) throws SQLException { // If the Connection is not in auto commit then this statement completion // cannot cause a commit. if (!getEmbedConnection().autoCommit) return; // If we have dynamic results, see if there is another result set open. // If so, then no commit. The last result set to close will close the statement. if (dynamicResults != null) { for (int i = 0; i < dynamicResults.length; i++) { EmbedResultSet lrs = dynamicResults[i]; if (lrs == null) continue; if (lrs.isClosed) continue; if (lrs == closingLRS) continue; // at least one still open so no commit now. return; } } // new Throwable("COMMIT ON " + SQLText).printStackTrace(System.out); // beetle 5383. Force a commit in autocommit always. Before this // change if client in autocommit opened a result set, did a commit, // then next then close a commit would not be forced on the close. commitIfAutoCommit(); } /** * Get the execute time holdability for the Statement. * When in a global transaction holdabilty defaults to false. * @throws SQLException Error from getResultSetHoldability. */ private boolean getExecuteHoldable() throws SQLException { if (resultSetHoldability == JDBC30Translation.CLOSE_CURSORS_AT_COMMIT) return false; // Simple non-XA case if (applicationStatement == this) return true; return applicationStatement.getResultSetHoldability() == JDBC30Translation.HOLD_CURSORS_OVER_COMMIT; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -