Obtener una cadena de consulta SQL sin formato a partir de declaraciones preparadas por PDO
¿Hay alguna manera de ejecutar la cadena SQL sin formato al llamar a PDOStatement::execute() en una declaración preparada? Para fines de depuración, esto sería extremadamente útil.
Supongo que quiere decir que desea la consulta SQL final, con los valores de los parámetros interpolados en ella. Entiendo que esto sería útil para la depuración, pero no es la forma en que funcionan las declaraciones preparadas. Los parámetros no se combinan con una declaración preparada en el lado del cliente, por lo que PDO nunca debería tener acceso a la cadena de consulta combinada con sus parámetros.
La declaración SQL se envía al servidor de la base de datos cuando prepara () y los parámetros se envían por separado cuando ejecuta (). El registro de consultas generales de MySQL muestra el SQL final con valores interpolados después de ejecutar(). A continuación se muestra un extracto de mi registro de consultas generales. Ejecuté las consultas desde la CLI de mysql, no desde PDO, pero el principio es el mismo.
081016 16:51:28 2 Query prepare s1 from 'select * from foo where i = ?'
2 Prepare [2] select * from foo where i = ?
081016 16:51:39 2 Query set @a =1
081016 16:51:47 2 Query execute s1 using @a
2 Execute [2] select * from foo where i = 1
También puede obtener lo que desea si configura el atributo PDO PDO::ATTR_EMULATE_PREPARES. En este modo, PDO interpola parámetros en la consulta SQL y envía la consulta completa cuando ejecuta(). Esta no es una verdadera consulta preparada. Evitará los beneficios de las consultas preparadas interpolando variables en la cadena SQL antes de ejecutar().
Re comentario de @afilina:
No, la consulta SQL textual no se combina con los parámetros durante la ejecución. Así que PDO no tiene nada que mostrarle.
Internamente, si usa PDO::ATTR_EMULATE_PREPARES, PDO hace una copia de la consulta SQL e interpola los valores de los parámetros en ella antes de preparar y ejecutar. Pero PDO no expone esta consulta SQL modificada.
El objeto PDOStatement tiene una propiedad $queryString, pero se establece solo en el constructor de PDOStatement y no se actualiza cuando la consulta se reescribe con parámetros.
Sería una solicitud de función razonable para PDO pedirles que expongan la consulta reescrita. Pero incluso eso no le daría la consulta "completa" a menos que use PDO::ATTR_EMULATE_PREPARES.
Es por eso que muestro la solución anterior de usar el registro de consultas generales del servidor MySQL, porque en este caso incluso una consulta preparada con marcadores de posición de parámetros se reescribe en el servidor, con los valores de los parámetros rellenados en la cadena de consulta. Pero esto sólo se hace durante el registro, no durante la ejecución de la consulta.
/**
* Replaces any parameter placeholders in a query with the value of that
* parameter. Useful for debugging. Assumes anonymous parameters from
* $params are are in the same order as specified in $query
*
* @param string $query The sql query with parameter placeholders
* @param array $params The array of substitution parameters
* @return string The interpolated query
*/
public static function interpolateQuery($query, $params) {
$keys = array();
# build a regular expression for each parameter
foreach ($params as $key => $value) {
if (is_string($key)) {
$keys[] = '/:'.$key.'/';
} else {
$keys[] = '/[?]/';
}
}
$query = preg_replace($keys, $params, $query, 1, $count);
#trigger_error('replaced '.$count.' keys');
return $query;
}