Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Pages: 1
Bonjour
Dés que j'essaie d'établir une requête avec From sur plusieurs tables et une jointure j'ai le message d'erreur : Warning: Select query cannot join with another table in C:\wamp\www\location\library\Zend\Db\Table\Select.php on line 191..
Dans le $table->Join() et$table->From, faut-il mettre les champs de table défini dans mon schéma MySQL ? Les champs défini dans table extends Zend_Db_Table_Abstract ? J'ai tout essayé, mais je n'arrive pas.
Dans mon fichier Zend_Db_Table_Abstract, voilà comment est défini ma table :
protected $_dependentTables = array('Renovation','Facture','Plainte','Quitance'); protected $_referenceMap = array('Locataire' => array( 'columns' => array('ID_LOCATAIRE'), 'refTableClass' => 'Locataire', 'refColumns' => array('ID_LOCATAIRE')), 'Appartement' => array( 'columns' => array('ID_APPARTEMENT'), 'refTableClass' => 'Appart', 'refColumns' => array('ID_APPARTEMENT')) );
Voici ma requête en SQL
string(657) "SELECT STRUCTURE.NOM STRUCTURE_NOM, STRUCTURE.ID_STRUCTURE ID_STRUCTURE, APPARTEMENT.ID_APPARTEMENT ID_APPARTEMENT, APPARTEMENT.NUM APPARTEMENT_NUM, LOCATAIRE.ID_LOCATAIRE ID_LOCATAIRE, LOCATAIRE.NOM NOM, LOCATAIRE.PRENOM PRENOM, LOCATAIRE.NUM_DOSSIER LOCATAIRE_NUM_DOSSIER, LOCATION.* FROM STRUCTURE, LOCATION, LOCATAIRE, APPARTEMENT WHERE LOCATAIRE.ID_LOCATAIRE = LOCATION.ID_LOCATAIRE AND APPARTEMENT.ID_APPARTEMENT = LOCATION.ID_APPARTEMENT AND STRUCTURE.ID_STRUCTURE = APPARTEMENT.ID_STRUCTURE ORDER BY STRUCTURE_NOM"
Voilà, à partir de là je galère comme c'est pas possible. J'ai bien compris comment fonctionne le Where(), le From(array('t'=>'table') ainsi que le Join('table2','id=id) ... J'ai bien compris qu'il faut ajouter autant de join qu'on a de jointure, j'imagine que pour les From c'est pareil... Mais toujours cette même erreur.
Si quelqu'un peut me sauver, ce serait super....
Merci d'avance.
Dernière modification par whitespirit (29-04-2008 07:06:29)
Hors ligne
$table->select n'est pas un select sur la table
c'est le select qui permet de parcourir la table
pour faire des jointures et autre requêtes il faut utiliser $db->select()
voici une explication de l'usage de table select
http://sekaijin.ovh.org/?p=21
A+JYT
Hors ligne
Ho purée !!! Du coup, c'est normal que je n'arrivais pas à faire mes jointures, ce n'est pas possible. J'ai envie de lacher un vrai gros mot, mais bon. Ca me plante pas mal cette histoire, tous mes controlleurs utilisent une classe assez costaud pour gérer un menu de déplacement dans la bd.
Merci de cette précieuse information. Je vais me tenter à l'auto-jointure ce matin et voir si c'est jouable pour moi.
PS: super classe ton site.
Dernière modification par whitespirit (28-04-2008 07:56:02)
Hors ligne
J'ai ajouté les deux classes Fast_Db_Table et _Select.
Ca aurait pu être trop beau pour fonctionner du premier coup mais j'ai des erreurs :
Strict Standards: Declaration of Fast_Db_Table::info() should be compatible with that of Zend_Db_Table_Abstract::info() in C:\wamp\www\location\library\Fast\Db\Table.php on line 63
A la ligne 101, j'ai un new sur ma table qui est définit de la sorte :
class Location extends Fast_Db_Table { /** * Classname for row * * @var string */ protected $_rowClass = 'StructureRow'; /** * Auto Joined table for query * * @var string */ protected $_autojoin = array( array('table' => 'structure', 'on' => 'Appartement.ID__APPARTEMENT= LOCATION.ID__APPARTEMENT', 'fields' => array('NOM') ) ); protected $_restrict = array('1 = 1'); protected $_name = 'location'; protected $_primary = array('ID_LOCATION'); protected $_dependentTables = array('Renovation','Facture','Plainte','Quitance'); protected $_referenceMap = array('Locataire' => array( 'columns' => array('ID_LOCATAIRE'), 'refTableClass' => 'Locataire', 'refColumns' => array('ID_LOCATAIRE')), 'Appartement' => array( 'columns' => array('ID_APPARTEMENT'), 'refTableClass' => 'Appart', 'refColumns' => array('ID_APPARTEMENT')) );
J'ai encore 2 questiosn :
- dans la variable $_autojoin, est ce que je dois mettre le nom de ma table tel qu'elle est défini dans le schéma de ma base de données (c'est à dire en majuscule) ou bien tel qu'elle est défini dans mon modèle ? Ca une importance ?
- La ClassRow, comment dois-je la créer ? Je n'en ai jamais eu besoin pour l'instant, je ne vois pas quoi y mettre, et j'ai aussi ce message : File "StructureRow.php" was loaded but class "StructureRow" was not found in the file
Ben voilà, si tu repasses dans le coin...
Dernière modification par whitespirit (28-04-2008 09:02:43)
Hors ligne
Pour l'erreur info(), j'ai ajouté ces paramètres : info($key = null), il ne me reste que l'erreur de StructureRow.php. Sinon j'ai remplacé aussi la méthode find() dans ma classe Fast_Db_Table comme tu l'as précisé dans ton post.
Quand je met en commentaire cette ligne, j'exécute la requête et je l'affiche, j'ai bien :
SELECT `location`.*, `appartement`.`NUM` FROM `location` INNER JOIN `appartement` ON APPARTEMENT.ID_APPARTEMENT = LOCATION.ID_APPARTEMENT WHERE (1 = 1) ORDER BY `ID_LOCATION` ASC LIMIT 10
Ne pas tenir compte des 1=1, j'ai du faire cette manip (bourrin) sinon j'ai un bug si je n'ai pas de where !!!!!
En tout cas, en 30mn j'obtiens un résultat sur lequel j'ai passé 3h hier soir !!! Déjà, même si je ne m'en sortirai pas avec cette méthode, je te remercie 1000+1fois. En plus, j'avais déjà été sur ton site, et à l'époque je me disais "le jour ou je dois utilisais ça, c'est que j'ai déjà bien avancé dans mon apprentissage" !!! Je jette un oeil en passant sur ton billet concernant les champs calculés.
Dernière modification par whitespirit (29-04-2008 07:08:06)
Hors ligne
En relisant les tutos de Julien, j'ai trouvé des informations concernant _rowClass. Je pense que ce sera suffisant pour m'en sortir pour le reste. J'espère que je n'aurai pas de bugg durant l'utilisation de cette classe.
(http://julien-pauli.developpez.com/tuto … ge-tables/)
Hors ligne
quelle version de ZF utilise tu ?
Hors ligne
Ma version de ZF est la 1.5.0
Voilà j'ai un problème, après avoir lancé ma requête, j'ai bien un élément Rowset dont les premiers éléments me donne via un dump()
object(Zend_Db_Statement_Pdo)#260 (9) { ["_stmt:protected"] => object(PDOStatement)#258 (1) { ["queryString"] => string(657) "SELECT STRUCTURE.NOM STRUCTURE_NOM, STRUCTURE.ID_STRUCTURE ID_STRUCTURE, APPARTEMENT.ID_APPARTEMENT ID_APPARTEMENT, APPARTEMENT.NUM APPARTEMENT_NUM, LOCATAIRE.ID_LOCATAIRE ID_LOCATAIRE, LOCATAIRE.NOM NOM, LOCATAIRE.PRENOM PRENOM, LOCATAIRE.NUM_DOSSIER LOCATAIRE_NUM_DOSSIER, LOCATION.* FROM STRUCTURE, LOCATION, LOCATAIRE, APPARTEMENT WHERE LOCATAIRE.ID_LOCATAIRE = LOCATION.ID_LOCATAIRE AND APPARTEMENT.ID_APPARTEMENT = LOCATION.ID_APPARTEMENT AND STRUCTURE.ID_STRUCTURE = APPARTEMENT.ID_STRUCTURE ORDER BY STRUCTURE_NOM" }
Lorsque je tappe cette requête depuis phpmyadmin, j'obtient exactement les réultats attendus. Cependant, je ne récupère aucune information quand je fais un foreach($rowset as $row). La méthode de rowset "count()" n'existe plus et je ne peux pas traiter les informations. Comment dois-je procéder ?
Comment acceder dans ma vue à un élément de type STRUCTURE.ID_STRUCTURE car $row->STRUCTURE.ID_STRUCTURE me renvoie une erreur ?
Merci encore
[MODIF]
1.Je crois que je c'est parceque je n'ai pas défini le fameux rowset. Je test et je modifie ce post en cas de victoire.
2. Non, ce n'est pas ça, en regardant mieux mon dump, je n'ai pas un rowset mais un Statement (1ere ligne).
[/MODIF]
Dernière modification par whitespirit (28-04-2008 11:40:01)
Hors ligne
ce ne serait pas directement $monID=$row->ID_STRUCTURE par hazard?
En tout cas j'ai jamais vu de $quelquechose=$row->quelquechose.autrechose ...
Hors ligne
Je ne peux pas mettre $row->NOM car j'ai NOM défini dans LOCATAIRE.NOM et STRUCTURE.NOM. Il va y avoir une ambigüité.
Je ne sais pas pourquoi, je récupère non pas un RowSet mais un Statement. Peut-être qu'il faut que je redéfinisse la méthode _fetch ?
Hors ligne
Le Zend_Db_Statement dispose d'une méthode fetchAll...
(doc ici )
après, je ne me suis pas lancé encore assez dedans pour vraiment t'aider, ca va venir cette semaine, désolé ^^
Hors ligne
Ok, il me faut faire un $ligne = $this->location->FetchAll();. C'est domage que tout ceci ne me retourne pas un rowSet. S'il y'a un code à utiliser pour récupérer un RowSet, je suis preneur.
Merci, en tout cas ça marche.
Au sujet de cette syntaxe SQL dans le select() : LOCATAIRE.NOM, ZF le transforme en LOCATAIRE_NOM. Fantastique non ?
Hors ligne
ah ok, ca pourra peut etre m'éviter de faire des AS alors
Hors ligne
Lol... Je te conseil de garder AS quand même car dés c'est peut-être pénible de savoir ZF remplace quoi par quoi. Par exemple si le champs existe déjà dans le résultat de ta requête, il va remplacer le '.' par un majestueux '_'. Si ce champs n'existe pas, il va le mettre tel quel. Enfin, c'est à voir, ma requête est généré automatiquement mais c'est sûr que j'avais mis un AS avant.
Voilà une bonne chose de fait. Pour finaliser ce post qui m'a pris pas mal de temps dans ma journée, je pose ici la dernière question:
En suivant l'exemple de Sekajin pour effectuer les Join, est-il possible par une manip quelconque de récupérer un rowSet plutot qu'un Select ???
Hors ligne
Je ne comprends pas ce que tu veux faire
Le select est déjà une encapsulation du rowset
tu fait while($row= $select->fetchRow()) pour le parcourir
à quoi te sert un rowset
de plus j'ai l'impression que tu veux utilise r le select interne d'une table qui sert à définir le parcour de la table pour faire une requête.
pour cela il y a $db->select() et non $table->select()
le rowset ne sert absolument à rien
le truc c'est
$select = $this->_db->select(); // @var $select Zend_Db_Select $select ->from('role', array( 'id' => 'rol_id', 'ident' => 'rol_code', 'name' => 'rol_label', 'selected' => '(rol_id = :_selected)' )) ->where('rol_id > 1') ->where('rol_left >= (SELECT rol_left FROM role WHERE rol_id = :_currentRole1)') ->where('rol_right <= (SELECT rol_right FROM role WHERE rol_id = :_currentRole2)') ->order('rol_left') ; $statement = $this->_db->prepare($select); $statement->setFetchMode(Zend_Db::FETCH_OBJ); $statement->execute($params); $list = $statement->fetchAll();
ou si tu ne veux pas un tableau de tout les élément
$object = $statement->fetch();
l'objet statement et donc bien un élément qui te permet de parcourir le résultset sans avoir à le manipuler.
tu peux aussi te passer du statement et utiliser directement les méthodes du select qui lui aussi te permet le parcour du résultset
A+JYT
Hors ligne
Merci, en fait, je n'avais pas vu que c'était possible de faire while($row= $select->fetchRow()). En fait, mon questionnement viens du fait que pour garder une homogénéité dans mon code, j'aurai souhaité acceder à la ligne via $row->ID_STRUCTURE et non $row['ID_STRUCTURE'], car pour cette partie je fais un copier coller. Mais c'est un détail.
Quoi qu'il en soit, après avoir passé une bonne journée à manipuler ces informations dans tous les sens, j'ai compris plein de choses. Et tout fonctionne. Merci encore Sekajin.
Hors ligne
Excuse moi Sekajin, j'avais oublier d'effacer une ligne dans mon controlleur qui me retournait un objet Select. Du coup, je comprends que tu ne voyais pas trop ce que je voulais. Voilà juste pour cette remarque. Sinon, ton code fonctionne à 400%, c'est vraiment puissant ce que tu m'as fournis là.
Hors ligne
Pages: 1