【问题标题】:Better way to check if row exist update else insert new record检查行是否存在更新的更好方法,否则插入新记录
【发布时间】:2016-02-29 00:10:59
【问题描述】:

如果行存在更新其他插入新记录,编写查询的最佳方法是什么?我正在尝试下面列出的垃圾代码:

<?php
for ($i = 0; $i < ($_POST['count']); $i++) {
    $form_details_subquestion_id = $_POST['form_details_subquestion_id'][$i];
    $form_details_section_id = $_POST['form_details_section_id'][$i];
    $mark = $_POST['mark'][$i];
    $remark = $_POST['remark'][$i];

    $result = $db->query("
        SELECT * 
        FROM audit_section_markrecord 
        WHERE 
          form_details_subquestion_id = $form_details_subquestion_id AND 
          audit_section_no = $audit_no
    ");
    if ($result->num_rows == 1) {
        $query2 = "
            UPDATE audit_section_markrecord 
            SET 
                mark = '$mark', 
                dateofmodify = '$date' 
            WHERE 
              form_details_subquestion_id = '$form_details_subquestion_id' AND 
              audit_section_no = '$audit_no'
        ";
        $result2 = $db->query($query2);

        $query3 = "
            INSERT INTO markrecord_update_details (
                audit_section_no,
                form_details_subquestion_id, 
                form_details_section_id, 
                mark,
                userlog,
                ipaddress
            ) VALUES (
                '$audit_no', 
                '$form_details_subquestion_id', 
                '$form_details_section_id', 
                '$mark', 
                '$user_staff', 
                '$ip'
            )
        ";
        $result3 = $db->query($query3);
    } else if ($result->num_rows == 0) {
        $query4 = "
            INSERT INTO audit_section_markrecord (
                audit_section_no,
                form_details_subquestion_id, 
                form_details_section_id, 
                mark
            ) VALUES (
                '$audit_no', 
                '$form_details_subquestion_id', 
                '$form_details_section_id', 
                '$mark'
            ) 
        ";
        $result4 = $db->query($query4);
    } else {
        echo "<script>alert('Error. Please contact IT support.')</script>";
        echo "<script language='javascript'>window.location.href='index.php'</script>";
    }
}

上面的代码是在for循环里面写的。我尝试获取 form_details_subquestion_id AND audit_no 是否存在,然后更新旧记录并插入到 markrecord_update_details;否则插入新记录。

我不知道怎么用最容易写的代码。我只是想从这段旅程中学习。

【问题讨论】:

  • 最好的方法是使用insert . . . on duplicate key update。但是,很难说出如何将其应用于您的代码。
  • IMO ,此时您不应专注于查询语句。只要您更新/插入正确的数据..您必须专注于保护您的数据..

标签: php mysql


【解决方案1】:

@Andrew,看来我已经了解您的需求了。

只有在 audit_section_markrecord 已更新(未插入)时,您才想更新 markrecord_update_details。

您检查两列组合所需的更新:form_details_subquestion_id 和 audit_section_no。

看来您的代码运行良好。使用它,不要使事情复杂化。

我建议你推迟倾向于“更轻松”的工作方式。添加数据转义以防止sql注入并放松。

附:当你准备好时,谷歌“mysql triggers on update”、“unique key”和“on duplicate key update”(我的上一个例子有一些基础)。

【讨论】:

    【解决方案2】:

    另一种方法是使用REPLACE 语句。它就像INSERT 语句一样工作,但是当它尝试插入记录时,如果存在具有相同键的记录,则删除旧记录并插入新记录。由于您不是根据以前的值进行更新,因此这可能更容易工作。

    用户需要DELETE 权限才能正常工作。

    例子:

    $query4 = "REPLACE INTO `audit_section_markrecord` (audit_section_no,form_details_subquestion_id, form_details_section_id, mark) VALUES 
        ('$audit_no', '$form_details_subquestion_id', '$form_details_section_id', '$mark') ";
    

    【讨论】:

      【解决方案3】:

      最好的方法是insert on duplicate key update。

      第一次查询的解释。

      /* execute this directly in MySQL to add unique key constraint*/
      ALTER TABLE audit_section_markrecord
      ADD UNIQUE(form_details_subquestion_id, audit_section_no);
      
      /* this query is for calling from php */
      INSERT INTO audit_section_markrecord
      SET
        /* try to insert value */
        mark = '$mark', 
        dateofmodify = '$date',
        form_details_subquestion_id = '$form_details_subquestion_id',
        audit_section_no = '$audit_no'
      
      /* if constraint check fails, i.e. */
      /* there is a row with this form_details_subquestion_id and audit_section_no */
      /* then just update mark and dateofmodify */
      ON DUPLICATE KEY UPDATE
        mark = '$mark', 
        dateofmodify = '$date';
      

      附:转义您的数据以防止sql-injection!

      P.S2。要检查它是否有效,请在 MySQL 中运行 2 个查询:

      INSERT INTO audit_section_markrecord
      SET
        mark = 'good', 
        dateofmodify = '2015-11-10',
        form_details_subquestion_id = 10,
        audit_section_no = 23;
      
      INSERT INTO audit_section_markrecord
      SET
        mark = 'good', 
        dateofmodify = '2015-11-10',
        form_details_subquestion_id = 10,
        audit_section_no = 23
      ON DUPLICATE KEY UPDATE
        mark = 'excellent', 
        dateofmodify = '2015-11-26';
      

      行应该有 mark=excellent 和 dateofmodify=2015-11-26。

      P.S3。如果它正在插入重复的行,则添加唯一键会出现问题。看看 SHOW CREATE TABLE audit_section_markrecord。 (感谢 Barmar)。

      【讨论】:

      • 兄弟,我只是试试代码。但它插入所有记录而不是只插入单个数据。
      • $query = "ALTER TABLE audit_section_markrecord ADD UNIQUE(form_details_subquestion_id, audit_section_no)"; $result = $db->query($query); /* 此查询用于从 php 调用 */ $query1 = "INSERT INTO audit_section_markrecord SET mark = '$mark', dateofmodify = '$date', form_details_subquestion_id = '$form_details_subquestion_id', audit_section_no = '$audit_no' ON DUPLICATE KEY UPDATE标记 = '$mark', dateofmodify = '$date'"; $result1 = $db->query($query1);
      • 直接对mysql运行第一个查询(例如通过控制台或phpmyadmin)。检查错误。检查唯一键实际上已创建。我还没有测试,但声明看起来不错。
      • @Andrew 您不需要在循环中执行ALTER TABLE。它是数据库架构的一部分。
      • @userlond 我直接通过 phpmyadmin 检查:MySQL 返回了一个空结果集(即零行)。 (查询耗时 0.0620 秒)
      猜你喜欢
      • 2016-03-24
      • 2021-09-13
      • 1970-01-01
      • 1970-01-01
      • 2010-12-10
      • 1970-01-01
      • 2015-12-18
      • 2012-10-09
      • 2012-11-12
      相关资源
      最近更新 更多