Cuando ejecuto una consulta en la base de datos MySQL el comando Execute congela completamente la base de datos, mientras que si el comando es Query corre normalmente la consulta. ¿Cuál es la diferente entre estos dos comandos?
-
si te ha servido alguna respuesta, te recomiendo que la marques como respuesta aceptada. – Dev 200 Jun 20 '17 at 17:06
3 Answers
Buenos dias, te responderé de manera general usando MySQLi y PDO, ya que no especificas el tipo de clase de consulta:
query()
Ejecuta una consulta estandarizada SQL a la base de datos, esto requiere escapar correctamente los datos para evitar inyecciones sql (vease: ¿Cómo evitar la inyección SQL en PHP?), generalmente se usa cuando obtendrás datos sin ninguna condición o característica, es decir sin usar WHERE
.
Ejemplo:
$sql = 'SELECT nombre, color, calorias FROM frutas ORDER BY nombre';
foreach ($conexion->query($sql) as $valor) {
echo $valor['nombre'] . "\t";
echo $valor['color'] . "\t";
echo $valor['calorias'] . "\n";
}
Como se aprecia en el ejemplo únicamente devolvemos datos directos, es decir, no buscamos usar WHERE
para condicionar los resultados, en el caso de querer hacerlo debemos asignar parámetros, para eso se usa el execute
, ya que este acompaña a las sentencias preparadas
(vease: http://php.net/manual/es/mysqli.quickstart.prepared-statements.php).
Otro problema del query()
, es que debes declarar la sentencia de nuevo para volver a usar la consulta.
Haciendo las consultas menos eficientes.
execute()
Corre o ejecuta una sentencia preparada
que permite asignar parámetros que evitan la inyección SQL ya que no debes recurrir a comillas o escapar caracteres, en el caso de que quieras ejecutar de nuevo la consulta a la base de datos, basta con ejecutar execute
de nuevo para hacerlo.
Esto requiere ademas que la sentencia se prepare
antes.
Ejemplo:
$consulta = $conexion->prepare('SELECT nombre, color, calorias FROM frutas
WHERE calorias < :calorias AND color = :color');
$consulta->bindValue(':calorias', $calorias);
$consulta->bindValue('color', $color);
$consulta->execute();
Donde:
$consulta->bindValue('calorias', $calorias) -> Asignar parametros
Le asignamos $calorias al parametro calorias , el cual corresponde al campo calorias de la tabla frutas.
Como observas en la sentencia SQL cuando igualamos calorias=:calorias, se presentan dos puntos, eso representa que :calorias es una cajita donde se metera luego el valor de la variable asignada.
Esto porque las sentencias preparadas primero mandan a MySQL la sentencia:
SELECT nombre, color, calorias FROM frutas
WHERE calorias < :calorias AND color = :color
Y luego le mandan los valores
:color, $color
Para que al darle execute ambas se combinen algo asi:
SELECT nombre, color, calorias FROM frutas
WHERE calorias < $calorias AND color=$color
Pero todo ocurre dentro del mismo MySQL, no en el PHP.
En conclusion:
query():
consultas simples sin condicionales (inseguro si no se sabe estructrar la consulta SQL).
execute():
consultas con parámetros pasados por asignación (mas seguras, si se emplea PDO o MySQLi permiten definir el tipo de dato que recibirán)
el comando Execute congela completamente la base de datos
Ahora, que hacemos con esto, necesitaria que publicaras la consulta para ver que error podria presentar.
Para saber mas sobre inyeccion sql y sentencias preparadas te invito a leer:
https://phpdelusions.net/sql_injection
https://phpdelusions.net/safemysql
https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php
- 5,246
- 5
- 39
- 80
Query ejecuta una instrucción SQL estándar y puede provocar Inyecciones SQL y otros problemas.
Execute ejecuta una instrucción preparada que le permite enlazar parámetros para evitar la necesidad de escapar o citar los parámetros. También funcionará mejor si está repitiendo una consulta varias veces.
$sth = $dbh->prepare('SELECT name, colour, calories FROM fruit
WHERE calories < :calories AND colour = :colour');
$sth->bindParam(':calories', $calories);
$sth->bindParam(':colour', $colour);
$sth->execute();
En resumen, Execute, de cierta forma es más seguro. Saludos.
- 2,249
- 10
- 21
Me gustaría aportar otras diferencias entre query
y execute
, tomando en cuenta las API PDO y MySQLi, que son actualmente las dos recomendadas por PHP para manejar los datos de forma segura. Ya que la extensión mysql_*
es insegura y por tanto obsoleta.
query
Realiza una consulta a la base de datos y la puedes usar sin peligro cuando en la misma no haya valores que sean obtenidos desde fuera.
Hay una pequeña diferencia con respecto a query
en cuanto los valores devueltos si usas PDO o MySQLi.
- Valores devueltos en PDO
PDO::query() devuelve un objeto PDOStatement, o
FALSE
en caso de error.
- Valores devueltos en MySQLi
mysqli::query Retorna
FALSE
en caso de error. Si una consulta del tipo SELECT, SHOW, DESCRIBE o EXPLAIN es exitosa,mysqli_query()
retornará un objeto mysqli_result. Para otras consultas exitosas demysqli_query()
retornará TRUE. O sea, no devuelve conjunto de resultados en todos los tipos de consultas.
execute
Prepara una sentencia SQL para su ejecución.
También hay diferencias si trabajas con PDO o con MySQLi:
- Usando PDO
PDO::exec() ejecuta una sentencia SQL en una única llamada a la función, devolviendo el número de filas afectadas por la sentencia.
PDO::exec() no devuelve resultados de una sentencia SELECT. Para una sentencia SELECT que sólo se necesita ejecutar una vez en el programa, se debe considerar el uso de PDO::query(). Para una sentencia que se deba ejecutar en múltiples ocasiones, preparar un objeto PDOStatement con PDO::prepare() y ejecutarlo con PDOStatement::execute().
valores devueltos
PDO::exec() devuelve el número de filas modificadas o borradas por la sentencia SQL ejecutada. Si no hay filas afectadas, PDO::exec() devuelve 0.
Nota importante:
Dado que execute se usa con consultas preparadas, es importante señalar lo siguiente:
PDO emulará sentencias preparadas/parámetros de sustitución para drivers que no lo soporten nativamente, y puede reescribir el estilo de los parámetros de sustitución por una forma más apropiada, si el driver soporta un estilo pero no el otro.
Esto puede resultar peligroso de cara a la Inyección SQL. Por eso, siempre que usemos PDO debemos establecer al modo off
la emulación de consultas preparadas. Para más detalles se pueden ver esta respuesta la pregunta: ¿Cómo evitar la inyección SQL en PHP?
- Usando MySQLi
mysqli_stmt::execute Ejecuta una consulta que ha sido previamente preparada usando la función mysqli_prepare(). Cuando se ejecutó cualquier marcador de parámetro que existe, será automáticamente reemplazado con los datos apropiados.
Si la sentencia es UPDATE, DELETE, o INSERT, se puede determinar el número total de filas afectadas usando le función mysqli_stmt_affected_rows(). Asimismo, si la consulta produce un conjunto de resultados se usa la función mysqli_stmt_fetch().
Al usar mysqli_stmt_execute(), se debe usar la función mysqli_stmt_fetch() para obtener los datos antes de realizar cualquier consulta adicional.
valores devueltos
mysqli_prepare()
devuelve un objeto de sentencia o FALSE si ocurre un error. A diferencia de PDO, no hace saltar excepciones.
- 86,578
- 19
- 122
- 221