9.5 使用 SQL 結果集

當您使用 sql() 方法在 Session 上執行 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 操作傳回的結果不同,在於表示結果集和資料集的方式。SqlResultINSERT 等產生的結果集,與 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();
}

查詢執行後,不會立即知道結果集的數量。查詢結果可以串流到用戶端,或在用戶端緩衝。在串流或部分緩衝模式下,用戶端無法判斷查詢是否發出多個結果集。