When you execute an SQL operation on a Session using the
sql()
method, an SqlResult
is returned. Iterating over 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. An 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 for
SqlResult
. An SqlResult
instance exports methods for accessing data and to retrieving the
last inserted ID or number of affected rows.
Use the hasData()
method to learn whether an
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 an 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
if, for example, fetchOne()
returns
NULL
or fetchAll()
returns
an empty list. And if multiple result sets are returned, any of
the result sets may be empty too. 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 hasData()
indicates that an 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 an 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 there is 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.