UPDATE表记录而不是添加新记录MySQL

时间:2016-05-14 15:05:59

标签: php mysql

好的..这就是事情。我想列出登录的用户并在注销时更改其状态。这很完美。我创建了一个名为tblaudit_users的表。我从tbl_users表中选择的现有用户。

我想要的是,如果用户已经存在于tblaudit_users表中,它将使用NOW()更新LastTimeSeen时间。但它不是更新该记录,而是创建新记录。这种方式表会增长和增长,我想避免这种情况。我用于此的代码如下:

+++++++++++++++++++

$ipaddress = $_SERVER['REMOTE_ADDR'];

if(isset($_SESSION['id'])){

    $userId = $_SESSION['id'];
    $username = $_SESSION['username'];
    $achternaam = $_SESSION['achternaam'];
    $district = $_SESSION['district'];
    $gemeente = $_SESSION['gemeente'];

    $query = $db->prepare("SELECT * FROM tblaudit_users WHERE username = '{$username}' AND active = '1' LIMIT 1");
    $query->execute();

    foreach($query->fetchAll(PDO::FETCH_OBJ) as $value){
        $duplicate = $value->username;  
    }

    if($duplicate != 1){

        $insert = $db->prepare("
                    INSERT INTO tblaudit_users (user_id, username, achternaam, district, gemeente, ipaddress, LastTimeSeen, status)
                    VALUES ('{$userId}', '{$username}', '{$achternaam}', '{$district}', '{$gemeente}', '{$ipaddress}', NOW(), '1')
                    ");
        $insert->execute();

    } elseif($duplicate = 1){

        $update = $db->prepare("UPDATE tblaudit_users SET LastTimeSeen = NOW(),status = '1' WHERE username = '{$username}'");
        $update->execute();

    } else {
        header('Location: index.php');
        die();
    }
}

我迷失并搜索了很多网站/页面以解决这个问题,所以希望有人可以帮助我吗?在此先感谢!!

更新:

我已经尝试了以下但没有结果。

+++++

$insert = $db->prepare("
                    INSERT INTO tblaudit_users (user_id, username, achternaam, district, gemeente, ipaddress, LastTimeSeen, status)
                    VALUES ('{$userId}', '{$username}', '{$achternaam}', '{$district}', '{$gemeente}', '{$ipaddress}', NOW(), '1')
                    ON DUPLICATE KEY UPDATE set LastTimeSeen = NOW(), status = '1'
                    ");
        $insert->execute();

确定。我改变了我的查询和代码:

$query = $db->prepare("SELECT * FROM tblaudit_users WHERE username = '{$username}' LIMIT 1");
$query->execute();

if($query){

    $insert = $db->prepare("
                INSERT INTO tblaudit_users (user_id, username, achternaam, district, gemeente, ipaddress, LastTimeSeen, status)
                VALUES ('{$userId}', '{$username}', '{$achternaam}', '{$district}', '{$gemeente}', '{$ipaddress}', NOW(), '1')
                ON DUPLICATE KEY UPDATE set LastTimeSeen = NOW(), status = '1'
                ");
    $insert->execute();

} else {
    header('Location: index.php');
    die();
}

}

我还添加了一个名为pid(主要ID)的UNIQUE键。仍然没有工作。

3 个答案:

答案 0 :(得分:0)

基于http://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html,请勿在更新语法中使用'set'

页面上的示例:

INSERT INTO table (a,b,c) VALUES (4,5,6) ON DUPLICATE KEY UPDATE c=9;

答案 1 :(得分:0)

几个问题:

  • 您在$query上进行测试,但这是您的语句对象,即使您没有从select语句返回的记录也会有效;
  • 在确保前一个语句已关闭或至少提取其所有记录之前,可能会出现访问第二个预准备语句的问题;
  • insert语句中存在语法错误(set不应存在);
  • 要使insert ... on duplicate key update生效,您提供的值必须包含唯一键;
  • SQL注入漏洞;
  • selectinsert的不必要拆分:这可以在一个声明中完成

您可以使用num_rows()编写测试。要获得正确的计数通话store_result()。最好在发出下一个声明之前关闭声明:

$query = $db->prepare("SELECT * FROM tblaudit_users 
                       WHERE username = '{$username}' LIMIT 1");
$query->execute();
$query->store_result();
if($query->num_rows()){
     $query->close();
     // etc...

但是,当您执行insert ... on duplicate key update时,不需要执行整个查询:无需先使用select检查该用户是否确实存在。这完全由insert ... on duplicate key update声明完成。

INSERT

中的错误

ON DUPLICATE KEY UPDATE的语法后面不应包含SET字样。

防止SQL注入

虽然您使用预准备语句(好!),但您仍然在SQL语句中注入字符串(不好!)。预处理语句的一个优点是,您可以使用bind_param()

来查询查询的参数,而无需将字符串实际注入SQL字符串中。
$insert = $db->prepare("
    INSERT INTO tblaudit_users (user_id, username, achternaam, district, 
                                gemeente, ipaddress, LastTimeSeen, status)
    VALUES (?, ?, ?, ?, ?, ?, NOW(), '1')
    ON DUPLICATE KEY UPDATE LastTimeSeen = NOW(), status = '1'
    ");
$insert->bind_param("ssssss", $userId, $username, $achternaam, 
                              $district, $gemeente, $ipaddress);
$insert->execute();

这样可以避免SQL injection

确保user_id中的tblaudit_users具有唯一约束。将另一个(auto_increment)字段作为主键没有帮助。它必须是您为其插入值的字段之一。

上述代码不再使用$query。你不需要它。

答案 2 :(得分:-1)

我发现了问题

if(isset($_SESSION['id'])){

    $userId = $_SESSION['id'];
    $username = $_SESSION['username'];
    $achternaam = $_SESSION['achternaam'];
    $district = $_SESSION['district'];
    $gemeente = $_SESSION['gemeente'];

    $query = $db->prepare("SELECT * FROM tblaudit_users WHERE user_id = '{$userId}' LIMIT 1");
    $query->execute();

    if($query->rowcount()<1){

      $insert = $db->prepare("
                  INSERT INTO tblaudit_users (user_id, username, achternaam, district, gemeente, ipaddress, LastTimeSeen, status)
                  VALUES ('{$userId}', '{$username}', '{$achternaam}', '{$district}', '{$gemeente}', '{$ipaddress}', NOW(), '1')
                  ");
      $insert->execute();

    } elseif($query->rowcount()>0) {

        $update = $db->prepare("UPDATE tblaudit_users SET LastTimeSeen = NOW(),status = '1' WHERE user_id = '{$userId}'");
        $update->execute(); 

    } else {
        header('Location: index.php');
        die();
    }
}

我没有在查询中使用$ username,而是选择$ userId并且它可以工作。