Page 1 sur 1

INSERT avec jointure

Posté : 21 juin 2021, 09:07
par nestor94
Bonjour,
J'ai un soucis avec la fin de cette requête (la phase INSERT).
$sql = "UPDATE membres SET pos_x = pos_x, pos_y= pos_y+1 WHERE id=:id";
$pdostat = $bdd->prepare($sql);
$pdostat->bindvalue(':id',$id ,PDO::PARAM_INT);
$pdostat->execute();

$sql = "SELECT pos_x, pos_y FROM membres WHERE id=:id";
$pdostat = $bdd->prepare($sql);
$pdostat->bindvalue(':id',$id ,PDO::PARAM_INT);
$pdostat->execute();
$resultat = $pdostat->fetch();    
if (!empty($resultat )) { 
$pos_x = $resultat['pos_x'];
$pos_y = $resultat['pos_y'];
}
$sql =  "INSERT INTO map (pos_x, pos_y)  SELECT ('$pos_x','$pos_y')  FROM membres WHERE id= $id";
$pdostat = $bdd->prepare($sql);
$pdostat->bindvalue(':id',$id ,PDO::PARAM_INT);
$pdostat->execute();
Cardinality violation: 1241 Operand should contain 1 column(s) in C:\wamp64

Re: INSERT avec jointure

Posté : 21 juin 2021, 10:03
par @rthur
Vérifie la syntaxe de INSERT INTO ... SELECT car pour moi ça doit être des noms de colonnes dans le SELECT et non pas des valeurs.

Par ailleurs, si tu utilises une requête préparée alors tu ne devrais pas avoir de variables PHP dans ta requête : ($id, $pos_x, $pos_y) : revérifie la syntaxe pour insérer des variables avec bindvalue(), et profites en pour y passer aussi $pos_x, $pos_y

Re: INSERT avec jointure

Posté : 22 juin 2021, 10:07
par Shadowwera
Je confirme il s'agit bien du nom des colonnes et non des variables : https://www.mysqltutorial.org/mysql-insert-into-select/

Le but du INSERT INTO SELECT est de ne pas avoir besoin d'aller chercher le contenu d'une autre table et de refaire une requête avec ces variables

Re: INSERT avec jointure

Posté : 22 juin 2021, 10:21
par nestor94

$sql =  "INSERT INTO map (pos_x, pos_y)  SELECT (pos_x,pos_y)  FROM membres WHERE id= :id";
$pdostat = $bdd->prepare($sql);
$pdostat->bindvalue(':pos_x',$pos_x ,PDO::PARAM_INT);
$pdostat->bindvalue(':pos_y',$pos_y ,PDO::PARAM_INT);
$pdostat->bindvalue(':id',$id ,PDO::PARAM_INT);

$pdostat->execute();
ne fonctionne pas encore et je ne comprends pas comment faire

Re: INSERT avec jointure

Posté : 22 juin 2021, 10:38
par Shadowwera
ça ne fonctionne pas car tu essaye de faire un bindValue sur :pos_x alors que tu ne la pas mis dans ta requete, idem pour :pos_y

A tu regarder le lien que je tes envoyé ?

Dans ta table membres, tes colonnes s'appellent bien pos_x et pos_y ? idem pour ta table map ?

Re: INSERT avec jointure

Posté : 22 juin 2021, 10:43
par nestor94
Invalid parameter number: number of bound variables does not match number of tokens in C:
$sql =  "INSERT INTO map (pos_x, pos_y)  SELECT (pos_x,pos_y)  FROM membres WHERE id= :id";
$pdostat = $bdd->prepare($sql);
$pdostat->bindvalue('pos_x',$pos_x ,PDO::PARAM_INT);
$pdostat->bindvalue('pos_y',$pos_y ,PDO::PARAM_INT);
$pdostat->bindvalue(':id',$id ,PDO::PARAM_INT);
$pdostat->execute();

Re: INSERT avec jointure

Posté : 22 juin 2021, 10:45
par nestor94
oui, les colonnes portent le meme nom dans les deux tables et oui j'ai regardé ton lien et c'est ce que je ne comprends pas.
si je mets les : avec pos_x et pos_y dans la requete ca ne marche pas non plus.

Re: INSERT avec jointure

Posté : 22 juin 2021, 10:47
par Shadowwera
ça ne fonctionne pas car tu essaye de faire un bindValue sur :pos_x alors que tu ne la pas mis dans ta requete, idem pour :pos_y
Tu n'a pas fait les modifications. Tu as 2 bindValue en trop

Tu doit passer des nom de colonnes, pas des valeurs

INSERT INTO map(pos_x,pos_y) //Le nom de tes colonnes dans la tables map
SELECT
(pos_x,pos_y) //Le nom de tes colonnes dans la tables membres
FROM
membre
WHERE
id = :id;

Re: INSERT avec jointure

Posté : 22 juin 2021, 16:11
par nestor94
Fatal error: Uncaught PDOException: SQLSTATE[21000]: Cardinality violation: 1241 Operand should contain 1 column(s) in C:\wamp64\www\map_maj.php on line 8
( ! ) PDOException: SQLSTATE[21000]: Cardinality violation: 1241 Operand should contain 1 column(s) in C:\wamp64\www\map_maj.php on line 8
<?php
session_start();
require_once 'config.php';
$id = !empty($_SESSION['id']) ? $_SESSION['id'] : NULL;
$sql =  "INSERT INTO map (pos_x, pos_y)  SELECT (pos_x,pos_y)  FROM membres WHERE id= :id";
$pdostat = $bdd->prepare($sql);
$pdostat->bindvalue(':id',$id ,PDO::PARAM_INT);
$pdostat->execute();
?>

Re: INSERT avec jointure

Posté : 22 juin 2021, 16:54
par nestor94
j'ai essayé avec:
$sql = "UPDATE map INNER JOIN  membres ON  membres.pos_x = map.pos_x AND membres.pos_y = map.pos_y
SET  map.pos_x = membres.pos_x, map.pos_y = membres.pos_y WHERE membres.id=$id";
$pdostat = $bdd->prepare($sql);
$pdostat->execute();
mais aucune modif dans la table map.

Re: INSERT avec jointure

Posté : 22 juin 2021, 16:57
par Ryle
Salutations !

Il ne faut pas de parenthèses autour de la liste des colonnes retournées par le select. Il faut commencer par construire une requête de type select valide, que tu pourra ensuite facilement inclure dans ton insert : "SELECT pos_x, pos_y FROM membres WHERE id= :id" :)

Edit : euh... pourquoi ce update ? tes enregistrements existent déjà dans ta table map (auquel cas c'est effectivement un update qu'il faut pour les mettre à jour), ou au contraire tu veux les créer (et dans ce cas, c'est un insert dont tu as besoin)

Re: INSERT avec jointure

Posté : 22 juin 2021, 23:51
par nestor94
Merci Ryle.
<?php
session_start();
require_once 'config.php';
$id = !empty($_SESSION['id']) ? $_SESSION['id'] : NULL;
$sql =  "INSERT INTO map (pos_x, pos_y)  SELECT pos_x,pos_y  FROM membres WHERE id= :id";
$pdostat = $bdd->prepare($sql);
$pdostat->bindvalue(':id',$id ,PDO::PARAM_INT);
$pdostat->execute();
?>