文档主页
MySQL 9.0 参考手册
相关文档 下载本手册
PDF (美国信纸) - 40.0Mb
PDF (A4) - 40.1Mb
手册页 (TGZ) - 258.2Kb
手册页 (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


27.3.7.2 预处理语句

预处理语句 API 允许执行受支持的 SQL 语句(参见 预处理语句中允许的 SQL 语法),而无需每次都承担解析和优化的成本。

预处理语句支持参数化。问号或问号 (?) 用作参数标记;参数在之前更新(绑定到值),每次执行语句时,使用 PreparedStatement.bind()。有关更多信息,请参见此方法的描述。

要释放解析查询和语句参数占用的资源,请调用 PreparedStatement.deallocate(),它将关闭预处理语句并释放其资源。省略取消分配不会产生错误,但存储过程执行期间消耗的内存否则不会在例程执行完成之前释放。一旦预处理语句关闭(取消分配),它将不再可用以执行。

预处理语句的执行流程包括以下步骤

  1. 准备语句 (prepare())

  2. 更新参数 (bind())

  3. 执行语句 (execute())

  4. 关闭语句 (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)