9.5 Работа с наборами результатов SQL
При выполнении операции SQL на сессии с помощью метода sql() возвращается объект SqlResult. Итерация по объекту SqlResult идентична работе с результатами операций CRUD. Следующий пример предполагает, что таблица пользователей существует.
Код JavaScript MySQL Shell
var res = mySession.sql('SELECT name, age FROM users').execute();
var row;
while (row = res.fetchOne()) {
print('Name: ' + row['name'] + '\n');
print(' Age: ' + row.age + '\n');
}
Код Python MySQL Shell
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()
Код JavaScript Node.js
mySession.sql('SELECT name, age FROM users')
.execute()
.then(res => {
while (row = res.fetchOne()) {
console.log('Name: ' + row[0] + '\n');
console.log(' Age: ' + row[1] + '\n');
}
});
В качестве альтернативы можно использовать обратные вызовы:
mySession.sql('SELECT name, age FROM users')
.execute(function (row) {
console.log('Name: ' + row[0] + '\n');
console.log(' Age: ' + row[1] + '\n');
});Код C#
var res = Session.SQL("SELECT name, age FROM users").Execute();
while (res.Next())
{
Console.WriteLine("Name: " + res.Current["name"]);
Console.WriteLine("Age: " + res.Current["age"]);
}
Код Python
# Connector/Python
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()
Код Java
SqlResult res = mySession.sql("SELECT name, age FROM users").execute();
Row row;
while ((row = res.fetchOne()) != null) {
System.out.println(" Name: " + row.getString("name") + "\n");
System.out.println(" Age: " + row.getInt("age") + "\n");
}
Код C++
SqlResult res = mysession.sql("SELECT name, age FROM users").execute();
Row row;
while ((row = res.fetchOne())) {
cout << "Name: " << row[0] << endl;
cout << " Age: " << row[1] << endl;
}
Объект SqlResult отличается от результатов, возвращаемых операциями CRUD, способом представления наборов результатов и наборов данных. Объект SqlResult объединяет набор результатов, полученный, например, из запроса, и набор данных, полученный, например, из оператора INSERT. В отличие от операций CRUD, для объектов SqlResult нет различия между этими двумя типами. Экземпляр SqlResult экспортирует методы для доступа к данным и извлечения последнего вставленного ID или количества затронутых строк.
Используйте метод hasData(), чтобы узнать, является ли объект SqLResult набором данных или результатом. Этот метод полезен, когда код не знает происхождение объекта SqlResult. Это может быть случай при написании универсальной функции приложения для вывода результатов запроса или при обработке результатов хранимой процедуры. Если метод hasData() возвращает true, то объект SqlResult происходит из запроса или аналогичной команды, которая может возвращать строки.
Возвращаемое значение true не указывает, содержит ли набор данных какие-либо строки. Набор данных может быть пустым, если, например, fetchOne() возвращает NULL или fetchAll() возвращает пустой список. И если возвращается несколько наборов результатов, любой из них может быть пустым тоже. Следующий пример предполагает, что процедура my_proc существует.
Код JavaScript MySQL Shell
var res = mySession.sql('CALL my_proc()').execute();
if (res.hasData()){
var row = res.fetchOne();
if (row){
print('List of rows available for fetching.');
do {
print(row);
} while (row = res.fetchOne());
}
else{
print('Empty list of rows.');
}
}
else {
print('No row result.');
}
Код Python MySQL Shell
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.')
Код JavaScript Node.js
mySession.sql('CALL my_proc()')
.execute()
.then(function (res) {
if (!res.hasData()) {
return console.log('No row result.');
}
var row = res.fetchOne();
if (!row) {
return console.log('Empty list of rows.');
}
console.log('List of rows available for fetching.');
do {
console.log(row);
} while (row = res.fetchOne());
})
Код C#
var res = Session.SQL("CALL my_proc()").Execute();
if (res.HasData)
{
var row = res.FetchOne();
if (row != null)
{
Console.WriteLine("List of rows available for fetching.");
do
{
PrintResult(row);
} while ((row = res.FetchOne()) != null);
}
else
{
Console.WriteLine("Empty list of rows.");
}
}
else
{
Console.WriteLine("No row result.");
}
Код Python
# Connector/Python
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.')
Код Java
SqlResult res = mySession.sql("CALL my_proc()").execute();
if (res.hasData()){
Row row = res.fetchOne();
if (row != null){
System.out.println("List of rows available for fetching.");
do {
for (int c = 0; c < res.getColumnCount(); c++) {
System.out.println(row.getString(c));
}
} while ((row = res.fetchOne()) != null);
}
else{
System.out.println("Empty list of rows.");
}
}
else {
System.out.println("No row result.");
}
Код C++
SqlResult res = mysession.sql("CALL my_proc()").execute();
if (res.hasData())
{
Row row = res.fetchOne();
if (row)
{
cout << "List of rows available for fetching." << endl;
do {
cout << "next row: ";
for (unsigned i=0 ; i < row.colCount(); ++i)
cout << row[i] << ", ";
cout << endl;
} while ((row = res.fetchOne()));
}
else
{
cout << "Empty list of rows." << endl;
}
}
else
{
cout << "No row result." << endl;
}
Вызов метода fetchOne() или fetchAll() является ошибкой, если hasData() указывает, что объект SqlResult не является набором данных.
Код JavaScript MySQL Shell
function print_result(res) {
if (res.hasData()) {
// SELECT
var columns = res.getColumns();
var record = res.fetchOne();
while (record){
for (index in columns){
print (columns[index].getColumnName() + ": " + record[index] + "\n");
}
// Get the next record
record = res.fetchOne();
}
} else {
// INSERT, UPDATE, DELETE, ...
print('Rows affected: ' + res.getAffectedItemsCount());
}
}
print_result(mySession.sql('DELETE FROM users WHERE age < 30').execute());
print_result(mySession.sql('SELECT * FROM users WHERE age = 40').execute());
Код Python MySQL Shell
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())
Код JavaScript Node.js
function print_result(res) {
if (res.hasData()) {
// SELECT
var columns = res.getColumns();
var record = res.fetchOne();
while (record) {
for (index in columns) {
console.log(columns[index].getColumnName() + ": " + record[index]);
}
// Get the next record
record = res.fetchOne();
}
} else {
// INSERT, UPDATE, DELETE, ...
console.log('Rows affected: ' + res.getAffectedItemsCount());
}
}
mySession.sql(`DELETE FROM users WHERE age < 30`)
.execute()
.then(function (res) {
print_result(res);
});
mySession.sql(`SELECT * FROM users WHERE age = 40`)
.execute()
.then(function (res) {
print_result(res);
});
Код C#
private void print_result(SqlResult res)
{
if (res.HasData)
{
// SELECT
}
else
{
// INSERT, UPDATE, DELETE, ...
Console.WriteLine("Rows affected: " + res.RecordsAffected);
}
}
print_result(Session.SQL("DELETE FROM users WHERE age < 30").Execute());
print_result(Session.SQL("SELECT COUNT(*) AS forty FROM users WHERE age = 40").Execute());
Код Python
# Connector/Python
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())
Код Java
private void print_result(SqlResult res) {
if (res.hasData()) {
// SELECT
Row row;
while ((row = res.fetchOne()) != null){
for (int c = 0; c < res.getColumnCount(); c++) {
System.out.println(row.getString(c));
}
}
} else {
// INSERT, UPDATE, DELETE, ...
System.out.println("Rows affected: " + res.getAffectedItemsCount());
}
}
print_result(mySession.sql("DELETE FROM users WHERE age < 30").execute());
print_result(mySession.sql("SELECT COUNT(*) AS forty FROM users WHERE age = 40").execute());
Код C++
void print_result(SqlResult &&_res)
{
// Note: We need to store the result somewhere to be able to process it.
SqlResult res(std::move(_res));
if (res.hasData())
{
// SELECT
const Columns &columns = res.getColumns();
Row record = res.fetchOne();
while (record)
{
for (unsigned index=0; index < res.getColumnCount(); ++index)
{
cout << columns[index].getColumnName() << ": "
<< record[index] << endl;
}
// Get the next record
record = res.fetchOne();
}
}
else
{
// INSERT, UPDATE, DELETE, ...
// Note: getAffectedItemsCount() not yet implemented in Connector/C++.
cout << "No rows in the result" << endl;
}
}
print_result(mysession.sql("DELETE FROM users WHERE age < 30").execute());
print_result(mysession.sql("SELECT * FROM users WHERE age = 40").execute());
Вызов хранимой процедуры может потребовать работы с несколькими наборами результатов в рамках одного выполнения. В результате выполнения запроса возвращается объект SqlResult, который содержит первый набор результатов. После обработки набора результатов можно вызвать nextResult(), чтобы перейти к следующему результату, если он есть. После перехода к следующему набору результатов он заменяет ранее загруженный набор, который затем становится недоступным.
Код JavaScript MySQL Shell
function print_result(res) {
if (res.hasData()) {
// SELECT
var columns = res.getColumns();
var record = res.fetchOne();
while (record){
for (index in columns){
print (columns[index].getColumnName() + ": " + record[index] + "\n");
}
// Get the next record
record = res.fetchOne();
}
} else {
// INSERT, UPDATE, DELETE, ...
print('Rows affected: ' + res.getAffectedItemsCount());
}
}
var res = mySession.sql('CALL my_proc()').execute();
// Prints each returned result
var more = true;
while (more){
print_result(res);
more = res.nextResult();
}
Код Python MySQL Shell
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()
Код JavaScript Node.js
function print_result(res) {
if (res.hasData()) {
// SELECT
var columns = res.getColumns();
var record = res.fetchOne();
while (record) {
for (index in columns) {
console.log(columns[index].getColumnName() + ": " + record[index]);
}
// Get the next record
record = res.fetchOne();
}
} else {
// INSERT, UPDATE, DELETE, ...
console.log('Rows affected: ' + res.getAffectedItemsCount());
}
}
mySession.sql('CALL my_proc()')
.execute()
.then(function (res) {
// Prints each returned result
var more = true;
while (more) {
print_result(res);
more = res.nextResult();
}
})
Код C#
var res = Session.SQL("CALL my_proc()").Execute();
if (res.HasData)
{
do
{
Console.WriteLine("New resultset");
while (res.Next())
{
Console.WriteLine(res.Current);
}
} while (res.NextResult());
}
Код Python
# Connector/Python
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()
Код Java
SqlResult res = mySession.sql("CALL my_proc()").execute();
Код C++
SqlResult res = mysession.sql("CALL my_proc()").execute();
while (true)
{
if (res.hasData())
{
cout << "List of rows in the resultset." << endl;
for (Row row; (row = res.fetchOne());)
{
cout << "next row: ";
for (unsigned i = 0; i < row.colCount(); ++i)
cout << row[i] << ", ";
cout << endl;
}
}
else
{
cout << "No rows in the resultset." << endl;
}
if (!res.nextResult())
break;
cout << "Next resultset." << endl;
}
При использовании Node.js отдельные строки могут быть возвращены немедленно с помощью обратного вызова, который должен быть передан методу execute(). Для идентификации отдельных наборов результатов можно указать второй обратный вызов, который вызывается для метаданных, обозначающих начало набора результатов.
Код JavaScript Node.js
var resultcount = 0;
var res = session
.sql('CALL my_proc()')
.execute(
function (row) {
console.log(row);
},
function (meta) {
console.log('Begin of result set number ', resultCount++);
});
Количество наборов результатов неизвестно сразу после выполнения запроса. Результаты запроса могут передаваться клиенту потоком или буферироваться на клиенте. В режиме потоковой передачи или частичного буферирования клиент не может определить, генерирует ли запрос более одного набора результатов.
© 2025 Oracle
Licensed under the GPLv2 License.