我必须进行查询,在1行中插入或更新。
编辑:我在这里添加 WORKING SQL查询。
$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);"
);
理论上我想在准备好的MySQL语句中使用相同的东西
目前这个烂摊子看起来像这样:
$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);"
);
如你所见,非常混乱。
这就是数据库的样子:
所以从理论上讲,如果用户执行 savePlot 功能,会替换几个字段,就像您在PHP代码中看到的那样。的" sqlSavePlot"是我上面显示的查询
对于一些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;
}
如果&#34;空&#34;或者具有从savePlot函数获取的ID,则情节的id可以是-1
我知道混乱的部分是围绕第一个&#34;值&#34;:
您的SQL语法有错误;检查手册 对应于您的MySQL服务器版本,以便使用正确的语法 接近&#39;?,X =?,Z = ?, name = ?, owner = ?, helpers = ?, denied = ?, 生物群落=?) &#39;在第2行
有人可以解释一下我可以放的东西吗?
编辑:根据要求,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
答案 0 :(得分:0)
我想你想要更像这样的东西:
INSERT INTO plots (`id`, `level`, `X`, `Z`, `name`, `owner`, `helpers`, `denied`, `biome`)
SELECT id, p.level, p.X, p.Z, ?, ?, ?, ?
FROM plots p
WHERE p.level = ? AND X = ? AND Z = ?
ON DUPLICATE KEY
UPDATE name = VALUES(name),
owner = VALUES(owner),
helpers = VALUES(helpers),
denied = VALUES(denied),
biome = VALUES(biome);
你需要注意参数的顺序。我猜测id
是主键,(X, Z, level)
被声明为唯一(如何识别重复项)。您只指定要在发生冲突时更改名称,但这会设置所有值(如您的版本)。
答案 1 :(得分:0)
原来我甚至有一个合乎逻辑的问题..我混淆了&#34; saveByID&#34;和&#34; saveByXZ&#34; ..
public function savePlot(Plot $plot): bool{
$this->db->ping();
$helpers = implode(',', $plot->helpers);
$denied = implode(',', $plot->denied);
if ($plot->id >= 0){
$stmt = $this->sqlSavePlotById;
$stmt->bind_param('isiisssss', $plot->id, $plot->levelName, $plot->X, $plot->Z, $plot->name, $plot->owner, $helpers, $denied, $plot->biome);
} else{
$stmt = $this->sqlSavePlot;
$stmt->bind_param('siisiisssss', $plot->levelName, $plot->X, $plot->Z, $plot->levelName, $plot->X, $plot->Z, $plot->name, $plot->owner, $helpers, $denied, $plot->biome);
}
$result = $stmt->execute();
$this->lastSave = time();
if ($result === false){
$this->plugin->getLogger()->error($stmt->error);
return false;
}
$this->cachePlot($plot);
return true;
}
修正后的查询:
$this->sqlSavePlot = $this->db->prepare(
"INSERT INTO plots (`id`, `level`, `X`, `Z`, `name`, `owner`, `helpers`, `denied`, `biome`)
VALUES((SELECT id
FROM plots p
WHERE p.level = ? AND X = ? AND Z = ?),?,?,?,?,?,?,?,?)
ON DUPLICATE KEY
UPDATE name = VALUES(name),
owner = VALUES(owner),
helpers = VALUES(helpers),
denied = VALUES(denied),
biome = VALUES(biome);"
);
$this->sqlSavePlotById = $this->db->prepare(
"UPDATE plots SET id = ?, level = ?, X = ?, Z = ?, name = ?, owner = ?, helpers = ?, denied = ?, biome = ? WHERE id = VALUES(id);"
);
非常感谢大家!希望这有助于将来的其他人!