我必须进行查询,在 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;
}
如果“空”,绘图的 ID 可以是 -1,或者具有从 savePlot 函数中获取的 ID
我知道困惑的部分是第一个“值”:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?, X = ?, Z = ?, name = ?, owner = ?, helpers = ?, denied = ?, biome = ?) ' at line 2
有人可以解释一下我可以用什么代替吗?
编辑:按要求显示创建表
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
最佳答案
我想你想要更像这样的东西:
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)
被声明为唯一的(你如何识别重复项)。您只指定要在发生碰撞时更改名称,但这会设置所有值(如您的版本)。
关于php - 带有内部选择的复杂 SQL 插入更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45130286/