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 操作傳回的結果不同之處在於結果集和資料集的表示方式。SqlResultINSERT 等產生的結果集和 SELECT 等產生的資料集合併為一個。與 CRUD 操作不同,SqlResult 的兩種型別之間沒有區別。SqlResult 執行個體會匯出用於存取資料以及擷取最後插入的 ID 或受影響的列數的方法。

使用 hasData() 方法可了解 SqLResult 是資料集還是結果。當程式碼必須在不知道 SqlResult 的來源的情況下撰寫時,此方法非常有用。例如,在撰寫通用應用程式函式以列印查詢結果或處理預存程序結果時,可能會發生這種情況。如果 hasData() 傳回 true,則 SqlResult 的來源是 SELECT 或類似的命令,可以傳回列。

傳回值為 true 並不表示資料集是否包含任何列。如果 fetchOne() 傳回 NULLfetchAll() 傳回空清單,則資料集可能為空。如果傳回多個結果集,則任何結果集也可能為空。下列範例假設程序 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.')

hasData() 指出 SqlResult 不是資料集時,呼叫 fetchOne()fetchAll() 會產生錯誤。

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

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