文件首頁
MySQL 9.0 參考手冊
相關文件 下載本手冊
PDF (美式 Letter) - 40.0Mb
PDF (A4) - 40.1Mb
Man Pages (TGZ) - 258.2Kb
Man Pages (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 9.0 參考手冊  /  ...  /  處理資料和中繼資料

27.3.7.3 處理資料和中繼資料

結果集

此處顯示的函數 print_result() 接受結果集 (SqlResult) 作為輸入

function print_result(result) {
  if (result.hasData()) {
    console.log(result.getColumnNames())
    console.log(result.getColumns())

    let row = result.fetchOne()

    while(row) {
      console.log(row.toArray())
      row = result.fetchOne()
    }
  } 
  else {
    console.log("Number of affected rows: " + result.getAffectedItemsCount())
    console.log("Last insert ID: " + result.getAutoIncrementValue())
  }

  while(result.nextResult()) {
    console.log("\nNext result set")
    print_result(result)
  }
}

如果 query 是有效 SQL 陳述式的文字,則可以在 JavaScript 儲存程序的內文中像這樣呼叫函數

let stmt = session.sql(query);
let res = stmt.execute();

print_result(res);

print_result() 將其輸出列印到 stdout。這包括結果集中資料行的名稱。如果結果集不是空的,則會依取得的順序列印每列的內容;否則,函數會取得陳述式影響的列數和最後插入的 ID 值。最後,它會使用 nextResult() 檢查多個結果集,並在有下一個結果集時呼叫自身。

中繼資料

本節示範如何取得資料行中繼資料。

CREATE PROCEDURE jssp_simple_meta(IN query VARCHAR(250))
LANGUAGE JAVASCRIPT AS $$

  let stmt = session.sql(query)
  let result = stmt.execute()

  console.log(result.getColumnNames())

  let cols = result.getColumns()
  let cnt = result.getColumnCount()

  var out = 'COLUMN INFO:'

  for (var i=0; i<cnt; i++) {
    let col = cols[i]

    out += "\nColumn: " + col.getColumnName() + "(" + col.getColumnLabel() + ")"
    out += "; Schema: " + col.getSchemaName()
    out += "; Table: " + col.getTableName() + "(" + col.getTableLabel() + ")"
    out += "; Type: " + col.getType();
  }

  out += "\n"

  console.log(out);

  if (result.hasData()) {
    console.log("ROWS:")
    let row = result.fetchOne()
  
    while(row) {
      console.log(row.toArray())
      row = result.fetchOne()
    }
  }

$$;

輸出

mysql> SELECT mle_session_reset(); 
+------------------------------------------+
| mle_session_reset()                      |
+------------------------------------------+
| The session state is successfully reset. |
+------------------------------------------+
1 row in set (0.01 sec)

mysql> CALL jssp_simple_meta("
    ">   SELECT c.Name, c.LocalName, t.Name AS Capital, c.Population
    ">   FROM country c 
    ">   JOIN countrylanguage l 
    ">   ON c.Code=l.CountryCode 
    ">   JOIN city t 
    ">   ON c.Capital=t.ID
    ">   WHERE l.Language='Swedish'
    "> ");
Query OK, 0 rows affected (0.01 sec)

mysql> SELECT mle_session_state('stdout')\G
*************************** 1. row ***************************
mle_session_state('stdout'): Name,LocalName,Capital,Population
COLUMN INFO:
Column: Name(Name); Schema: world; Table: country(c); Type: STRING
Column: LocalName(LocalName); Schema: world; Table: country(c); Type: STRING
Column: Name(Capital); Schema: world; Table: city(t); Type: STRING
Column: Population(Population); Schema: world; Table: country(c); Type: INT

ROWS:
Denmark,Danmark,København,5330000
Finland,Suomi,Helsinki [Helsingfors],5171300
Norway,Norge,Oslo,4478500
Sweden,Sverige,Stockholm,8861400

1 row in set (0.00 sec)
錯誤處理

本節描述使用 SQL API 時,MySQL JavaScript 儲存程式中的基本錯誤處理。

在陳述式準備或執行期間遇到的 SQL 錯誤會以例外狀況的形式在 JavaScript 中擲回,可以使用一個或多個 try ... catch 區塊來處理,在這種情況下,執行會繼續。如果未以此方式處理錯誤,則儲存程序執行會停止,並產生在 JavaScript 內部執行 SQL 查詢期間遇到的原始 SQL 錯誤。

在執行 JavaScript 儲存程序後執行 SHOW WARNINGS,會傳回程序內最近執行的陳述式產生的錯誤或警告。

有些錯誤無法在 JavaScript 中處理。例如,如果查詢中止 (CTRL-C),則儲存程式會立即停止執行並產生錯誤。同樣地,記憶體不足的錯誤無法在 JavaScript 常式中處理。

導致錯誤的 SQL 陳述式如果未在儲存程式中處理,則會將錯誤傳回給用戶端。為了觀察這一點,我們使用下列 SQL 陳述式建立儲存程序

CREATE PROCEDURE jssp_simple_error(IN query VARCHAR(250))
LANGUAGE JAVASCRIPT AS $$
 let session = mysql.getSession()
 var result1 = session.sql("SELECT * FROM t_unknown;").execute()
$$;

現在,我們呼叫 jssp_simple_error(),並將針對已知不存在的表格的查詢傳遞給它,像這樣

mysql> CALL jssp_simple_error("SELECT * FROM bogus");
ERROR 1146 (42S02): Table 'test.t_unknown' doesn't exist

您可以選擇改用 try-catch 語法在 JavaScript 中處理 SQL 錯誤,像這樣

CREATE PROCEDURE jssp_catch_errors(IN query VARCHAR(200))
LANGUAGE JAVASCRIPT AS $$
 try {
  var result = session.sql("SELECT * FROM bogus").execute()
 } catch (e) {
  console.error("\nJS Error:\n" + e.name + ":\n" + e.message)
 }
$$;

在這裡,您可以看到當傳遞給 jssp_catch_errors() 的查詢嘗試存取不存在的表格時的結果

mysql> CALL jssp_catch_errors("SELECT * FROM bogus");
Query OK, 0 rows affected (0.01 sec)

mysql> SELECT mle_session_state('stderr')\G
*************************** 1. row ***************************
mle_session_state('stderr'): 
JS Error: 
org.graalvm.polyglot.nativeapi.PolyglotNativeAPI$CallbackException: 
SQL-CALLOUT: Error code: 1146 Error state: 42S02 Error message: Table 'test.bogus' doesn't exist 

1 row in set (0.00 sec)