Пример #1
0
        /// <summary>
        /// Moves to the next resultset in multiple row-returning SQL command.
        /// </summary>
        /// <returns>True if the command was successful and a new resultset is available, False otherwise.</returns>
        public override bool NextResult()
        {
            CheckClosed();

            SQLiteStatement stmt = null;
            int             fieldCount;

            while (true)
            {
                if (_activeStatement != null && stmt == null)
                {
                    // Reset the previously-executed statement
                    _activeStatement._sql.Reset(_activeStatement);

                    // If we're only supposed to return a single rowset, step through all remaining statements once until
                    // they are all done and return false to indicate no more resultsets exist.
                    if ((_commandBehavior & CommandBehavior.SingleResult) != 0)
                    {
                        for (; ;)
                        {
                            stmt = _command.GetStatement(_activeStatementIndex + 1);
                            if (stmt == null)
                            {
                                break;
                            }
                            _activeStatementIndex++;

                            stmt._sql.Step(stmt);
                            if (stmt._sql.ColumnCount(stmt) == 0)
                            {
                                if (_rowsAffected == -1)
                                {
                                    _rowsAffected = 0;
                                }
                                _rowsAffected += stmt._sql.Changes;
                            }
                            stmt._sql.Reset(stmt); // Gotta reset after every step to release any locks and such!
                        }
                        return(false);
                    }
                }

                // Get the next statement to execute
                stmt = _command.GetStatement(_activeStatementIndex + 1);

                // If we've reached the end of the statements, return false, no more resultsets
                if (stmt == null)
                {
                    return(false);
                }

                // If we were on a current resultset, set the state to "done reading" for it
                if (_readingState < 1)
                {
                    _readingState = 1;
                }

                _activeStatementIndex++;

                fieldCount = stmt._sql.ColumnCount(stmt);

                // If the statement is not a select statement or we're not retrieving schema only, then perform the initial step
                if ((_commandBehavior & CommandBehavior.SchemaOnly) == 0 || fieldCount == 0)
                {
                    if (stmt._sql.Step(stmt))
                    {
                        _readingState = -1;
                    }
                    else if (fieldCount == 0) // No rows returned, if fieldCount is zero, skip to the next statement
                    {
                        if (_rowsAffected == -1)
                        {
                            _rowsAffected = 0;
                        }
                        _rowsAffected += stmt._sql.Changes;
                        stmt._sql.Reset(stmt);
                        continue; // Skip this command and move to the next, it was not a row-returning resultset
                    }
                    else // No rows, fieldCount is non-zero so stop here
                    {
                        _readingState = 1; // This command returned columns but no rows, so return true, but HasRows = false and Read() returns false
                    }
                }

                // Ahh, we found a row-returning resultset eligible to be returned!
                _activeStatement = stmt;
                _fieldCount      = fieldCount;
                _fieldTypeArray  = null;

                return(true);
            }
        }