更好的方法来检查行是否存在更新,否则插入新记录

时间:2015-11-26 02:00:45

标签: php mysql

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

<?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;否则插入新记录。

我不知道如何使用最容易编写的代码。我只是试着从这次旅程中学习。

3 个答案:

答案 0 :(得分:2)

最好的方式是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';

P.S。转义数据以阻止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 )。

答案 1 :(得分:1)

另一种方法是使用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') ";

答案 2 :(得分:1)

@Andrew,似乎我理解你的需求。

您只有在markrecord_update_details更新(未插入)时才更新audit_section_markrecord

您需要检查两列组合所需的更新:form_details_subquestion_idaudit_section_no

似乎你的代码工作正常。使用它,不要复杂化。

我建议你推迟“更容易”的工作方式。添加数据转义以防止sql注入和放松。

P.S。当你准备好了,google“mysql触发更新”,“唯一密钥”和“重复密钥更新”(我的上一个例子有一些基础)。