Как я могу просмотреть содержание подготовленного заявления?


Я работаю над тем, чтобы научиться использовать подготовленные инструкции с mysqli в PHP, и обычно, если у меня возникают проблемы с запросом, я просто выводю его на экран, чтобы посмотреть, как он выглядит в качестве первого шага.

Как я могу сделать это с помощью подготовленного заявления?

Я хотел бы увидеть инструкцию SQL после замены переменных.

Author: Stomped, 2010-02-21

6 answers

Используя подготовленные инструкции:

  • Когда вы готовите инструкцию, она отправляется на сервер MySQL
  • Когда вы связываете переменные + выполняете инструкцию, только переменные отправляются на сервер MySQL
  • И оператор + связанные переменные выполняются на сервере MySQL - без повторного выполнения "подготовки" при каждом выполнении оператора (именно поэтому подготовленные операторы могут быть полезны для производительности, когда один и тот же оператор выполняется несколько раз раз)

На стороне PHP нет "построения" SQL-запроса, поэтому на самом деле нет способа получить этот запрос.

Это означает, что если вы хотите увидеть SQL-запрос, вы должны использовать, ну, SQL-запросы, а не подготовленные инструкции.

 18
Author: Pascal MARTIN, 2014-07-31 15:02:41
Для подготовленных инструкций, которые выполняются с помощью функций API mysql_stmt_prepare() и mysql_stmt_execute() C, сервер записывает строки подготовки и выполнения в общий журнал запросов, чтобы вы могли определить, когда подготовлены инструкции и выполненный.
[...] сервер записывает следующие строки в общий журнал запросов:
Подготовить [1] ВЫБРАТЬ?
Выполнить [1] ВЫБЕРИТЕ 3

Поэтому в целях отладки активируйте общий журнал и следите за этим файлом.

Редактировать: о, у вопроса есть тег [mysqli]... полностью упущенный из виду.
Если оператор вообще не выполняется, проверили ли вы (дважды/трижды), что по пути не произошло ошибок?

echo "<pre>Debug: start</pre>\n";

$mysqli = new mysqli('localhost', 'localonly', 'localonly', 'test');
if ($mysqli->connect_error) {
  die('Connect Error (' . $mysqli->connect_errno . ') ' . $mysqli->connect_error);
}

$result = $mysqli->query('CREATE TEMPORARY TABLE foo (id int auto_increment, x int, primary key(id))');
if ( false=== $result) { 
 die('error : '. $mysqli->error);
}

$stmt = $mysqli->prepare('INSERT INTO foo (x) VALUES (?)');
if ( false===$stmt ) {
  die ('prepare() failed: ' . $mysqli->error);
}

$result = $stmt->bind_param('i', $x);
if ( false===$result ) {
  die('bind_param() failed');
}

$x = 1;
$result = $stmt->execute();
if ( false===$result ) {
  die('execute() failed: '.$stmt->error);
}

echo "<pre>Debug: end</pre>\n";
 11
Author: VolkerK, 2010-02-21 18:54:24

Я обычно делаю это, когда мне нужно отладить подготовленный sql с параметрами.

Пример подготовки и выполнения:

$sql = "SELECT VAL1, VAL2 FROM TABLE(?, '?', '?', '?', '?', ?, '?', '?', '?')";
$prep = ibase_prepare( $sql ) or die("Error");
$query = ibase_execute($prep, $param1, $param2, .....) or $err = true;
                              ^^^^^^^^^^^^^^^^^^^^^^^

Простой способ отладки результирующего SQL предложения это:

printf( str_replace('?', '%s', $sql), $param1, $param2, ....);
                                      ^^^^^^^^^^^^^^^^^^^^^^

Вам нужно сделать только один printf, заменив? в подготовленной строке SQL на один %s. printf будет интерпретировать все как одну строку, принимая каждый параметр как размещающий его на каждом замененном %s.

 2
Author: NetVicious, 2018-02-26 09:10:25

Соглашаясь с Паскалем МАРТИНОМ (+1), поэтому я предлагаю другой метод отладки: var_dump() или регистрируйте каждую переменную, которую вы вставляете в инструкцию, таким образом, вы сможете выяснить, являются ли это неверными данными или логически неправильным SQL.

 0
Author: chelmertz, 2010-02-20 22:30:39

Я недавно обновил этот проект, включив интеграцию с композитором, модульное тестирование и улучшив обработку принятия аргументов по ссылке (для этого требуется обновление до php 5.6).


Я создал набор классов, которые расширяют классы по умолчанию mysqli и mysqli_stmt, чтобы вы могли просматривать представление потенциальной строки запроса, которая должна предоставить то, что вы ищете:

Https://github.com/noahheck/E_mysqli

Это (близкое к) падение замена для вас обычного объекта mysqli, который возвращает пользовательский объект mysqli_stmt, когда вы prepare() вводите строку запроса. После привязки ваших параметров E_mysqli позволит вам просмотреть результирующую строку запроса как новое свойство объекта stmt:

$mysqli = new E_mysqli($dbHost, $dbUser, $dbPass, $dbName);

$query = "INSERT INTO registration SET name = ?, email = ?";

$stmt = $mysqli->prepare($query);

$stmt->bind_param("ss", $_POST['name'], $_POST['email']);

$stmt->execute();

echo $stmt->fullQuery;

Приведет к:

INSERT INTO registration SET name = 'John Doe', email = '[email protected]'

Есть некоторые предостережения при использовании этого расширения (описано в разделе README в проекте github), но для устранения неполадок в проблемных областях вашего приложения или перехода к объектно-ориентированному стилю с процедурной точки зрения это должно обеспечить определенный уровень помощи для большинства пользователей.

Как я описал в проекте github, у меня нет никакого практического опыта использования расширения mysqli, и этот проект был создан по просьбе пользователей его дочернего проекта, поэтому любые отзывы, которые могут быть предоставлены разработчиками, использующими это в производстве, будут весьма признательны.

Отказ от ответственности - Как я уже сказал, я сделал это расширение.

 0
Author: myesain, 2016-12-03 15:48:46

Вы можете использовать такой инструмент, как Подсказка . Идея состоит в том, чтобы действовать как прокси-сервер MySQL. Он анализирует пакеты MySQL, извлекает запрос и его параметры, чтобы вы могли видеть подготовленные инструкции с его содержимым.

 0
Author: Orderbynull, 2017-07-09 11:22:04