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;
 }
Exemple #6
-1
        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;
        }