Spec-Zone.ru › MySQL 9.2

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(5) после предыдущего вызова stmt.bind(2,3) эквивалентен вызову 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)

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-9.2-en/srjs-api-prepared-statements.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API