Php 重复更新时的复合键——删除用户id与输入的用户id不同的行

Php 重复更新时的复合键——删除用户id与输入的用户id不同的行,php,mysql,sql,Php,Mysql,Sql,我有一个包含两列的表,它们一起构成了一个复合键。这是表格: CREATE TABLE `teachers_subjects` ( `subject_id` int(11) NOT NULL, `users_user_id` int(11) NOT NULL, UNIQUE KEY `subject_user_id` (`subject_id`,`users_user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 我曾经有一个第三列,它是一个额外的主键,

我有一个包含两列的表,它们一起构成了一个复合键。这是表格:

CREATE TABLE `teachers_subjects` (
`subject_id` int(11) NOT NULL,
`users_user_id` int(11) NOT NULL,
 UNIQUE KEY `subject_user_id` (`subject_id`,`users_user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
我曾经有一个第三列,它是一个额外的主键,在重复的行上,一切正常。但第三个专栏并没有真正起到任何作用(除了把我从这个问题中解救出来),所以我放弃了它。这是我的PHP函数/SQL查询:

public function update_or_insert_rows($table, $data) {

    # Build the fields string. Ex: (person_id,first_name,email)
    # And the duplicate key update string. Ex: first_name=VALUES(first_name),email=VALUES(email)
    # We do this by using the indexes on the first row of data
    # NOTE: The index of the data array has to start at 0 in order for this to work
        $fields = ""; 
        $dup    = "";
        foreach($data[0] as $index => $value) {
            $fields .= $index.",";
            $dup    .= $index."=VALUES(".$index."),";
        }

        # Remove last comma
        $fields = substr($fields, 0, -1);
        $dup = substr($dup, 0, -1);

    # Build the data string. Ex: (1,'Ethel','ethel@aol.com'),(3,'Leroy','leroy@hotmail.com'),(3,'Francis','francis@gmail.com')
        $values = "";
        foreach($data as $row) {

            $values .= "(";
            foreach($row as $value) {
                $values .= "'".$this->connection->real_escape_string($value)."',";
            }
            $values = substr($values, 0, -1);
            $values .= "),";
        }
        # Remove last comma
        $values = substr($values, 0, -1);

    # Put it all together   
        $sql = "INSERT INTO ".$table." (".$fields.") 
                VALUES ".$values."
                ON DUPLICATE KEY UPDATE ".$dup;

    # Run it
        $run = $this->query($sql);
        return $this->connection->affected_rows;    
}
INSERT INTO teachers_subjects (users_user_id,subject_id) VALUES ('98','12') ON DUPLICATE KEY UPDATE users_user_id=VALUES(users_user_id),subject_id=VALUES(subject_id)
现在,当我向表中添加数据时,它会删除所有具有userid的行,而不是与我添加行的当前用户的userid。这是有意义的,因为为了让函数工作,我需要有一个唯一的第三列,在传递给表的数据中包括该列

我可以把这个索引加回去,但我想知道是否有更好的解决方案

更新:转储的SQL查询:

public function update_or_insert_rows($table, $data) {

    # Build the fields string. Ex: (person_id,first_name,email)
    # And the duplicate key update string. Ex: first_name=VALUES(first_name),email=VALUES(email)
    # We do this by using the indexes on the first row of data
    # NOTE: The index of the data array has to start at 0 in order for this to work
        $fields = ""; 
        $dup    = "";
        foreach($data[0] as $index => $value) {
            $fields .= $index.",";
            $dup    .= $index."=VALUES(".$index."),";
        }

        # Remove last comma
        $fields = substr($fields, 0, -1);
        $dup = substr($dup, 0, -1);

    # Build the data string. Ex: (1,'Ethel','ethel@aol.com'),(3,'Leroy','leroy@hotmail.com'),(3,'Francis','francis@gmail.com')
        $values = "";
        foreach($data as $row) {

            $values .= "(";
            foreach($row as $value) {
                $values .= "'".$this->connection->real_escape_string($value)."',";
            }
            $values = substr($values, 0, -1);
            $values .= "),";
        }
        # Remove last comma
        $values = substr($values, 0, -1);

    # Put it all together   
        $sql = "INSERT INTO ".$table." (".$fields.") 
                VALUES ".$values."
                ON DUPLICATE KEY UPDATE ".$dup;

    # Run it
        $run = $this->query($sql);
        return $this->connection->affected_rows;    
}
INSERT INTO teachers_subjects (users_user_id,subject_id) VALUES ('98','12') ON DUPLICATE KEY UPDATE users_user_id=VALUES(users_user_id),subject_id=VALUES(subject_id)
更新2:问题不在这个SQL查询中,而是在SQL delete from查询中,我删除了以前选中的框现在未选中的行。仍然不知道为什么要删除其他用户行,但它位于以下代码中的某个位置:

// delete those subjects that have not been checked
    foreach($_POST['subject_on_page_id'] as $subject_on_page_id) {
        if(!in_array($subject_on_page_id, $_POST['subject_id'])){
            DB::instance(DB_NAME)->delete('teachers_subjects', "WHERE subject_id = ".$subject_on_page_id);
        }
    }

这段代码的工作原理是根据隐藏字段构建的数组检查复选框。

这非常简单,实际上与我的INSERT SQL查询无关。这是我的SQL DELETE查询,它只是缺少WHERE子句的第二部分,该子句指定了当前登录的用户:

&& users_user_id = ".$this->user->user_id

我从来没有注意到这个问题,直到我对网站的其他一些看起来相关的部分做了重大更改之后,我才错误地将错误归咎于此。我在分别测试了单独的SQL语句后解决了这个问题,以前这两个语句都是由一个提交按钮执行的。吸取教训!转储您的SQL语句并分别运行它们,以查看它们是如何工作的

对于查询中的
$fields
,需要指定唯一索引中的所有字段。请给出一个示例查询,
$sql
是通过在运行时转储该值生成的,并将其添加到问题中。@gillyspy刚刚添加了sql查询这是一个非常奇怪的
重复键
元组集。他们不处理冲突。当您得到一个重复的密钥时,您希望发生什么?也许您想将
替换为
语句?@gillyspy关于冲突,我想忽略该行,而不是删除它,就像当前发生的那样。该SQL不删除行。你在别的地方做的。