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不删除行。你在别的地方做的。