Usar stored procedures desde Zend Framework 2
En esta ocasión veremos cómo usar stored procedures desde Zend Framework 2, en realidad, ejecutar o llamar un stored procedure no es muy diferente de ejecutar cualquier otra consulta. Pero veamos un ejemplo para ver esto más claramente.
Partamos de una tabla en MySQL con el siguiente contenido:
+———–+——-+———+———–+
| cvepedido | total | usuario | status |
+———–+——-+———+———–+
| 1 | 82.65 | 4 | abierta |
| 2 | 11.60 | 7 | abierta |
| 3 | 76.56 | 10 | cerrada |
| 4 | 50.23 | 7 | cerrada |
| 5 | 65.43 | 4 | cancelada |
| 6 | 91.03 | 5 | cancelada |
| 7 | 40.69 | 8 | cancelada |
| 8 | 53.92 | 5 | cancelada |
| 9 | 58.28 | 6 | abierta |
| 10 | 21.96 | 4 | enviada |
| 11 | 92.72 | 7 | enviada |
+———–+——-+———+———–+
De esta tabla lo más importante para nuestro ejemplo serám las columna total y status, pues las usaremos en el siguiente stored procedure:
CREATE PROCEDURE promedioStatus(IN estado varchar(20),OUT promedio float(10,2))
BEGIN
select AVG(total) into promedio from pedidos where status=estado;
END
Este procedimiento, es simple, recibe 2 parámetros uno de entrada y otro de salida, el de entrada es el status que se usará para calcular el promedio del total de los pedidos, promedio que será almacenada en el parametro de entrada “promedio”.
Ahora entramos al Zend Framework 2 usaremos un patrón Table Module con el componente Zend\Db de Zend Framework 2. Lo primero sería colocar la configuración de BD y el adaptador.
<?php return array( 'db' => array( 'driver' => 'pdo_mysql', 'host' => 'localhost', 'username' => 'xxxx', 'password' => 'xxxxxxxx', 'dbname' => 'xxxxxx' ), 'service_manager' => array( 'factories' => array( 'DbAdapter' => 'Zend\Db\Adapter\AdapterServiceFactory' ) ) );
Ahora hay que crear la clase para la Tabla
<?php namespace Application\Model; use Zend\Db\TableGateway\TableGateway; use Zend\Db\Adapter\Adapter; class PedidosTable { /** * * @var TableGateway */ protected $tableGateway; public function __construct(Adapter $adapter) { $this->tableGateway=new TableGateway('pedidos', $adapter); } }
Aquí en el constructor recibimos el adaptador de BD y creamos el Objeto TableGateway que estará dentro de una propiedad, desde el podremos llamar cualquier operación de BD y la idea es envolver esas operaciónes, querys y llamadas a store procedures dentro de métodos que describan esas operaciones en terminos de funcionalidad de clase y no funcionalidad de tabla, es decir que digan, insertar, actualizar, borrar, sino, obtener, cambiar, quitar.
Así creamos el siguiente método que ejecuta nuestro stored procedure:
public function obtenerPromedio($status) { $sql="CALL promedioStatus('{$status}',@res)"; $statement = $this->tableGateway->getAdapter()->createStatement($sql); $statement->execute(); $query = $this->tableGateway->getAdapter()->query("select @res as resultado"); $fila=$query->execute(); $resultado=$fila->current(); return $resultado['resultado']; }
Dentro de este módulo tomamos el adaptador y creamos una sentencia que llame nuestro store procedure y lo ejecutamos, el resultado se almacenará en la variable @res, luego simplemente hay que hacer un query que seleccione esa variable y hacer un fetch de ese resultado.
Lo que seguiría sería crear un servicio de esta clase para poder invocarla desde cualquier lugar donde tangamos acceso desde cualquier lugar en el que exista