Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 23-02-2009 15:00:27

LeDuc08
Membre
Date d'inscription: 23-02-2009
Messages: 22

[Zend_Db][1.7] 2 Procedures Stockees à la suite

Bonjour,
Je suis un nouvel utilisateur du Zend Framework et je commence à tester un peu les possibilités de celui-ci.
Je bute sur une problématique simple, je n'arrive pas à enchainer 2 appels à une procédure stockée:

Code:

<?php

require 'Zend/Loader.php';
Zend_Loader::registerAutoload();

$config =     new Zend_Config_Ini('config.ini', 'prod');
$db     =    Zend_Db::factory($config->database);

// 1ère requete ok, le dump me renvoi bien un tableau
$query_one = "CALL work_code_infos('AAAAAH')";
$infos_one = $db->fetchRow($query_one);
Zend_Debug::dump($infos_one);    

// 2nd requete affiche une erreur => Cannot execute queries while other unbuffered queries are active
$query_two = "CALL work_code_infos('AAAAAI')";
$infos_two = $db->fetchRow($query_two);
Zend_Debug::dump($infos_two);

Je comprend bien le message, mais comment faire pour que la première requête soit retirée du buffer???
Est-ce que je passe à côté de quelque chose pour l'appel à la procédure stockée ?

D'avance merci pour votre aide.

Edit: En fait, j'obtiens le même message si j'essaye de faire une simple requête après l'appel à ma procédure.

Dernière modification par LeDuc08 (23-02-2009 15:03:42)

Hors ligne

 

#2 23-02-2009 15:36:59

philippe
Administrateur
Lieu: Grenoble
Date d'inscription: 01-03-2007
Messages: 1624

Re: [Zend_Db][1.7] 2 Procedures Stockees à la suite

si tu fais un fetchAll sur ton premier appel le buffer sera vide après (le problème d'un fetchRow, c'est que le ZF attend que tu récupères l'ensemble des lignes avant de refermer son curseur).

Sinon tu peux faire des prepare, execute avec des statements différents si tu veux réellement imbriquer tes requêtes, mais je pense que dans ton cas, ça n'est pas le but.

A+, Philippe


twitter : @plv ; kitpages.fr : Création de sites internet à Grenoble et Paris

Hors ligne

 

#3 23-02-2009 15:50:24

LeDuc08
Membre
Date d'inscription: 23-02-2009
Messages: 22

Re: [Zend_Db][1.7] 2 Procedures Stockees à la suite

Merci Philippe pour ta réponse,
Malheureusement cela ne corrige pas le problème, j'ai commencé par un fetchAll et j'avais essayé le fetchRow en espérant justement qu'il ne laisse pas le curseur ouvert...
Vu la simplicité du problème, je me demande si cela ne vient pas de ma procédure stockée?

Je ne dois pas être le premier à appeler une procédure stockée puis faire une requête sur la base... ;-))

Je mets le code de ma procédure au cas où quelqu'un y verrait une erreur...

Code:

CREATE PROCEDURE my_procedure(IN workcode VARCHAR(8)) 
BEGIN
SELECT works_type_ref FROM burden WHERE work_code = workcode INTO @wo_tbl;
SET @requete = CONCAT('SELECT * FROM burden B INNER JOIN ', @wo_tbl, ' W ON B.work_code = W.work_code AND B.work_code = "', workcode, '"' );
PREPARE rp FROM @requete;
EXECUTE rp;
DROP PREPARE rp;
END|

Edit: J'ai essayé également avec une procédure tout ce qu'il y a de plus simple, mais le résultat est identique... ;-(

Dernière modification par LeDuc08 (23-02-2009 17:44:07)

Hors ligne

 

#4 24-02-2009 10:43:38

sekaijin
Membre
Date d'inscription: 17-08-2007
Messages: 1137

Re: [Zend_Db][1.7] 2 Procedures Stockees à la suite

voilà une classe que j'ai fait pour capitaliser des appels à des Proc stockée en oracle

Code:

<?php
Zend_Loader::loadClass('Fast_Model_Component');

class Model_Imc extends Fast_Model_Component
{
    /**
    *  @var Zend_Db_Adapter_Abstract
    */
    protected $_db;

    public function __construct()
    {
        // On va avoir besoin de la base.
        $this->_db = Fast_Registry::get('dbAdapter');
    }

    protected function _callImcProc($procName, $params, $out=null) {
        //Fast_Debug::show('trace', $params);
        /*$data = array();
        foreach ($paramsOrder as $key) {
        $data[$key] = $params[$key];
        }*/
        $data = $params;
        //Fast_Debug::show('trace', $data);
        $return = new stdClass();
        $res = '';
        if (isset($out)) {
            $sql = 'BEGIN PKG_IMC.' . $procName . '(?, :out); END;';
        } else {
            $sql = 'BEGIN PKG_IMC.' . $procName . '(?); END;';
        }
        $sql = $this->_db->quoteInto($sql,$data);
        #Fast_Debug::show('$sql', $sql);

        $this->_db->beginTransaction();
        try {
            //$result = $this->_db->query($sql);

            $statement = $this->_db->prepare($sql);
            if (isset($out)) {
                $statement->bindParam(':out', $res, PDO::PARAM_STR, 32);
            }
            $statement->execute();
            //echo "\n\n\n=>";
            //Fast_Debug::show('trace', $result);
            $this->_db->commit();
            $return->success = true;
            if (isset($out)) {
                $return->$out = $res;
            }
        } catch (Exception $e) {
            //echo "\n\n\n=>";
            //Fast_Debug::show('trace', $result);
            $this->_db->rollBack();
            //echo "\n =====>".$e->getMessage();
            $return->error = $e->getMessage();
            $return->msg = $sql;
            $return->success = false;
            $this->_traceException(2, $e);
        }
        return $return;
    }

    /**
     * Execute une requête et retourne un élément
     *
     * @param $select requête SQL
     * @param $params tableau de parameters nommés.
     *
     * @return array Tableau d'objet (sdtClass)
     */
    protected function _get($select, $params=array(), $level=1)
    {
        try {
            //Fast_Debug::show("$select", $params);
            $statement = $this->_db->prepare($select);
            $statement->setFetchMode(Zend_Db::FETCH_OBJ);
            $statement->execute($params);
            $res = $statement->fetch();
            //Fast_Debug::show('get',$res);
            return $res;
        } catch (Exception $e) {
            $this->_traceException($level, $e);
            return false;
        }

    }

    /**
     * Execute une requête et retourne sous forme de tableau tous les éléments
     *
     * @param $select requête SQL
     * @param $params tableau de parameters nommés.
     *
     * @return array Tableau d'objet (sdtClass)
     */
    protected function _getList($select, $params=array(), $level=1)
    {
        try {
            #Fast_Debug::show("$select", $params);
            $statement = $this->_db->prepare($select);
            $statement->setFetchMode(Zend_Db::FETCH_OBJ);
            $statement->execute($params);
            $list = $statement->fetchAll();
            #Fast_Debug::show('getList',$list);
            return $list;
        } catch (Exception $e) {
            $this->_traceException($level, $e);
            return false;
        }

    }

    protected function _getPagedList($select, $count, $params=array())
    {
        try {
            $list = $this->_getList($select, $params, 2);
            if (! is_array($list)) {
                return false;
            }
            #Fast_Debug::show("$count", $params);
            $statement = $this->_db->prepare($count);
            $statement->setFetchMode(Zend_Db::FETCH_OBJ);
            $statement->execute($params);
            $number = $statement->fetch();
            #Fast_Debug::show('$number',$number);
            return (object)array('count' => $number->count, 'data' => $list);
        } catch (Exception $e) {

            $this->_traceException(1, $e);
            return false;
        }
    }

    protected function _traceException($level, $e) {
        $trace = debug_backtrace();
        $entry = $trace[$level+1];
        $msgs = array();
        array_push($msgs, 'Fail');
        $user = Zend_Auth::getInstance()->getIdentity();
        if ($user) {
            array_push($msgs, $user->usr_ident);
        } else {
            array_push($msgs, ANONYMOUS);
        }
        if (isset($entry["class"])) {
            $stack = $entry["class"] . "." . $entry["function"];
        } else {
            $stack = $entry["function"];
        }
        array_push($msgs, $stack);

        $entry = $trace[$level];
        if (isset($entry["class"])) {
            $stack = $entry["class"] . "." . $entry["function"];
        } else {
            $stack = $entry["function"];
        }
        if (isset($entry["file"])) {
            $stack .= " => " . $entry["file"] . ":" . $entry["line"] . PHP_EOL;
        } else {
            $stack .= PHP_EOL;
        }

        array_push($msgs, ereg_replace("\n", ' ', $e->getMessage()));

        error_log(
        '----------------------------------------' . PHP_EOL
        . $e->getMessage(). PHP_EOL
        . $stack
        . '----------------------------------------',0
        );
        call_user_func_array('Fast_Log::standard', $msgs);
    }
}

toutes mes proc étaient faites avec le même format et lorsque il y avait un retour ce n'était qu'une seule variable

voici un exemple d'appel

Code:

<?php
Zend_Loader::loadClass('Model_Imc');

class Model_Access extends Model_Imc
{

    /*
    PROCEDURE INSERT_ACCES (
    P_SITE_ID NUMBER,
    P_USR_ID NUMBER,
    P_ADMIN NUMBER,
    P_USR_ID_ADMIN,
    );
    */
    public function saveAccess($data) {
        return $this->_callImcProc('INSERT_ACCES', $data, 'a_id');
    }
...

appel de insert_acces avec un tableau associatif d'argument et retourne le champs a_id

A+JYT

Hors ligne

 

#5 24-02-2009 11:15:44

LeDuc08
Membre
Date d'inscription: 23-02-2009
Messages: 22

Re: [Zend_Db][1.7] 2 Procedures Stockees à la suite

Salut,
Merci pour ta réponse, je ne suis pas encore bien familiarisé avec le chargement de class perso, je vais donc prendre un peu de temps pour voir comment intégrer ta class dans mon code, ensuite je verrais si cela corrige mon problème.

PS: Peux-tu me donner la class Fast_Model_Component, où est-ce que je suis déjà sensé l'avoir?
Sa sent le boulet là... ;-)

@ +

LeDuc

Dernière modification par LeDuc08 (24-02-2009 11:22:36)

Hors ligne

 

#6 24-02-2009 15:30:13

sekaijin
Membre
Date d'inscription: 17-08-2007
Messages: 1137

Re: [Zend_Db][1.7] 2 Procedures Stockees à la suite

elle ne contient rien de pertinent c'est juste un mécanisme perso pour charger certaines partie de mon modèle en fonction du besoin.

ce qui est intéressante dans la classe c'est l'emploie d'une méthode unique qui fait tous les appel aux procédures stokées

A+jyt

Hors ligne

 

Pied de page des forums

Propulsé par PunBB
© Copyright 2002–2005 Rickard Andersson
Traduction par punbb.fr

Graphisme réalisé par l'agence Rodolphe Eveilleau
Développement par Kitpages