$DBH = new PDO($dsn, $username, $password, $opt);
$DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$DBH->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$STH = $DBH->prepare("INSERT INTO requests (id,imdbid,msg) VALUES ('',:imdbid,:msg)");
$STH->bindParam(':imdbid', $_POST['imdbid']);
$STH->bindParam(':msg', $_POST['msg']);
$STH->execute();
echo "<p>Successfully Requested ".$_POST['imdbid']."! Thanks!</p>";
是否有一些SQL Query会检查和插入或者是什么? 我需要它来检查用户输入的内容是否已经存在于数据库中,因此如果用户键入已经存在的imdbid,那么它将不会继续插入任何内容。我该怎么做?我知道我可以做一个fetch_all并为它做一个foreach但是只有在你执行之后才能工作吗?
答案 0 :(得分:5)
最好在列上设置约束以防止重复数据,而不是检查和插入。
只需在imdbid
上设置UNIQUE约束:
ALTER TABLE `requests` ADD UNIQUE `imdbid_unique`(`imdbid`);
这样做的原因是您不会遇到race condition。
在完成检查和实际插入数据之间有一个小窗口,在那个小窗口中,可能会插入与待插入数据冲突的数据。
解决方案?使用约束并检查$DBH->error()
是否存在插入错误。如果有任何错误,您知道存在重复,然后您可以通知您的用户。
我注意到您正在使用此$DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
。在这种情况下,您无需检查->error()
,因为PDO将抛出异常。只需用try尝试包装你的执行,然后像这样抓住:
$duplicate = false;
try {
$STH->execute();
} catch (Exception $e) {
echo "<p>Failed to Request ".$_POST['imdbid']."!</p>";
$duplicate = true;
}
if (!$duplicate)
echo "<p>Successfully Requested ".$_POST['imdbid']."! Thanks!</p>";
答案 1 :(得分:2)
只需在插入之前运行查询。
如果发现死于剧本:
$DBH = new PDO($dsn, $username, $password, $opt);
$DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$DBH->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$sql = 'SELECT COUNT(*) from requests WHERE imdbid = :imdbid';
$stmt = $DBH->prepare($sql);
$stmt->execute(array(':imdbid' => $_POST['imdbid']));
if($stmt->fetchColumn()){ die('Already exist');}
$STH = $DBH->prepare("INSERT INTO requests (id,imdbid,msg) VALUES ('',:imdbid,:msg)");
$STH->bindParam(':imdbid', $_POST['imdbid']);
$STH->bindParam(':msg', $_POST['msg']);
$STH->execute();
echo "<p>Successfully Requested ".$_POST['imdbid']."! Thanks!</p>";
或者使msg
字段唯一。
使用存储过程:
DELIMITER //
CREATE PROCEDURE insert_request_msg(IN `p_imbd`, IN `p_msg`)
IF NOT EXISTS (SELECT COUNT(*) from requests WHERE imdbid = p_imbd)
BEGIN
INSERT INTO requests (id,imdbid,msg) VALUES ('',p_imbd,p_msg)
END
END IF; //
DELIMITER ;
您可以在一个查询中调用它:
$STH = $DBH->prepare('
call insert_request_msg(:imdbid,:msg)
');
$STH->bindParam(':imdbid', $_POST['imdbid']);
$STH->bindParam(':msg', $_POST['msg']);
答案 2 :(得分:1)
试试这个
$DBH = new PDO($dsn, $username, $password, $opt);
$DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$DBH->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$STH = $DBH->prepare("INSERT INTO requests (id,imdbid,msg) VALUES ('',:imdbid,:msg) WHERE NOT EXISTS(SELECT imdbid FROM requests WHERE imdbid =:imdbid)");
$STH->bindParam(':imdbid', $_POST['imdbid']);
$STH->bindParam(':msg', $_POST['msg']);
$STH->execute();
echo "<p>Successfully Requested ".$_POST['imdbid']."! Thanks!</p>";