private bool NextResult(bool disposing, bool allresults) { // if disposing, loop through all the remaining results and ignore error messages // if allresults, loop through all results and collect all error messages for a single exception // callers are via Close(false, true), Dispose(true, false), NextResult(false,false) Debug.Assert(!disposing || !allresults, "both disposing & allresults are true"); const int MaxConsecutiveFailure = 2000; // see WebData 72126 for why more than 1000 SQLLEN cRowsAffected; Int16 cColsAffected; ODBC32.RetCode retcode, firstRetCode = ODBC32.RetCode.SUCCESS; bool hasMoreResults; bool hasColumns = false; bool singleResult = IsCommandBehavior(CommandBehavior.SingleResult); if (IsClosed) { throw ADP.DataReaderClosed("NextResult"); } _fieldNameLookup = null; if (IsCancelingCommand || _noMoreResults) { return false; } //Blow away the previous cache (since the next result set will have a different shape, //different schema data, and different data. _isRead = false; _hasRows = HasRowsStatus.DontKnow; _fieldNameLookup = null; this.metadata = null; this.schemaTable = null; int loop = 0; // infinite loop protection, max out after 2000 consecutive failed results OdbcErrorCollection errors = null; // SQLBU 342112 do { _isValidResult = false; retcode = StatementHandle.MoreResults(); hasMoreResults = ((retcode == ODBC32.RetCode.SUCCESS) ||(retcode == ODBC32.RetCode.SUCCESS_WITH_INFO)); if (retcode == ODBC32.RetCode.SUCCESS_WITH_INFO) { Connection.HandleErrorNoThrow(StatementHandle, retcode); } else if (!disposing && (retcode != ODBC32.RetCode.NO_DATA) && (ODBC32.RetCode.SUCCESS != retcode)) { // allow for building comulative error messages. if (null == errors) { firstRetCode = retcode; errors = new OdbcErrorCollection(); } ODBC32.GetDiagErrors(errors, null, StatementHandle, retcode); ++loop; } if (!disposing && hasMoreResults) { loop = 0; cRowsAffected = GetRowCount(); // get rowcount of the current resultset (if any) CalculateRecordsAffected(cRowsAffected); // update recordsaffected if (!singleResult) { // update row- and columncount FieldCountNoThrow(out cColsAffected); hasColumns = (0 != cColsAffected); _isValidResult = hasColumns; } } } while ((!singleResult && hasMoreResults && !hasColumns) // repeat for results with no columns || ((ODBC32.RetCode.NO_DATA != retcode) && allresults && (loop < MaxConsecutiveFailure)) // or process all results until done || (singleResult && hasMoreResults)); // or for any result in singelResult mode if (MaxConsecutiveFailure <= loop) { Bid.Trace("<odbc.OdbcDataReader.NextResult|INFO> 2000 consecutive failed results"); } if(retcode == ODBC32.RetCode.NO_DATA) { this.dataCache = null; _noMoreResults = true; } if (null != errors) { Debug.Assert(!disposing, "errors while disposing"); errors.SetSource(Connection.Driver); OdbcException exception = OdbcException.CreateException(errors, firstRetCode); Connection.ConnectionIsAlive(exception); throw exception; } return (hasMoreResults); }
override public bool Read() { if (IsClosed) { throw ADP.DataReaderClosed("Read"); } if (IsCancelingCommand) { _isRead = false; return false; } // HasRows needs to call into Read so we don't want to read on the actual Read call if (_skipReadOnce){ _skipReadOnce = false; return _isRead; } if (_noMoreRows || _noMoreResults || IsCommandBehavior(CommandBehavior.SchemaOnly)) return false; if (!_isValidResult) { return false; } ODBC32.RetCode retcode; //SQLFetch is only valid to call for row returning queries //We get: [24000]Invalid cursor state. So we could either check the count //ahead of time (which is cached), or check on error and compare error states. //Note: SQLFetch is also invalid to be called on a prepared (schemaonly) statement //SqlFetch retcode = StatementHandle.Fetch(); switch(retcode) { case ODBC32.RetCode.SUCCESS_WITH_INFO: Connection.HandleErrorNoThrow(StatementHandle, retcode); _hasRows = HasRowsStatus.HasRows; _isRead = true; break; case ODBC32.RetCode.SUCCESS: _hasRows = HasRowsStatus.HasRows; _isRead = true; break; case ODBC32.RetCode.NO_DATA: _isRead = false; if (_hasRows == HasRowsStatus.DontKnow) { _hasRows = HasRowsStatus.HasNoRows; } break; default: Connection.HandleError(StatementHandle, retcode); break; } //Null out previous cached row values. this.dataCache.FlushValues(); // if CommandBehavior == SingleRow we set _noMoreResults to true so that following reads will fail if (IsCommandBehavior(CommandBehavior.SingleRow)) { _noMoreRows = true; // no more rows, set to -1 SetCurrentRowColumnInfo(-1, 0); } else { // move to the next row SetCurrentRowColumnInfo(_row + 1, 0); } return _isRead; }
private void Close(bool disposing) { Exception exception = null; CMDWrapper wrapper = this._cmdWrapper; if ((wrapper != null) && (wrapper.StatementHandle != null)) { if (this.IsNonCancelingCommand) { this.NextResult(disposing, !disposing); if (this.command != null) { if (this.command.HasParameters) { this.command.Parameters.GetOutputValues(this._cmdWrapper); } wrapper.FreeStatementHandle(ODBC32.STMT.CLOSE); this.command.CloseFromDataReader(); } } wrapper.FreeKeyInfoStatementHandle(ODBC32.STMT.CLOSE); } if (this.command != null) { this.command.CloseFromDataReader(); if (this.IsCommandBehavior(CommandBehavior.CloseConnection)) { this.command.Parameters.RebindCollection = true; this.Connection.Close(); } } else if (wrapper != null) { wrapper.Dispose(); } this.command = null; this._isClosed = true; this.dataCache = null; this.metadata = null; this.schemaTable = null; this._isRead = false; this._hasRows = HasRowsStatus.DontKnow; this._isValidResult = false; this._noMoreResults = true; this._noMoreRows = true; this._fieldNameLookup = null; this.SetCurrentRowColumnInfo(-1, 0); if ((exception != null) && !disposing) { throw exception; } this._cmdWrapper = null; }
public override bool Read() { if (this.IsClosed) { throw ADP.DataReaderClosed("Read"); } if (this.IsCancelingCommand) { this._isRead = false; return false; } if (this._skipReadOnce) { this._skipReadOnce = false; return this._isRead; } if ((this._noMoreRows || this._noMoreResults) || this.IsCommandBehavior(CommandBehavior.SchemaOnly)) { return false; } if (!this._isValidResult) { return false; } ODBC32.RetCode retcode = this.StatementHandle.Fetch(); switch (retcode) { case ODBC32.RetCode.SUCCESS: this._hasRows = HasRowsStatus.HasRows; this._isRead = true; break; case ODBC32.RetCode.SUCCESS_WITH_INFO: this.Connection.HandleErrorNoThrow(this.StatementHandle, retcode); this._hasRows = HasRowsStatus.HasRows; this._isRead = true; break; case ODBC32.RetCode.NO_DATA: this._isRead = false; if (this._hasRows == HasRowsStatus.DontKnow) { this._hasRows = HasRowsStatus.HasNoRows; } break; default: this.Connection.HandleError(this.StatementHandle, retcode); break; } this.dataCache.FlushValues(); if (this.IsCommandBehavior(CommandBehavior.SingleRow)) { this._noMoreRows = true; this.SetCurrentRowColumnInfo(-1, 0); } else { this.SetCurrentRowColumnInfo(this._row + 1, 0); } return this._isRead; }
private bool NextResult(bool disposing, bool allresults) { ODBC32.RetCode code; bool flag; ODBC32.RetCode sUCCESS = ODBC32.RetCode.SUCCESS; bool flag3 = false; bool flag2 = this.IsCommandBehavior(CommandBehavior.SingleResult); if (this.IsClosed) { throw ADP.DataReaderClosed("NextResult"); } this._fieldNameLookup = null; if (this.IsCancelingCommand || this._noMoreResults) { return false; } this._isRead = false; this._hasRows = HasRowsStatus.DontKnow; this._fieldNameLookup = null; this.metadata = null; this.schemaTable = null; int num = 0; OdbcErrorCollection errors = null; do { this._isValidResult = false; code = this.StatementHandle.MoreResults(); flag = (code == ODBC32.RetCode.SUCCESS) || (code == ODBC32.RetCode.SUCCESS_WITH_INFO); if (code == ODBC32.RetCode.SUCCESS_WITH_INFO) { this.Connection.HandleErrorNoThrow(this.StatementHandle, code); } else if ((!disposing && (code != ODBC32.RetCode.NO_DATA)) && (code != ODBC32.RetCode.SUCCESS)) { if (errors == null) { sUCCESS = code; errors = new OdbcErrorCollection(); } ODBC32.GetDiagErrors(errors, null, this.StatementHandle, code); num++; } if (!disposing && flag) { num = 0; SQLLEN rowCount = this.GetRowCount(); this.CalculateRecordsAffected((int) rowCount); if (!flag2) { short num2; this.FieldCountNoThrow(out num2); flag3 = 0 != num2; this._isValidResult = flag3; } } } while ((((!flag2 && flag) && !flag3) || (((ODBC32.RetCode.NO_DATA != code) && allresults) && (num < 0x7d0))) || (flag2 && flag)); if (0x7d0 <= num) { Bid.Trace("<odbc.OdbcDataReader.NextResult|INFO> 2000 consecutive failed results"); } if (code == ODBC32.RetCode.NO_DATA) { this.dataCache = null; this._noMoreResults = true; } if (errors != null) { errors.SetSource(this.Connection.Driver); OdbcException innerException = OdbcException.CreateException(errors, sUCCESS); this.Connection.ConnectionIsAlive(innerException); throw innerException; } return flag; }
private void Close(bool disposing) { Exception error = null; CMDWrapper wrapper = _cmdWrapper; if (null != wrapper && wrapper.StatementHandle != null) { // disposing // true to release both managed and unmanaged resources; false to release only unmanaged resources. // if (IsNonCancelingCommand) { //Read any remaining results off the wire // some batch statements may not be executed until SQLMoreResults is called. // We want the user to be able to do ExecuteNonQuery or ExecuteReader // and close without having iterate to get params or batch. // NextResult(disposing, !disposing); // false,true or true,false if (null != command) { if (command.HasParameters) { // Output Parameters are not guareenteed to be returned until all the data // from any restssets are read, so we do this after the above NextResult call(s) command.Parameters.GetOutputValues(_cmdWrapper); } wrapper.FreeStatementHandle(ODBC32.STMT.CLOSE); command.CloseFromDataReader(); } } wrapper.FreeKeyInfoStatementHandle(ODBC32.STMT.CLOSE); } // if the command is still around we call CloseFromDataReader, // otherwise we need to dismiss the statement handle ourselves // if (null != command) { command.CloseFromDataReader(); if(IsCommandBehavior(CommandBehavior.CloseConnection)) { Debug.Assert(null != Connection, "null cmd connection"); command.Parameters.RebindCollection = true; Connection.Close(); } } else if (null != wrapper) { wrapper.Dispose(); } this.command = null; _isClosed=true; this.dataCache = null; this.metadata = null; this.schemaTable = null; _isRead = false; _hasRows = HasRowsStatus.DontKnow; _isValidResult = false; _noMoreResults = true; _noMoreRows = true; _fieldNameLookup = null; SetCurrentRowColumnInfo(-1, 0); if ((null != error) && !disposing) { throw error; } _cmdWrapper = null; }