繁体   English   中英

PHP - 在插入之前检查行是否存在

[英]PHP - Check if row exists before inserting

$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查询将检查和插入或什么? 我需要它来检查用户输入的内容是否已经存在于数据库中,因此如果用户键入已经存在的imdbid,那么它将不会继续插入任何内容。 我该怎么做? 我知道我可以做一个fetch_all并为它做一个foreach但是只有在你执行之后才能工作吗?

最好在列上设置约束以防止重复数据而不是检查和插入。

只需在imdbid上设置UNIQUE约束:

ALTER TABLE `requests` ADD UNIQUE `imdbid_unique`(`imdbid`);

这样做的原因是您不会遇到竞争条件

在完成检查和实际插入数据之间有一个小窗口,在那个小窗口中,可以插入与待插入数据冲突的数据。

解? 使用约束并检查$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>";

只需在插入之前运行查询。

如果发现死于脚本:

$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']);

尝试这个

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

资源

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM