Précédent   Forum des professionnels en informatique > PHP > PHP & SGBD
PHP & SGBD Forum d'entraide sur les SGBD avec PHP. Avant de poster : FAQ BDD, toutes les FAQ PHP, cours BDD et sources BDD
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 06/02/2011, 19h10   #1
Invité de passage
 
nicolas gaillard
Inscription : août 2010
Messages : 12
Détails du profil
Informations personnelles :
Nom : nicolas gaillard

Informations forums :
Inscription : août 2010
Messages : 12
Points : 1
Points : 1
Par défaut Insert de plusieurs entrée avec Classe CRUD

Bonjour,

J'utilise cette classe CRUD et j'aimerai faire une requête insert de plusieurs entrées.

Voici ce que j'obtient lorsque j'affiche le tableau $values passé en paramètre :

Citation:
Array
(
[0] => Array
(
[nom] => dupont
[prenom] => julien
[societe] => fichier
[email] => julien.dupont@hotmail.com
)

[1] => Array
(
[nom] => Durant
[prenom] => lkuh
[societe] => fichier
[email] => durant@gmail.com
)

)
Et voici l'erreur :

Citation:
Exception levée dans l'application.
Message SQLSTATE[HY093]: Invalid parameter number: parameter was not defined
Si quelqu'un comprend comment envoyer plusieurs entrées en une requête...

Merci d'avance.
nico21000 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/02/2011, 09h18   #2
Rédacteur/Modérateur
 
Avatar de MaitrePylos
 
Homme Gérard Ernaelsten
DBA & Dev PHP
Inscription : juin 2005
Messages : 3 174
Détails du profil
Informations personnelles :
Nom : Homme Gérard Ernaelsten
Âge : 39
Localisation : Belgique

Informations professionnelles :
Activité : DBA & Dev PHP
Secteur : Service public

Informations forums :
Inscription : juin 2005
Messages : 3 174
Points : 6 460
Points : 6 460
peux-t-on voir ton code, ainsi que la définition de ta table ?
MaitrePylos est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/02/2011, 12h19   #3
Modérateur
 
Avatar de Benjamin Delespierre
 
Benjamin Delespierre
Développeur Web
Inscription : février 2010
Messages : 2 984
Détails du profil
Informations personnelles :
Nom : Benjamin Delespierre
Âge : 24
Localisation : France

Informations professionnelles :
Activité : Développeur Web
Secteur : High Tech - Opérateur de télécommunications

Informations forums :
Inscription : février 2010
Messages : 2 984
Points : 5 015
Points : 5 015
Citation:
Message SQLSTATE[HY093]: Invalid parameter number: parameter was not defined
C'est probablement un problème dû au requêtes préparées. Il doit de manquer des valeurs dans le tableau de remplacement, regarde par ici: http://www.php.net/manual/en/pdostatement.execute.php

Vérifie et reviens nous voir
__________________
A la recherche d'un framework MVC facile a prendre en main ? Essayez Axiom
Nouveau: la référence d'Axiom est disponible sur GitHub (je la peaufine en ce moment même).

Un problème correctement identifié est à moitié résolu, évitez de poster l'intégralité de votre code avec pour seule explication "ça ne marche pas...".
Pour identifier correctement vos problèmes PHP, utilisez la gestion des erreurs et xdebug.

Les boutons et existent, servez-vous en
Benjamin Delespierre est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/02/2011, 08h32   #4
Invité de passage
 
nicolas gaillard
Inscription : août 2010
Messages : 12
Détails du profil
Informations personnelles :
Nom : nicolas gaillard

Informations forums :
Inscription : août 2010
Messages : 12
Points : 1
Points : 1
Voici mon code :

Controller :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 
$this->add($contact->Contact);
 
   public function add($tab = null) {
        if(is_null($tab)){
 
			}else{
				$tab = array_values($tab);
				if(count($tab) > 1){  //Si j'ai plus de une entré à envoyer
					$values = array();
 
                    foreach($tab as $key=>$value){
                    	array_push($values, array('nom'=>$tab[$key]->nom,'prenom'=>$tab[$key]->prenom,'societe'=>$tab[$key]->societe,'email'=>$tab[$key]->email));
                    }
 
					$this->data->AddEmail($values);
				}else{    // Si je n'ai qu'une entré à envoyer ça marche...
                    $values = array('nom'=>$tab[0]->nom,'prenom'=>$tab[0]->prenom,'societe'=>$tab[0]->societe,'email'=>$tab[0]->email);
 
					$this->data->AddEmail($values);
                }
 
			}
 
 
    }
Model :

Code :
1
2
3
4
5
 
public function AddEmail($values){
		$this->dbInsert('emails', $values);
		return $r;	
	}
Classe CRUD :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 
 public function dbInsert($table, $values)
        {
            /*** snarg the field names from the first array member ***/
            $fieldnames = array_keys($values);
            /*** now build the query ***/
            $size = sizeof($fieldnames);
            $i = 1;
            $sql = "INSERT INTO $table";
            /*** set the field names ***/
            $fields = '( ' . implode(' ,', $fieldnames) . ' )';
            /*** set the placeholders ***/
            $bound = '(:' . implode(', :', $fieldnames) . ' )';
            /*** put the query together ***/
            $sql .= $fields.' VALUES '.$bound;
            /*** prepare and execute ***/
			$stmt = BDinstance::getInstance()->prepare($sql);
 
			/* echo '<pre>';
             print_r($sql);
             echo '</pre>';
			*/
			return $stmt->execute($values);
        }
et voici ma table :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
CREATE TABLE `emails` (
  `id` int(11) NOT NULL auto_increment,
  `email` varchar(255) NOT NULL,
  `nom` varchar(255) NOT NULL,
  `societe` varchar(255) NOT NULL,
  `prenom` varchar(255) NOT NULL,
  `adresse` text NOT NULL,
  `cp` char(5) NOT NULL,
  `ville` varchar(255) NOT NULL,
  `tel` char(10) NOT NULL,
  `url` tinytext NOT NULL,
  `commentaire` text NOT NULL,
  `date_inscri` date NOT NULL,
  `valid` tinyint(1) NOT NULL,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `email` (`email`)
) ENGINE=MyISAM AUTO_INCREMENT=24 DEFAULT CHARSET=latin1 AUTO_INCREMENT=24 ;
nico21000 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/02/2011, 10h34   #5
Membre Expert
 
Avatar de Madfrix
 
Inscription : juin 2007
Messages : 2 278
Détails du profil
Informations personnelles :
Localisation : France, Gironde (Aquitaine)

Informations forums :
Inscription : juin 2007
Messages : 2 278
Points : 2 324
Points : 2 324
Bonjour,

tu mets à jour ta table emails avec 4 colonnes (nom, prenom, société, email) mais cette table contient d'autres colonnes qui ne peuvent pas être nulles (en fait toutes tes colonnes). Vu qu'elles n'ont pas de valeurs par défaut, tu as une erreur d'insertion
__________________
Je ne réponds pas aux questions envoyées par mp
Madfrix est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/02/2011, 10h55   #6
Invité de passage
 
nicolas gaillard
Inscription : août 2010
Messages : 12
Détails du profil
Informations personnelles :
Nom : nicolas gaillard

Informations forums :
Inscription : août 2010
Messages : 12
Points : 1
Points : 1
Bonjour et merci pour ta réponse,

Je me suis posé la question en écrivant le message. Je test ce soir et je vous redis demain.

Encore merci et bonne journée
nico21000 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/02/2011, 13h56   #7
Invité de passage
 
nicolas gaillard
Inscription : août 2010
Messages : 12
Détails du profil
Informations personnelles :
Nom : nicolas gaillard

Informations forums :
Inscription : août 2010
Messages : 12
Points : 1
Points : 1
J'ai changer quelques petites choses :

Controller :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 
public function add($tab = null) {
        if(is_null($tab)){
 
			}else{
				$tab = array_values($tab);
				if(count($tab) > 1){  //Si j'ai plus de une entré à envoyer
					$values = array();
 
                /*    foreach($tab as $key=>$value){
                    	array_push($values, array('nom'=>$tab[$key]->nom,'prenom'=>$tab[$key]->prenom,'societe'=>$tab[$key]->societe,'email'=>$tab[$key]->email));
                    }
                  */
 
				   array_push($values, array('nom'=>'nom1','prenom'=>'prenom1','societe'=>'societe1','email'=>'email1@test.fr'));
                   array_push($values, array('nom'=>'nom2','prenom'=>'prenom2','societe'=>'societe2','email'=>'email2@test.fr'));
 
                   $this->data->AddEmail($values);
				}else{    // Si je n'ai qu'une entré à envoyer ça marche...
                    $values = array('nom'=>$tab[0]->nom,'prenom'=>$tab[0]->prenom,'societe'=>$tab[0]->societe,'email'=>$tab[0]->email);
 
					$this->data->AddEmail($values);
                }
 
			}
 
 
    }
La structure de la table :

Citation:
CREATE TABLE `emails` (
`id` int(11) NOT NULL auto_increment,
`email` varchar(255) NOT NULL,
`nom` varchar(255) NOT NULL,
`societe` varchar(255) NOT NULL,
`prenom` varchar(255) NOT NULL,
`adresse` text,
`cp` char(5) default NULL,
`ville` varchar(255) default NULL,
`tel` char(10) default NULL,
`url` tinytext,
`commentaire` text,
`date_inscri` date default NULL,
`valid` tinyint(1) default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`)
) ENGINE=MyISAM AUTO_INCREMENT=24 DEFAULT CHARSET=latin1 AUTO_INCREMENT=24 ;
Et j'ai toujours la même erreur, et lorsque je fais le test avec ce tableau :
Citation:
Array
(
[nom] => dupont
[prenom] => julien
[societe] => fichier
[email] => julien.dupont@hotmail.com
)
Cela fonctionne alors qu'avec ce tableau :

Citation:
Array
(
[0] => Array
(
[nom] => dupont
[prenom] => julien
[societe] => fichier
[email] => julien.dupont@hotmail.com
)

[1] => Array
(
[nom] => Durant
[prenom] => lkuh
[societe] => fichier
[email] => durant@gmail.com
)

)
Cela de fonctionne pas.
nico21000 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/02/2011, 14h33   #8
Membre Expert
 
Avatar de Madfrix
 
Inscription : juin 2007
Messages : 2 278
Détails du profil
Informations personnelles :
Localisation : France, Gironde (Aquitaine)

Informations forums :
Inscription : juin 2007
Messages : 2 278
Points : 2 324
Points : 2 324
Essaies de modifier comme ceci :

Code php :
1
2
3
4
5
 
public function AddEmail($values){
    foreach($values as $value)
        $this->dbInsert('emails', $value);
}
__________________
Je ne réponds pas aux questions envoyées par mp
Madfrix est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/02/2011, 19h52   #9
Invité de passage
 
nicolas gaillard
Inscription : août 2010
Messages : 12
Détails du profil
Informations personnelles :
Nom : nicolas gaillard

Informations forums :
Inscription : août 2010
Messages : 12
Points : 1
Points : 1
Bonjour,

Le problème avec cette méthode c'est que je fais une requête pour chaque email a insérer dans la table et la but de mon application est de faire de l'import à partir d'un fichier .csv qui peux être très volumineux (3000 entrées par exemple donc 3000 requêtes). Je pense que comme ça, ça sera pas optimisé.
Il doit forcément y avoir un moyen de tous envoyer en une requête.
Merci quand même.
nico21000 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/02/2011, 23h05   #10
Membre Expert
 
Avatar de Madfrix
 
Inscription : juin 2007
Messages : 2 278
Détails du profil
Informations personnelles :
Localisation : France, Gironde (Aquitaine)

Informations forums :
Inscription : juin 2007
Messages : 2 278
Points : 2 324
Points : 2 324
teste cela je pense que ca devrait être bon :

Code php :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 
public function dbInsert($table, $values) {
 
	$bound = '';
	$bindParams = array();
	$fieldnames = array_keys($values[0]);
 
    $sql = 'INSERT INTO '. $table;
 
    $fields = '( ' . implode(', ', $fieldnames) . ' )';
 
	foreach($values as $key=>$value) {
		$bound .= ' (';
		foreach($fieldnames as $fieldname) {
			$param = ':' . $fieldname.$key . ', ';
			$bound .= $param;
			$bindParams[] = array('param'=>$param, 'value'=>$value[$fieldname]);
		}
		$bound = substr($bound, 0, -2);
		$bound .= '), ';
	}
 
	$bound = substr($bound, 0, -2);
 
    $sql .= $fields.' VALUES '.$bound;	
 
	$stmt = BDinstance::getInstance()->prepare($sql);
 
	foreach($bindParams as $value)
		$stmt->bindParam($value['param'], $value['value']);
 
	return $stmt->execute($values);
}
__________________
Je ne réponds pas aux questions envoyées par mp
Madfrix est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 09/02/2011, 09h20   #11
Rédacteur/Modérateur
 
Avatar de MaitrePylos
 
Homme Gérard Ernaelsten
DBA & Dev PHP
Inscription : juin 2005
Messages : 3 174
Détails du profil
Informations personnelles :
Nom : Homme Gérard Ernaelsten
Âge : 39
Localisation : Belgique

Informations professionnelles :
Activité : DBA & Dev PHP
Secteur : Service public

Informations forums :
Inscription : juin 2005
Messages : 3 174
Points : 6 460
Points : 6 460
C'est choux blancs et blancs choux, de plus imagine qu'il ne passe pas le même nombres de paramètres dans ses tableaux

le code suivants, va lui poser soucis
Code :
1
2
 
$fieldnames = array_keys($values[0]);
Et cela lui fera quand même 3000 requêtes.
MaitrePylos est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/02/2011, 09h59   #12
Membre Expert
 
Avatar de Madfrix
 
Inscription : juin 2007
Messages : 2 278
Détails du profil
Informations personnelles :
Localisation : France, Gironde (Aquitaine)

Informations forums :
Inscription : juin 2007
Messages : 2 278
Points : 2 324
Points : 2 324
Citation:
Envoyé par MaitrePylos Voir le message
de plus imagine qu'il ne passe pas le même nombres de paramètres dans ses tableaux
Là je suis d'accord, libre à lui de modifier un peu le code pour adapter à ses besoins

Citation:
Envoyé par MaitrePylos Voir le message
Et cela lui fera quand même 3000 requêtes
Là je suis pas d'accord, cela lui fera une seule requête de ce type :

Code sql :
1
2
3
4
5
 
INSERT INTO saTable (C1, C2)
VALUES (val1, val2),
(val3, val4),
(val5, val6)

EDIT: de toute manière s'il ne passe pas le même nombres de paramètres dans ses tableaux, il sera oblié de faire des requêtes d'insertions unitaires donc de passer par la méthode que je lui ai proposé dans le post #8
__________________
Je ne réponds pas aux questions envoyées par mp
Madfrix est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/02/2011, 17h56   #13
Invité de passage
 
nicolas gaillard
Inscription : août 2010
Messages : 12
Détails du profil
Informations personnelles :
Nom : nicolas gaillard

Informations forums :
Inscription : août 2010
Messages : 12
Points : 1
Points : 1
Bonjour et merci pour l'intérêt que vous portez sur mon problème.

Ma requête semble être correcte :

Citation:
INSERT INTO emails( nom, prenom, societe, email ) VALUES (:nom0, :prenom0, :societe0, :email0), (:nom1, :prenom1, :societe1, :email1)
Mais j'ai toujour la même erreur :

Citation:
Exception levée dans l'application.
Message SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens
Fichier /homepages/0/d341517557/htdocs/mailer/application/core/crud.phpLigne 145
voici mon tableau de test :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Array
(
    [0] => Array
        (
            [nom] => nom1
            [prenom] => prenom1
            [societe] => societe1
            [email] => email1@test.fr
        )
 
    [1] => Array
        (
            [nom] => nom2
            [prenom] => prenom2
            [societe] => societe2
            [email] => email2@test.fr
        )
 
)
nico21000 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/02/2011, 19h11   #14
Membre Expert
 
Avatar de Madfrix
 
Inscription : juin 2007
Messages : 2 278
Détails du profil
Informations personnelles :
Localisation : France, Gironde (Aquitaine)

Informations forums :
Inscription : juin 2007
Messages : 2 278
Points : 2 324
Points : 2 324
Bonjour,

écris cela juste avant le dernier foreach de ta fonction et controle si tu as autant de paramètres que de valeurs avec la requête SQL (j'ai pas testé le code que je t'ai proposé) :

Code php :
1
2
3
4
 
echo '<pre>';
print_r($bindParams);
echo '</pre>';
__________________
Je ne réponds pas aux questions envoyées par mp
Madfrix est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/02/2011, 19h27   #15
Invité de passage
 
nicolas gaillard
Inscription : août 2010
Messages : 12
Détails du profil
Informations personnelles :
Nom : nicolas gaillard

Informations forums :
Inscription : août 2010
Messages : 12
Points : 1
Points : 1
Voici le résultat de mon echo :

Citation:
Array
(
[0] => Array
(
[param] => :nom0,
[value] => nom1
)

[1] => Array
(
[param] => :prenom0,
[value] => prenom1
)

[2] => Array
(
[param] => :societe0,
[value] => societe1
)

[3] => Array
(
[param] => :email0,
[value] => email1@test.fr
)

[4] => Array
(
[param] => :nom1,
[value] => nom2
)

[5] => Array
(
[param] => :prenom1,
[value] => prenom2
)

[6] => Array
(
[param] => :societe1,
[value] => societe2
)

[7] => Array
(
[param] => :email1,
[value] => email2@test.fr
)

)
nico21000 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/02/2011, 19h32   #16
Membre Expert
 
Avatar de Madfrix
 
Inscription : juin 2007
Messages : 2 278
Détails du profil
Informations personnelles :
Localisation : France, Gironde (Aquitaine)

Informations forums :
Inscription : juin 2007
Messages : 2 278
Points : 2 324
Points : 2 324
Désolé, j'ai pas corrigé le execute dans la fonction. Mets ceci à la place pour voir :

Code php :
1
2
 
return $stmt->execute();
__________________
Je ne réponds pas aux questions envoyées par mp
Madfrix est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 16/02/2011, 17h18   #17
Invité de passage
 
nicolas gaillard
Inscription : août 2010
Messages : 12
Détails du profil
Informations personnelles :
Nom : nicolas gaillard

Informations forums :
Inscription : août 2010
Messages : 12
Points : 1
Points : 1
Bonjour,

Finalement cela fonctionne avec la fonction de Madfrix un tout petit peu modifiée :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 
public function dbMultiInsert($table, $values) {
		    $bound = '';
		    $bindParams = array();
		    $fieldnames = array_keys($values[0]);   
		    $sql = 'INSERT INTO '. $table;
 
		    $fields = '( ' . implode(', ', $fieldnames) . ' )';
 
		    foreach($values as $key=>$value) {
		        $bound .= ' (';
		        foreach($fieldnames as $fieldname) {
					$param = '"' . $value[$fieldname] . '", ';
		            $bound .= $param;
		            $bindParams[] = array('param'=>$param, 'value'=>$value[$fieldname]);
		        }
		        $bound = substr($bound, 0, -2);
		        $bound .= '), ';
		    }		        
		    $bound = substr($bound, 0, -2);
		    $sql .= $fields.' VALUES '.$bound;  
		    $stmt = BDinstance::getInstance()->prepare($sql);
			foreach($bindParams as $value)
		        $stmt->bindParam($value['param'], $value['value']);
 
			return $stmt->execute();
		}
nico21000 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 08h46.


 
 
 
 
Partenaires

Hébergement Web