9.5 使用 SQL 结果集

当您使用 sql() 方法对会话执行 SQL 操作时,会返回一个 SqlResult。迭代 SqlResult 与处理来自 CRUD 操作的结果相同。以下示例假设 users 表存在。

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');
}

SqlResult 与 CRUD 操作返回的结果的不同之处在于结果集和数据集的表示方式。 SqlResult 将例如由 INSERT 生成的结果集和例如由 SELECT 生成的结果集组合在一起。与 CRUD 操作不同,SqlResult 对这两种类型没有区别。 SqlResult 实例导出用于访问数据以及检索最后插入的 ID 或受影响行数的方法。

使用 hasData() 方法了解 SqLResult 是数据集还是结果。当要编写的代码不了解 SqlResult 的来源时,此方法很有用。例如,在编写用于打印查询结果的通用应用程序函数或处理存储过程结果时,可能会出现这种情况。如果 hasData() 返回 true,则 SqlResult 来自 SELECT 或类似的可以返回行的命令。

true 的返回值并不表示数据集中是否包含任何行。例如,如果 fetchOne() 返回 NULLfetchAll() 返回空列表,则数据集可能为空。如果返回多个结果集,则任何结果集也可能为空。以下示例假设过程 my_proc 存在。

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.');
}

hasData() 指示 SqlResult 不是数据集时,调用 fetchOne()fetchAll() 是错误的。

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());

调用存储过程可能导致必须处理多个结果集作为单个执行的一部分。作为查询执行的结果,将返回一个 SqlResult 对象,该对象封装了第一个结果集。处理完结果集后,您可以调用 nextResult() 前进到下一个结果(如果有)。前进到下一个结果集后,它将替换之前加载的结果,然后该结果将变为不可用。

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();
}

查询执行后不会立即知道结果集的数量。查询结果可以流式传输到客户端或缓存在客户端。在流式传输或部分缓冲模式下,客户端无法判断查询是否发出多个结果集。