如果行存在,写入查询的最佳方法是更新否则插入新记录?我正在尝试下面列出的垃圾代码:
<?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;否则插入新记录。
我不知道如何使用最容易编写的代码。我只是试着从这次旅程中学习。
答案 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_id
和audit_section_no
。
似乎你的代码工作正常。使用它,不要复杂化。
我建议你推迟“更容易”的工作方式。添加数据转义以防止sql注入和放松。
P.S。当你准备好了,google“mysql触发更新”,“唯一密钥”和“重复密钥更新”(我的上一个例子有一些基础)。