Como posso usar um procedimento armazenado em um database MySql com o Zend Framework?

Eu recentemente aprendi a usar o Zend Framework. Eu fiz um aplicativo CRUD simples. Mas agora eu quero usar um database existente para um aplicativo mais complexo e eu quero saber como eu chamo um procedimento armazenado no Model, como enviar parâmetros, como ler os resultados e armazená-los em um array em PHP. Por favor. Eu aprecio qualquer tipo de ajuda 🙂

Não é tão difícil. Aqui está um exemplo de um procedimento armazenado do MySQL com um parâmetro IN , um parâmetro OUT e um conjunto de resultados:

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

Você pode chamar isso com o método query() e passar um parâmetro:

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

O truque é que o procs armazenado do MySQL pode retornar vários conjuntos de resultados (se o proc tiver várias consultas SELECT por exemplo). Portanto, a API deve avançar em todos os conjuntos de resultados antes que você possa executar outra consulta SQL. Ou então você recebe o erro ” Comandos fora de sincronia “.

Se você usar o adaptador PDO_MySQL:

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

Se você usar o adaptador MySQLi, você verá que Zend_Db_Statement_Mysqli não implementa nextRowset() , então você tem que chamar o object de conexão mysqli interno:

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

Depois de limpar os conjuntos de resultados, você pode executar consultas SQL subseqüentes, por exemplo, para buscar o valor do parâmetro OUT do procedimento:

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

Ótima resposta do Bill. Apenas por completo, se você encontrar:

 SQLSTATE[HY000]: General error: 2053 

Ao usar esse método para obter um conjunto de resultados do seu procedimento, verifique seus argumentos. Refatorei um método e estava passando NULLs como argumentos para o procedimento, já que as variables ​​que usei estavam fora do escopo. Uma vez que eu consertei esse erro bobo, o problema foi embora (para ser substituído por outro):

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

Eu estou usando $stmt->fetchAll() embora. Eu mudei para usar prepare() e execute() no lugar de query() . Mudar para o mysqli do pdo_mysql na minha configuração do Zend_Db finalmente fez as coisas funcionarem para mim. Eu encontrei esta informação da seguinte pergunta SO:

Chamar vários stored procedures com o Zend Framework

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

Se alguém estiver procurando por ZendFramework 2 \ Zend Expressive usando Zend\Db :

Existe outra maneira de fazer isso usando o 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() }