¿Cómo puedo usar un procedimiento almacenado en una base de datos MySql con Zend Framework?

Recientemente aprendí a usar Zend Framework. Hice una simple aplicación CRUD. Pero ahora quiero usar una base de datos existente para una aplicación más compleja y quiero saber cómo llamo a un procedimiento almacenado en el Modelo, cómo enviar parámetros, cómo leer los resultados y almacenarlos en una matriz en PHP. Por favor. Agradezco cualquier tipo de ayuda 🙂

No es muy difícil. Aquí hay un ejemplo de un procedimiento almacenado de MySQL con un parámetro IN , un parámetro OUT y un conjunto de resultados:

 CREATE PROCEDURE MyProc(IN i INTEGER, OUT o INTEGER) BEGIN SELECT i+10 INTO o; SELECT i, o; END 

Puede llamar esto con el método query() y pasar un parámetro:

 $stmt = $db->query("CALL MyProc(?, @output)", array(25)); print_r( $stmt->fetchAll() ); 

El truco es que los procs almacenados de MySQL pueden devolver múltiples conjuntos de resultados (si el proceso tiene múltiples consultas SELECT por ejemplo). Por lo tanto, la API debe avanzar a través de todos los conjuntos de resultados antes de poder ejecutar otra consulta SQL. O bien obtienes el error ” Comandos no sincronizados “.

Si usa el adaptador PDO_MySQL:

 while ($stmt->nextRowset()) { } 

Si usa el adaptador MySQLi, encontrará que Zend_Db_Statement_Mysqli no implementa nextRowset() , por lo que debe llamar al objeto interno de conexión mysqli:

 while ($db->getConnection()->next_result()) { } 

Una vez que borre los conjuntos de resultados, puede ejecutar consultas SQL posteriores, por ejemplo para recuperar el valor del parámetro OUT del procedimiento:

 $stmt = $db->query("SELECT @output"); print_r( $stmt->fetchAll() ); 

Gran respuesta de Bill. Solo para completar, si encuentras:

 SQLSTATE[HY000]: General error: 2053 

Cuando use este método para obtener un conjunto de resultados de su procedimiento, verifique sus argumentos. Refactoreé un método y estaba pasando NULLs como argumentos para el procedimiento ya que las variables que había usado estaban fuera del scope. Una vez que solucioné este error tonto, el problema desapareció (para ser reemplazado por otro):

 SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). 

Estoy usando $stmt->fetchAll() embargo. Cambié a usar prepare() y execute() en lugar de query() . Cambiar a mysqli desde pdo_mysql en mi configuración de Zend_Db finalmente me funcionó. Encontré esta información de la siguiente pregunta SO:

Llamar a múltiples procedimientos almacenados con Zend Framework

  $db = Zend_Db_Table::getDefaultAdapter(); $stmt = $db->query("CALL procedure()"); $data = $stmt->fetchAll(); 

Si alguien está buscando ZendFramework 2 \ Zend Expressive usando Zend\Db :

Hay otra forma de hacerlo utilizando el método createStatement() .

 // prepare create statement from adapter $stmt = $this->getAdapter()->createStatement(); $stmt->prepare('CALL myproc("myVal")'); // execute sql query $records = $stmt->execute(); // manipulate results if ($records instanceof ResultInterface && $records->isQueryResult()) { $resultSet = new ResultSet; $resultSet->initialize($records); // return records if found if (count($resultSet)) { // return array of result set return $resultSet->toArray(); } // if no records found return array() }