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


Better way to check if row exist update else insert new record

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

<?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和audit_no是否存在,然后更新旧记录并插入到markrecord_update_details;否则插入新记录。

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

最好的方法是插入重复的密钥更新。

第一个查询的解释。

/* 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注入!

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';

行应具有标记=优秀和修改日期=2015-11-26。

p.S3。如果它插入了重复的行,那么添加唯一密钥时会出现问题。查看SHOW CREATE TABLE audit_action_markrecord。(感谢Barmar)。

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

仅当audit_section_markrecord已更新(未插入)时,才希望更新markrecord_update_details

检查两列(form_details_subquestion_idaudit_section_no)组合所需的更新。

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

我建议你推迟学习"更简单的方式"来做工作。添加数据转义以防止sql注入并放松。

附言:当你准备好的时候,谷歌"mysql触发器更新","唯一密钥"answers"重复密钥更新"(我前面的例子有一些基础)。

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