Php 复杂的SQL插入更新和内部选择

Php 复杂的SQL插入更新和内部选择,php,mysql,prepared-statement,Php,Mysql,Prepared Statement,我必须做一个查询,在一行中插入或更新 编辑:我在这里添加工作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 =

我必须做一个查询,在一行中插入或更新

编辑:我在这里添加工作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);"
    );
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);
如你所见,相当混乱

以下是数据库的外观:

因此从理论上讲,如果用户执行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;
}

我想你想要更像这样的东西:

    $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);"
    );
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)
被声明为唯一的(如何识别重复项)。您只指定要在发生冲突时更改名称,但这会设置所有值(与您的版本相同)。

用提供的答案修复了我的查询

结果我甚至有一个逻辑问题。。我把“saveByID”和“saveByXZ”弄混了

固定查询:

    $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);"
    );

非常感谢大家!希望这对以后的人有帮助

请从
显示创建表格图中添加信息
。还要解释你想做什么。一个不工作的查询不能为您做到这一点。添加为请求EDI为我的问题添加了更多信息,例如我想转换为mysql的SQL查询和数据库外观。