Php 更新重复密钥时出错
你能告诉我我做错了什么吗 我有一个功能,可以在数据库中添加用户id、属性id和用户输入的答案在此之前,它可以工作。但当我添加重复密钥更新部分以更新用户答案而不是创建新答案时,它会抛出一个错误: 致命错误:未捕获错误:在第39行的……\Attributes.php中对布尔值调用成员函数execute() 在那一行我有$add_user->execute() 下面添加了插入数据库的函数。如果我删除了“重复更新”部分,它将插入数据库,并且一切正常,但我需要,如果用户已经回答了,它将更新现有部分,而不是在数据库中插入新数据:Php 更新重复密钥时出错,php,mysql,Php,Mysql,你能告诉我我做错了什么吗 我有一个功能,可以在数据库中添加用户id、属性id和用户输入的答案在此之前,它可以工作。但当我添加重复密钥更新部分以更新用户答案而不是创建新答案时,它会抛出一个错误: 致命错误:未捕获错误:在第39行的……\Attributes.php中对布尔值调用成员函数execute() 在那一行我有$add_user->execute() 下面添加了插入数据库的函数。如果我删除了“重复更新”部分,它将插入数据库,并且一切正常,但我需要,如果用户已经回答了,它将更新现有部分,而不是
public function updateAttributes($attribute_id, $attribute_text) {
$dbobj = new Connection();
$connection = $dbobj->getConnection();
$user_id = $_SESSION['id'];
$_attribute_id = mysqli_real_escape_string($connection, $attribute_id);
$attribute = mysqli_real_escape_string($connection, $attribute_text);
$add_user = $connection->prepare("INSERT into user_answers(user_id, attribute_id, answer) VALUES ('$user_id', '$_attribute_id', '$attribute') ON DUPLICATE KEY UPDATE answer = VALUES(answer) WHERE user_id = VALUES(user_id) AND attribute_id = VALUES(attribute_id)");
//$add_user->bind_param('iis', $user_id, $_attribute_id, $attribute);
// ON DUPLICATE KEY UPDATE user_answer = VALUES(answer) WHERE user_id = VALUES(user_id) AND attribute_id = VALUES(attribute_id)
$add_user->execute();
$add_user->close();
$connection->close();
}
如果需要,这里是sql代码。包含两个外键和答案,用于存储用户输入的答案:
CREATE TABLE IF NOT EXISTS `user_answers` (
`user_id` int(11) DEFAULT NULL,
`attribute_id` int(11) DEFAULT NULL,
`answer` varchar(50) DEFAULT NULL,
KEY `user_id` (`user_id`),
KEY `attribute_id` (`attribute_id`),
CONSTRAINT `attribute_id` FOREIGN KEY (`attribute_id`) REFERENCES `attributes` (`id`),
CONSTRAINT `user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
更新:添加了连接类:
class Connection {
public function getConnection(){
$conn = mysqli_connect("localhost","root","","dbname") or die("Couldn't connect");
$conn->query("SET NAMES utf8");
return $conn;
}
}
编辑
更新代码后,我遇到了以下问题:
下面添加了插入数据库的函数。如果我删除了“重复更新”部分,它将插入数据库,并且一切正常,但我需要,如果用户已经回答了,它将更新现有部分,而不是在数据库中插入新数据:
public function updateAttributes($attribute_id, $attribute_text) {
$dbobj = new Connection();
$connection = $dbobj->getConnection();
$user_id = $_SESSION['id'];
$_attribute_id = mysqli_real_escape_string($connection, $attribute_id);
$attribute = mysqli_real_escape_string($connection, $attribute_text);
$add_user = $connection->prepare("INSERT into user_answers(user_id, attribute_id, answer) VALUES ('$user_id', '$_attribute_id', '$attribute') ON DUPLICATE KEY UPDATE answer = VALUES(answer) WHERE user_id = VALUES(user_id) AND attribute_id = VALUES(attribute_id)");
//$add_user->bind_param('iis', $user_id, $_attribute_id, $attribute);
// ON DUPLICATE KEY UPDATE user_answer = VALUES(answer) WHERE user_id = VALUES(user_id) AND attribute_id = VALUES(attribute_id)
$add_user->execute();
$add_user->close();
$connection->close();
}
公共函数updateAttributes($attribute\u id,$attribute\u text){
$dbobj=新连接();
$connection=$dbobj->getConnection()
}该错误是由准备失败引起的,因为重复密钥更新上的
子句不应包含WHERE
子句。要更新的行已经定义为要插入的数据与现有键匹配,因此WHERE
子句是多余的。尝试将代码更改为:
$add_user = $connection->prepare("INSERT into user_answers(user_id, attribute_id, answer) VALUES ('$user_id', '$_attribute_id', '$attribute') ON DUPLICATE KEY UPDATE answer = VALUES(answer)");
您正在字符串中注入变量,这违背了准备SQL语句的目的。。。你正在让你的应用程序对SQL注入攻击敞开大门
$add_user = $connection->prepare("INSERT into user_answers(user_id, attribute_id, answer)
VALUES ('$user_id', '$_attribute_id', '$attribute')
--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-- this is is plain wrong
ON DUPLICATE KEY UPDATE answer = VALUES(answer)
WHERE user_id = VALUES(user_id) AND attribute_id = VALUES(attribute_id)");
准备过程可能会失败,从而导致返回false
如果数据库服务器无法成功准备语句,PDO::prepare()将返回FALSE或发出PDOException(取决于错误处理)
请按你应该做的准备
$add_user = $connection->prepare("INSERT into user_answers(user_id, attribute_id, answer) VALUES (:user_id, :attribute_id, :attribute) ON DUPLICATE KEY UPDATE answer = VALUES(answer) WHERE user_id = VALUES(user_id) AND attribute_id = VALUES(attribute_id)");
// Inject the variables you want in the prepared statement.
$result = $add_user->execute([
':user_id' => $user_id,
':attribute_id' => $_attribute_id,
':attribute' => $attribute,
]);
也正如他在沟里指出的那样
现在,对于重复密钥问题。数据库如何识别哪个键是主键?现在定义了两个关键点。这就是为什么必须定义主键。在执行此语句之前,可能必须截断表或删除重复项
ALTER TABLE user_answers ADD PRIMARY KEY (user_id);
连接的邮政编码
类<代码>$connection->prepare()似乎返回boolean@MehravishTemkar你在说什么?@Tschallacka更新了密码。它仍然在数据库中创建新数据,而不是更新。屏幕截图--数据库中应该只有3个数据,而不是6个,它只是每次不断添加新数据,而不是更新…@Mee好吧,现在它工作了,所以根本问题已经解决了。请将新查询添加到问题中。只需编辑它,在一行下添加新的sql语句即可。另外,您是否已将键列设置为主键?否则,数据库引擎无法知道它是主键列,并且不会更新它。在将表设置为主键列之前,您很可能必须截断该表以删除重复值。@Tschallacka无法对您的答案进行投票,但谢谢!这是主要的关键问题。爱你。@Mee现在如果答案对你有帮助,你可以对它进行投票,但如果它解决了你的问题,你可以单击复选标记接受它,你可以这样做。