9.5 Работа с наборами результатов SQL
При выполнении SQL-операции на сессии с использованием метода sql() возвращается объект SqlResult. Перебор элементов объекта SqlResult идентичен работе с результатами операций CRUD. Следующий пример предполагает, что таблица users существует.
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 отличается от результатов, возвращаемых операциями CRUD, способом представления наборов результатов и наборов данных. Объект SqlResult объединяет набор результатов, полученный, например, , и набор данных, полученный, например, в один. В отличие от операций CRUD, нет различия между этими типами для SqlResult. Экземпляр SqlResult экспортирует методы для доступа к данным и получения последнего вставленного ID или количества затронутых строк.
Используйте метод hasData(), чтобы узнать, является ли SqLResult набором данных или набором результатов. Этот метод полезен, когда код не знает происхождение SqlResult. Это может быть случай при написании универсальной функции приложения для вывода результатов запроса или при обработке результатов хранимых процедур. Если hasData() возвращает true, то SqlResult происходит из команды или подобной, которая может возвращать строки.
Возвращаемое значение true не указывает, содержит ли набор данных какие-либо строки. Набор данных может быть пустым, если, например, fetchOne() возвращает NULL или fetchAll() возвращает пустой список. И если возвращается несколько наборов результатов, любой из них может быть пустым тоже. Следующий пример предполагает, что хранимая процедура my_proc существует.
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.')
Вызов метода fetchOne() или fetchAll() является ошибкой, когда hasData() указывает, что SqlResult не является набором данных.
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())
Вызов хранимой процедуры может привести к необходимости обработки нескольких наборов результатов в рамках одного выполнения. В результате выполнения запроса возвращается объект SqlResult, который содержит первый набор результатов. После обработки набора результатов можно вызвать nextResult(), чтобы перейти к следующему результату, если он есть. После перехода к следующему набору результатов, он заменяет ранее загруженный результат, который становится недоступным.
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()
Количество наборов результатов не известно сразу после выполнения запроса. Результаты запроса могут передаваться клиенту потоком или буферизоваться на клиенте. В режиме потоковой передачи или частичного буферизации клиент не может определить, отправляет ли запрос более одного набора результатов.
© 2025 Oracle
Licensed under the GPLv2 License.