Saltar la navegación

3.2.2.- Ejecución de consultas.

Imagen del dibujo de un cilindor hueco verde con las letras sql en amarillo
Ignacio javier igjav (CC BY-SA)

Para ejecutar una consulta SQL utilizando PDO, debes diferenciar aquellas sentencias SQL que no devuelven como resultado un conjunto de datos, de aquellas otras que sí lo devuelven.

En el caso de las consultas de acción, como INSERT, DELETE o UPDATE, el método exec devuelve el número de registros afectados.

$registros = $conProyecto->exec('DELETE FROM stocks WHERE unidades=0');
echo "<p>Se han borrado $registros registros.</p>";

Si la consulta genera un conjunto de datos, como es el caso de SELECT, debes utilizar el método query, que devuelve un objeto de la clase PDOStatement.

$host = "localhost";
$db = "proyecto";
$user = "gestor";
$pass = "secreto";
$dsn = "mysql:host=$host;dbname=$db";
$conProyecto=new PDO($dsn, $user, $pass);
$conProyecto->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
$resultado = $conProyecto->query("SELECT producto, unidades FROM stock");

Por defecto PDO trabaja en modo "autocommit", esto es, confirma de forma automática cada sentencia que ejecuta el servidor. Para trabajar con transacciones, PDO incorpora tres métodos:

  • beginTransaction. Deshabilita el modo "autocommit" y comienza una nueva transacción, que finalizará cuando ejecutes uno de los dos métodos siguientes.
  • commit. Confirma la transacción actual.
  • rollback. Revierte los cambios llevados a cabo en la transacción actual.

Una vez ejecutado un commit o un rollback, se volverá al modo de confirmación automática.

$ok = true;
$conProyecto->beginTransaction();
if(!$conProyecto->exec('DELETE …')) $ok = false;
if(!$conProyecto->exec('UPDATE …')) $ok = false;

…

if ($ok) $conProyecto->commit();  // Si todo fue bien confirma los cambios

else $dwes->rollback();   //  y si no, los revierte

Ten en cuenta que no todos los motores no soportan transacciones. Tal es el caso, como ya viste, del motor MyISAM de MySQL. En este caso concreto, PDO ejecutará el método beginTransaction sin errores, pero naturalmente no será capaz de revertir los cambios si fuera necesario ejecutar un rollback.

Ejercicio resuelto

De una forma similar al anterior ejercicio de transacciones, utiliza PDO para repartir entre las tiendas las tres unidades que figuran en unidades, del producto con código PAPYRE62GB, en la tienda de código 1. Es decir primero con un update ponemos el número de unidades de unidades del producto de nombre corto PAPYRE62GB a 1 en la tienda de código 1 y luego hacemos un insert para insertar dos unidades de dicho producto en la tienda de código 2.

Autoevaluación

Pregunta

Si programas tu aplicación correctamente utilizando "beginTransaction" antes de realizar un cambio, ¿siempre será posible revertirlo utilizando "rollback"?

Respuestas

Sí.

No.

Retroalimentación