Documentation Home
X DevAPI User Guide for MySQL Shell in Python Mode
Download this Manual
PDF (US Ltr) - 1.2Mb
PDF (A4) - 1.2Mb


9.5 Working with SQL Result Sets

When you execute an SQL operation on a Session using the sql() method an SqlResult is returned. Iterating an SqlResult is identical to working with results from CRUD operations. The following example assumes that the users table exists.

res = mySession.sql('SELECT name, age FROM users').execute()

row = res.fetch_one()

while row:
    print('Name: %s\n' % row[0])
    print(' Age: %s\n' % row.age)
    row = res.fetch_one()

SqlResult differs from results returned by CRUD operations in the way how result sets and data sets are represented. A SqlResult combines a result set produced by, for example, INSERT, and a data set, produced by, for example, SELECT in one. Unlike with CRUD operations there is no distinction between the two types. A SqlResult exports methods for data access and to retrieve the last inserted id or number of affected rows.

Use the hasData() method to learn whether a SqlResult is a data set or a result. The method is useful when code is to be written that has no knowledge about the origin of a SqlResult. This can be the case when writing a generic application function to print query results or when processing stored procedure results. If hasData() returns true, then the SqlResult origins from a SELECT or similar command that can return rows.

A return value of true does not indicate whether the data set contains any rows. The data set can be empty, for example it is empty if fetchOne() returns NULL or fetchAll() returns an empty list. The following example assumes that the procedure my_proc exists.

res = mySession.sql('CALL my_proc()').execute()

if res.has_data():

    row = res.fetch_one()
    if row:
        print('List of rows available for fetching.')
        while row:
            print(row)
            row = res.fetch_one()
    else:
        print('Empty list of rows.')
else:
    print('No row result.')

It is an error to call either fetchOne() or fetchAll() when hasResult() indicates that a SqlResult is not a data set.

def print_result(res):
  if res.has_data():
    # SELECT
    columns = res.get_columns()
    record = res.fetch_one()

    while record:
      index = 0

      for column in columns:
        print("%s: %s \n" % (column.get_column_name(), record[index]))
        index = index + 1

      # Get the next record
      record = res.fetch_one()
  else:
    #INSERT, UPDATE, DELETE, ...
    print('Rows affected: %s' % res.get_affected_items_count())

print_result(mySession.sql('DELETE FROM users WHERE age < 30').execute())
print_result(mySession.sql('SELECT * FROM users WHERE age = 40').execute())

Calling a stored procedure might result in having to deal with multiple result sets as part of a single execution. As a result for the query execution a SqlResult object is returned, which encapsulates the first result set. After processing the result set you can call nextResult() to move forward to the next result, if any. Once you advanced to the next result set, it replaces the previously loaded result which then becomes unavailable.

def print_result(res):
  if res.has_data():
    # SELECT
    columns = res.get_columns()
    record = res.fetch_one()

    while record:
      index = 0

      for column in columns:
        print("%s: %s \n" % (column.get_column_name(), record[index]))
        index = index + 1

      # Get the next record
      record = res.fetch_one()
  else:
    #INSERT, UPDATE, DELETE, ...
    print('Rows affected: %s' % res.get_affected_items_count())

res = mySession.sql('CALL my_proc()').execute()

# Prints each returned result
more = True
while more:
  print_result(res)
  more = res.next_result()

The number of result sets is not known immediately after the query execution. Query results can be streamed to the client or buffered at the client. In the streaming or partial buffering mode a client cannot tell whether a query emits more than one result set.