Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 24-08-2012 09:32:47

sencha-dev2
Membre
Lieu: Centre France
Date d'inscription: 25-07-2012
Messages: 12

max(champ) ?

Bonjour, j'utilise une requête Zend $this->select(); afin de récupérer divers enregistrements triés par nom. Mais je dois ajouter un critère car le schéma de données a évolué.

Il n'était possible d'avoir qu'une adresse par personne, auparavant, et j'en affichais la commune pour permettre une meilleure distinction en cas d'homonymie.

Aujourd'hui, les adresses sont historisées, ce qui fait que la même personne est affichée plusieurs fois.

J'ai voulu utiliser la clause 'max(table.champ)' qui me paraissait obligatoire du fait que j'explore plusieurs fichiers, mais cela me renvoie une erreur SQLSTATE[42703] me disant que la colonne table.champ n'existe pas. J'ai essayé diverses syntaxes, mais aucune ne fonctionne. Pourriez-vous m'aider ?

En l'occurrence, le champ correspondant est une date, et le SGBDR que j'emploie est PostGreSQL.


I love Developping smile

Un développeur, un objectif, mille façons de faire, toutes inconnues big_smile
Sench@Dev

Hors ligne

 

#2 24-08-2012 14:12:49

amiss
Membre
Lieu: Cesson-Sévigné
Date d'inscription: 08-05-2011
Messages: 115

Re: max(champ) ?

bonjour,
sans votre requête il est quand même difficile de savoir d'où vient l'erreur. Seulement voilà j'ai des doutes que Zend_Db_Select reconnaisse table.champ comme une colonne de votre table autant faire un alias sur ce champ.

Hors ligne

 

#3 24-08-2012 15:12:47

sencha-dev2
Membre
Lieu: Centre France
Date d'inscription: 25-07-2012
Messages: 12

Re: max(champ) ?

Je vous prie de m'excuser, il est vrai que le corps de la requête aurait pu aider...

Le voici:

Partie contrôleur :

Code:

[lang=php]
public function ajouterAdresseTiersAction()
        {
            $this->_helper->viewRenderer->setNoRender();
            
            $at = new Model_AdresseTiers();
            $a = new Model_Adresse();
            
            print_r($_POST);
            if($_POST['numeroVoie'] == '' || $_POST['numeroVoie'] == null) 
            {
                $num = null;
            }
            else
            {
                $num = (int) $_POST['numeroVoie'];
            }
            if($_POST['idComplementNumeroRue'] == '' || $_POST['idComplementNumeroRue'] == null) 
            {
                $cpl = null;
            }
            else
            {
                $cpl = (int) $_POST['idComplementNumeroRue'];
            }
            if($_POST['idTypeVoie'] == '' || $_POST['idTypeVoie'] == null) 
            {
                $tv = null;
            }
            else
            {
                $tv = (int) $_POST['idTypeVoie'];
            }
            if($_POST['cedexAdresse'] == '' || $_POST['cedexAdresse'] == null) 
            {
                $cedex = null;
            }
            else
            {
                $cedex = (int) $_POST['cedexAdresse'];
            }
            $comm = (int) $_POST['idCommune'];
            $idT = (int) $_POST['idTiersPourAdresse'];
            
            $id = $a->creerAdresse($num, $cpl, $tv, $_POST['nomVoie'], $_POST['complementAdresse'], $comm, $cedex, $_POST['pointRemise'], $_POST['localisationConstruction']);
            
            $at->creerAdresseTiers($id, $idT, $_POST['dateEffet'], $_POST['facturation']);
        }

Voici la partie du modèle Adresse :

Code:

[lang=php]
function creerAdresse($num,$idCompl=null,$idVoie=null,$nomVoie=null,$complAdr=null,$idComm,$cedex=null,$pointRemise=null,$localisationConstruction=null)
        {
            try
            {
                $data=array('numero'=>$num,'idComplementNumeroRue'=>$idCompl,'idTypeVoie'=>$idVoie,'nomVoie'=>$nomVoie,'complementAdresse'=>$complAdr, 'idCommune'=>$idComm, 'cedexAdresse'=>$cedex, 'pointRemise'=>$pointRemise, 'localisationConstruction'=>$localisationConstruction);
                
                $id= $this->insert($data);
                
                return $id;
            }
            catch (exception $e)
            {
                echo '<pre>';
                echo $e->getMessage();
                echo '</pre>';
            }
        }

Et la partie modèle de AdresseTiers :

Code:

[lang=php]
function creerAdresseTiers($adresse, $tiers, $dateEffet, $facturation)
        {
            try
            {
                $data = array('idAdresse'=>$adresse, 'idTiers'=>$tiers, 'dateEffet'=>$dateEffet, 'facturation'=>$facturation);
                
                $this->insert($data);
            }
            catch (exception $e)
            {
                echo '<pre>';
                echo $e->getMessage();
                echo '</pre>';
            }
        }

Ce ne sont que les morceaux intervenants du code, néanmoins je peux vous transmettre les classes complètes si vous le désirez.

Merci encore.


I love Developping smile

Un développeur, un objectif, mille façons de faire, toutes inconnues big_smile
Sench@Dev

Hors ligne

 

#4 24-08-2012 15:59:41

amiss
Membre
Lieu: Cesson-Sévigné
Date d'inscription: 08-05-2011
Messages: 115

Re: max(champ) ?

sencha-dev2 a écrit:

Bonjour, j'utilise une requête Zend $this->select(); afin de récupérer divers enregistrements triés par nom. Mais je dois ajouter un critère car le schéma de données a évolué.

Il n'était possible d'avoir qu'une adresse par personne, auparavant, et j'en affichais la commune pour permettre une meilleure distinction en cas d'homonymie.

Aujourd'hui, les adresses sont historisées, ce qui fait que la même personne est affichée plusieurs fois.

J'ai voulu utiliser la clause 'max(table.champ)' qui me paraissait obligatoire du fait que j'explore plusieurs fichiers, mais cela me renvoie une erreur SQLSTATE[42703] me disant que la colonne table.champ n'existe pas. J'ai essayé diverses syntaxes, mais aucune ne fonctionne. Pourriez-vous m'aider ?

En l'occurrence, le champ correspondant est une date, et le SGBDR que j'emploie est PostGreSQL.

C'est votre requête select() où figure 'max(table.champ)' à l'origine de l'erreur SQLSTATE[42703] qu'on aimerait voir. Ensuite le fait d'utiliser PostGreSQL ne change en rien votre requête car Zend_Db_Select  fait abstraction de la base de données comme peut le faire un ORM classique(Doctrine, propel...).

Hors ligne

 

#5 24-08-2012 16:10:35

amiss
Membre
Lieu: Cesson-Sévigné
Date d'inscription: 08-05-2011
Messages: 115

Re: max(champ) ?

Je m'interroge sur la pertinence d'avoir 2 tables(adresse et adresseTiers) combien même ceci semble répondre à l'historique d'une personne par rapport à son adresse?bien sûr que ma question n'a rien avoir sur l'erreur sql.

Hors ligne

 

#6 24-08-2012 16:10:38

sencha-dev2
Membre
Lieu: Centre France
Date d'inscription: 25-07-2012
Messages: 12

Re: max(champ) ?

Je suis vraiment navré, la requête précédente m'avait donné beaucoup de fil à retordre, j'ai dû les confondre sur l'instant... Mea culpa.

Plus sérieusement, donc, voici la partie contrôleur et la partie modèle concernées.

Code:

[lang=php]
public function rechercheAction()
        {
            $this->_helper->viewRenderer->setNoRender();
            $bens= new Model_Beneficiaire();
            $res= $bens->tri($_POST["tri"],$_POST["param"]);
            echo json_encode($res);
        }

Code:

[lang=php]
function tri($tri,$param)
        {
            try
            {
                switch ($tri) {
                    case 'nom':
                        $tri='i.nom';$param=strtoupper($param);
                        break;
                    
                    case 'id':
                        $tri="idBeneficiaire";
                        break;
                    
                    case 'commune':
                        $tri="nomCommune";$param=strtoupper($param);
                        break;
                    
                    case 'tel':
                        $tri="telephone";
                        break;
                }
                
                $in= array(1,2);
                $select= $this->select();
                $select->setIntegrityCheck(false);
                
                $select->from(array('b'=>'Beneficiaire'),array('idBeneficiaire','nomPers'=>'i.nom','i.prenom','nomComm'=>'c.nom','te.numero'/*, 'dateEffet'=>'max("a.dateEffet")' */)); // a corriger pour date
                $select->join(array('ti'=>'Tiers'),'ti."idTiers" = b."idTiers"');
                $select->join(array('i'=>'Individu'), 'i."idTiers" = ti."idTiers"');
                $select->joinLeft(array('a'=>'AdresseTiers'), 'a."idTiers" = ti."idTiers"');
                $select->joinLeft(array('ad'=>'Adresse'), 'a."idAdresse" = ad."idAdresse"');
                $select->joinLeft(array('c'=>'Commune'), 'c."idCommune" = ad."idCommune"');
                $select->joinLeft(array('t'=>'TelephoneTiers'), 't."idTiers" = ti."idTiers"');
                $select->joinLeft(array('te'=>'Telephone'), 'te."idTelephone" = t."idTelephone"');
                $select->where('"idTypeTelephone"= ?',3);
                $select->where($tri.' LIKE \''.$param.'%\'');
                $select->order($tri.' ASC');
                //echo "<pre>".$select->__toString()."</pre>";
                return $this->fetchAll($select)->toArray();
            }
            catch (exception $e)
            {
                echo $e->getMessage();
            }
        }

Sachant pertinemment que le max était faux, je vous l'ai indiqué entre commentaires.

Merci encore, et pardonnez moi du désagrément encouru par mon erreur.

----------

Pour répondre à votre question, nous sommes partis du postulat qu'une même personne peut avoir habité plusieurs adresses, parfois simultanément, et qu'une même adresse peut héberger plusieurs personnes. Ce projet concerne de l'aide à domicile. Il peut donc y avoir une adresse de facturation différente de l'adresse de résidence.

Par conséquent, il nous a paru logique de créer une table intermédiaire entre Tiers et Adresse.

Dernière modification par sencha-dev2 (24-08-2012 16:16:17)


I love Developping smile

Un développeur, un objectif, mille façons de faire, toutes inconnues big_smile
Sench@Dev

Hors ligne

 

#7 24-08-2012 16:52:37

amiss
Membre
Lieu: Cesson-Sévigné
Date d'inscription: 08-05-2011
Messages: 115

Re: max(champ) ?

c'est pas grâve ça arrive.

pour que la requête retourne le max il faut juste enlever les doubles quotes  placés en paramètre de max.

Code:

faire 'dateEffet'=>'max(a.dateEffet)' au lieu de 'dateEffet'=>'max("a.dateEffet")'

sencha-dev2 a écrit:

Code:

[lang=php]
public function rechercheAction()
        {
            $this->_helper->viewRenderer->setNoRender();
            $bens= new Model_Beneficiaire();
            $res= $bens->tri($_POST["tri"],$_POST["param"]);
            echo json_encode($res);
        }

Code:

[lang=php]
function tri($tri,$param)
        {
            try
            {
                switch ($tri) {
                    case 'nom':
                        $tri='i.nom';$param=strtoupper($param);
                        break;
                    
                    case 'id':
                        $tri="idBeneficiaire";
                        break;
                    
                    case 'commune':
                        $tri="nomCommune";$param=strtoupper($param);
                        break;
                    
                    case 'tel':
                        $tri="telephone";
                        break;
                }
                
                $in= array(1,2);
                $select= $this->select();
                $select->setIntegrityCheck(false);
                
                $select->from(array('b'=>'Beneficiaire'),array('idBeneficiaire','nomPers'=>'i.nom','i.prenom','nomComm'=>'c.nom','te.numero', 'dateEffet'=>'max(a.dateEffet)' )); // corrigé
                $select->join(array('ti'=>'Tiers'),'ti."idTiers" = b."idTiers"');
                $select->join(array('i'=>'Individu'), 'i."idTiers" = ti."idTiers"');
                $select->joinLeft(array('a'=>'AdresseTiers'), 'a."idTiers" = ti."idTiers"');
                $select->joinLeft(array('ad'=>'Adresse'), 'a."idAdresse" = ad."idAdresse"');
                $select->joinLeft(array('c'=>'Commune'), 'c."idCommune" = ad."idCommune"');
                $select->joinLeft(array('t'=>'TelephoneTiers'), 't."idTiers" = ti."idTiers"');
                $select->joinLeft(array('te'=>'Telephone'), 'te."idTelephone" = t."idTelephone"');
                $select->where('"idTypeTelephone"= ?',3);
                $select->where($tri.' LIKE \''.$param.'%\'');
                $select->order($tri.' ASC');
                //echo "<pre>".$select->__toString()."</pre>";
                return $this->fetchAll($select)->toArray();
            }
            catch (exception $e)
            {
                echo $e->getMessage();
            }
        }

Sachant pertinemment que le max était faux, je vous l'ai indiqué entre commentaires.

Merci encore, et pardonnez moi du désagrément encouru par mon erreur.

----------

Pour répondre à votre question, nous sommes partis du postulat qu'une même personne peut avoir habité plusieurs adresses, parfois simultanément, et qu'une même adresse peut héberger plusieurs personnes. Ce projet concerne de l'aide à domicile. Il peut donc y avoir une adresse de facturation différente de l'adresse de résidence.

Par conséquent, il nous a paru logique de créer une table intermédiaire entre Tiers et Adresse.

Hors ligne

 

#8 24-08-2012 16:57:10

sencha-dev2
Membre
Lieu: Centre France
Date d'inscription: 25-07-2012
Messages: 12

Re: max(champ) ?

Cela est très gentil, toutefois cela ne change rien à mon problème... J'ai toujours une erreur SQLSTATE[42703] sur le même point.

Vous avez une autre idée ?


I love Developping smile

Un développeur, un objectif, mille façons de faire, toutes inconnues big_smile
Sench@Dev

Hors ligne

 

#9 24-08-2012 17:57:16

amiss
Membre
Lieu: Cesson-Sévigné
Date d'inscription: 08-05-2011
Messages: 115

Re: max(champ) ?

dans la requête essayez Zend_Db_Expr pour forcer l'objet select d'accepter max(a.dateEffet) comme chaîne de caractères:

Code:

[lang=php]
'dateEffet'=>new Zend_Db_Expr('max(a.dateEffet)').

si ça passe passe pas mettez des valeurs en dures justes pur tester la requête.La même requête sql generée sur l'exécuteur des requêtes de PostegreSql donne quoi?

Dernière modification par amiss (24-08-2012 17:58:35)

Hors ligne

 

#10 24-08-2012 18:03:58

amiss
Membre
Lieu: Cesson-Sévigné
Date d'inscription: 08-05-2011
Messages: 115

Re: max(champ) ?

sinon une alternative pour max serait de trier(date DESC) les données par date avec la clause order et ensuite récupérer la 1ère ligne du jeu de résultat.

Hors ligne

 

#11 27-08-2012 09:03:21

sencha-dev2
Membre
Lieu: Centre France
Date d'inscription: 25-07-2012
Messages: 12

Re: max(champ) ?

Vous devez me trouver un peu bête, mais je n'avais pas pensé à utiliser l'éditeur sql de PostGreSQL, merci pour votre aide, cela marche. Il manquait une clause GROUP BY.

Merci encore ! cool


I love Developping smile

Un développeur, un objectif, mille façons de faire, toutes inconnues big_smile
Sench@Dev

Hors ligne

 

#12 27-08-2012 11:55:24

amiss
Membre
Lieu: Cesson-Sévigné
Date d'inscription: 08-05-2011
Messages: 115

Re: max(champ) ?

heureux que ça marche

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