MySQL 9.0 版本資訊
預處理語句 API 允許重新執行支援的 SQL 語句(請參閱 預處理語句中允許的 SQL 語法),而無需每次都產生剖析和最佳化的成本。
預處理語句支援參數化。問號或問號符號 (?
) 用作參數標記;每次執行語句時,都會預先更新(繫結至值)參數,使用 PreparedStatement.bind()
。如需更多資訊,請參閱此方法的描述。
若要釋放剖析的查詢和語句參數所佔用的資源,請呼叫 PreparedStatement.deallocate()
,這會關閉預處理語句並釋放其資源。省略取消配置並不會產生錯誤,但儲存程序執行期間所消耗的記憶體,在常式執行完成之前不會釋放。一旦預處理語句關閉(取消配置),便不再可供執行。
預處理語句的執行流程包含下列步驟
準備語句 (
prepare()
)更新參數 (
bind()
)執行語句 (
execute()
)關閉語句 (
deallocate()
)
在關閉預處理語句之前,可以重複步驟 2 和 3 任意次數。
這裡顯示的 JavaScript 儲存程序 jssp_prep1()
接受包含兩個參數標記的任意 SQL 語句,準備語句,然後執行兩次,每次都將不同的值繫結至參數,並將結果列印到 stdout
CREATE PROCEDURE jssp_prep1(IN query VARCHAR(200))
LANGUAGE JAVASCRIPT AS $$
function print_result(result) {
console.log(result.getColumnNames())
let row = result.fetchOne()
while(row) {
console.log(row.toArray())
row = result.fetchOne()
}
}
function fetch_warnings(result) {
console.log("Number of warnings: " + result.getWarningsCount())
for (var w in result.getWarnings()) {
console.log(w.level + ", " + w.code + ", " + w.message)
}
}
let stmt = session.prepare(query)
stmt.bind(3, 4)
let res1 = stmt.execute()
print_result(res1)
fetch_warnings(res1)
stmt.bind(2, 3)
let res2 = stmt.execute()
print_result(res2)
fetch_warnings(res2)
stmt.bind(5)
let res3 = stmt.execute()
print_result(res3)
fetch_warnings(res3)
stmt.deallocate()
$$;
完成預處理語句後,我們會呼叫 deallocate()
來關閉它,釋放準備和執行它時所使用的任何資源。
在至少繫結一次所有參數之後,允許使用少於語句中參數數量的引數呼叫 bind()
。在這種情況下,在先前呼叫 stmt.bind(2,3)
之後呼叫 stmt.bind(5)
,與呼叫 stmt.bind(5,3)
相同—遺失的第二個值會重複使用先前的呼叫,如下所示
mysql> CALL jssp_prep1("
"> SELECT *
"> FROM t1
"> WHERE c1 = ? OR c1 = ?
"> ");
Query OK, 0 rows affected (0.03 sec)
mysql> SELECT mle_session_state("stdout")\G
*************************** 1. row ***************************
mle_session_state('stdout'): c1,c2,c3
3,37,peach
4,221,watermelon
Number of warnings: 0
c1,c2,c3
2,139,apple
3,37,peach
Number of warnings: 0
c1,c2,c3
3,37,peach
5,83,pear
Number of warnings: 0
1 row in set (0.00 sec)