MySQL / PHP在INSERT之前检查重复

时间:2014-12-23 18:29:53

标签: php mysql

我尝试在执行INSERT语句之前检查MySQL中的现有条目。如果用户输入数据库中已存在的名称(字段设置为唯一),则应提示他们重新输入名称。

我遇到的问题是,如果新条目与任何形式的记录匹配,则会显示错误消息,并且不会发生INSERT。

例如,如果用户输入DUMMY_NEW并且有记录DUMMY_OLD,即使表中不存在DUMMY_NEW,他们也无法添加记录。

我已经搜索过并尝试了其他答案,但似乎无法使其发挥作用。

为清晰起见,删除了无关位的代码:

//Create connection to database using mysqli
$conn = new mysqli($dbhost, $dbuser, $dbpass, $db);

//Set variables according to user input on previous form
$Server_Name = $_POST['Server_Name'];

//Check for duplicate server name - if exists inform user else run INSERT ($stmt)
$checkdup = "SELECT * FROM dcr_table WHERE SERVER_NAME = '".$Server_Name."'";
$dupresult = $conn->query($checkdup);

if($dupresult = 1)
{
        print "<br>Error! <p></p>";
        echo "" . $Server_Name . " already exists in the DCR";
        print "<p></p>Please check the Server Name and try again";
}
else {


//Define the INSERT statement
    $stmt = "INSERT INTO dcr_master (Server_Name, Description,..., ... , ... )";

//Execute the INSERT statement
    $conn->query($stmt);

//Success and return new id
    echo "<br><p></p>Record Added!<p></p>";
    echo "New id: " . mysqli_insert_id($conn);

//Drop the connection
    $conn->close();
};

编辑: 我很清楚注射漏洞。 MySQL帐户只对表有SELECT,INSERT和UPDATE权限。最终用户必须提供密码或提交将失败。这是一款小型应用,目前用户访问受限。在解决当前问题后,将实现MySQL转义字符串。

编辑2: 使用Hobo Sapiens方法确实可以报告现有条目,但仍会在表中添加新的(空)行。记录ID仍然自动递增,所以我得到的是id#300 - 记录,id#301 - 空白,id#302 - 记录。这是INSERT语句中IGNORE的结果吗?

3 个答案:

答案 0 :(得分:3)

如果两个人同时尝试创建相同的ame并且您没有正确处理余量,则代码会产生竞争条件。

如果您已将SERVER_NAME列设置为UNIQUE,则在执行INSERT之前无需检查是否存在服务器名称,因为MySQL会为您执行此操作。在执行查询后,使用INSERT IGNORE广告检查受影响的行数,以确定其是否有效:

//Create connection to database using mysqli
$conn = new mysqli($dbhost, $dbuser, $dbpass, $db);

//Set variables according to user input on previous form
$Server_Name = $_POST['Server_Name'];

//Define the INSERT statement with IGNORE keyword
    $stmt = "INSERT IGNORE INTO dcr_master (Server_Name, Description,..., ... , ... )";
    if ($conn->query($stmt) === false) {
        die("Database error:".$conn->error);
    }

// Check for success
    if ($conn->affected_rows == 0) {
        print "<br>Error! <p></p>";
        echo "" . $Server_Name . " already exists in the DCR";
        print "<p></p>Please check the Server Name and try again";
    } else {

//Success and return new id
        echo "<br><p></p>Record Added!<p></p>";
        echo "New id: " . $conn->insert_id;
    }

这是原子操作,因此没有竞争条件,只涉及对数据库的一次调用。

我建议您使用OOP样式 mysqli_*()的程序样式,但不要混用它们。有关SQL注入的常见警告适用。

答案 1 :(得分:1)

使用mysqli_num_rows

$row_cnt = $dupresult->num_rows;

if ($row_cnt > 0) {

   echo "There is a matching record";

}else {

   //insert into table

}

答案 2 :(得分:0)

本声明:

if($dupresult = 1)

将始终返回1.您应首先检索第一个查询结果(如果有),如下所示:

$row=$dupresult->fetch_array(MYSQLI_NUM);

然后将结果与NULL进行比较:

if(!$row)