在插入数据库表之前检查是否存在相同的行

时间:2016-12-17 13:11:02

标签: mysql sql database insert

我的用户可以相互连接,或者与其他个人资料相关联。该配置文件的所有连接同时进行。

但可能是,用户已经与其他用户的其中一个连接建立了连接。我需要确保在数据库中不会有两个相同的行:

我的查询如下:

if (isset($_POST['crewconnect'])) {

    include '../php/dbconnect.php';

    $connections = $DBcon->query("SELECT connection_id FROM tbl_current_userconnections WHERE user_id=$profileID");
    while($row = $connections->fetch_array()){
        $crewmemberID = $row['connection_id'];

        $DBcon->query("DELETE FROM tbl_former_userconnections WHERE user_id=$activeID AND connection_id=$crewmemberID");
        $DBcon->query("DELETE FROM tbl_former_userconnections WHERE user_id=$crewmemberID AND connection_id=$activeID");

//the following query needs to be changed:
        $DBcon->query("INSERT INTO tbl_current_userconnections(user_id, connection_id) VALUES('$activeID','$crewmemberID'),('$crewmemberID','$activeID')");
    }

    $DBcon->query("INSERT INTO tbl_current_userconnections(user_id, connection_id) VALUES('$activeID','$profileID'),('$profileID','$activeID')");

    $DBcon->close();
}

对于要改变的部分,我想到了类似的东西:

        $DBcon->query("IF (NOT EXISTS(SELECT user_id, connection_id FROM tbl_current_userconnections WHERE user_id=$activeID AND connection_id=$crewmemberID)) INSERT INTO tbl_current_userconnections(user_id, connection_id) VALUES('$activeID','$crewmemberID'),('$crewmemberID','$activeID')");

但是到目前为止这没有用......

2 个答案:

答案 0 :(得分:3)

执行此操作的正确方法是让数据库执行检查。也就是说,让数据库保持数据的完整性。

因此,首先要创建一个唯一索引:

import os
os.environ['ENV1'] = "foo"
os.system("python cool_script.py command line args")

然后,任何插入现有值的尝试都会导致错误。如果您不想要错误,请使用:

create unique index unq_t_userid_connectionid on tbl_current_userconnections(user_id, connection_id);

INSERT INTO tbl_current_userconnections(user_id, connection_id) VALUES ('$activeID', '$crewmemberID'), ('$crewmemberID', '$activeID') ON DUPLICATE KEY UPDATE user_id = VALUES(user_id); 对数据不执行任何操作,但可以防止报告错误。

为什么这样更好?在应用程序中执行检查的问题是两个用户可能会尝试同时创建相同的链接。这可能导致两个用户ON DUPLICATE KEY通过的竞争条件,因此两者都插入数据。这是为什么在数据库中执行逻辑非常重要的一个重要原因。

此外,您应该学会使用参数化查询,而不是将值直接传递给查询语句。您的方法很危险,可能会导致意外的语法错误。

答案 1 :(得分:0)

(user_id, connection_id)上添加唯一索引。然后你可以使用INSERT IGNORE。如果它试图创建一个重复的行,它将只是跳过这些值而不会出错。