Je dois faire une requête, qui insère-ou-met à jour en 1 ligne.Insertion SQL compliquée-mise à jour avec sélection interne
EDIT: J'ajoute le WORKING requête SQL ici.
$this->sqlSavePlot = $this->db->prepare(
"INSERT OR REPLACE INTO plots (id, level, X, Z, name, owner, helpers, denied, biome) VALUES
((select id from plots where level = :level AND X = :X AND Z = :Z),
:level, :X, :Z, :name, :owner, :helpers, :denied, :biome);"
);
Théoriquement je veux la même chose dans les états MySQL préparés
Actuellement le désordre ressemble à ceci:
$this->sqlSavePlot = $this->db->prepare(
"INSERT INTO plots (`id`, `level`, `X`, `Z`, `name`, `owner`, `helpers`, `denied`, `biome`)
VALUES(id = (SELECT id FROM plots WHERE level = level AND X = VALUES(X) AND Z = VALUES(Z)), level = ?, X = ?, Z = ?, name = ?, owner = ?, helpers = ?, denied = ?, biome = ?)
ON DUPLICATE KEY UPDATE
id = VALUES(id),
level = VALUES(level),
X = VALUES(X),
Z = VALUES(Z),
name = VALUES(name),
owner = VALUES(owner),
helpers = VALUES(helpers),
denied = VALUES(denied),
biome = VALUES(biome);"
);
Comme vous le voyez, assez chaotique.
Voici comment la base de données ressemble à:
Donc, en théorie, si l'utilisateur exécute la fonction savePlot, plusieurs champs sont remplacés, comme vous pouvez le voir dans le code PHP . « sqlSavePlot » est la requête que j'ai montré
Pour une explication plus profonde du code PHP:
public function savePlot(Plot $plot): bool{
print "------------------------------------------------------".PHP_EOL;
$this->db->ping();
$helpers = implode(',', $plot->helpers);
$denied = implode(',', $plot->denied);
if ($plot->id <= 0){
$stmt = $this->sqlSavePlot;
$stmt->bind_param('siisssss', $plot->levelName, $plot->X, $plot->Z, $plot->name, $plot->owner, $helpers, $denied, $plot->biome);
} else{
$stmt = $this->sqlSavePlotById;
$stmt->bind_param('isiisssss', $plot->id, $plot->levelName, $plot->X, $plot->Z, $plot->name, $plot->owner, $helpers, $denied, $plot->biome);
}
$result = $stmt->execute();
var_dump($stmt);
var_dump($result);
var_dump($plot);
$this->lastSave = time();
if ($result === false){
$this->plugin->getLogger()->error($stmt->error);
return false;
}
$this->cachePlot($plot);
return true;
}
si « vide » id d'un terrain peut être soit -1, ou avoir une carte d'identité qui est tiré par les cheveux de la fonction savePlot
Je sais que la partie foiré est autour des premiers « valeurs »:
Vous avez une erreur dans votre syntaxe SQL; vérifier le manuel que correspond à votre version du serveur MySQL pour la bonne syntaxe à utiliser près de??, X =?, Z =?, nom =?, propriétaire =?, helpers =?, refusé =?, biome =?) 'à la ligne 2
Quelqu'un pourrait-il m'expliquer ce que je pourrais mettre à la place?
EDIT: comme l'a demandé, SHOW CREATE TABLE
CREATE TABLE `plots` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`level` text COLLATE utf8_unicode_ci,
`X` int(11) DEFAULT NULL,
`Z` int(11) DEFAULT NULL,
`name` text COLLATE utf8_unicode_ci,
`owner` text COLLATE utf8_unicode_ci,
`helpers` text COLLATE utf8_unicode_ci,
`denied` text COLLATE utf8_unicode_ci,
`biome` text COLLATE utf8_unicode_ci,
PRIMARY KEY (`id`),
KEY `XZ` (`X`,`Z`)
) ENGINE=InnoDB AUTO_INCREMENT=3609 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
S'il vous plaît ajouter des informations de 'SHOW CREATE TABLE parcelles». Expliquez aussi ce que vous essayez de faire. Une requête qui ne fonctionne pas ne peut pas le faire pour vous. –
Ajouté comme demandé – thebigsmileXD