我想在PHP中运行类似的更新
// pseudocode
UPDATE invoice SET due_date=? WHERE invoice_id=? AND creater_id=?;
IF AFFECTED_ROWS == 1 THEN
UPDATE invoice_item SET price=? WHERE invoice_id=?
为了增加安全性,我附加了creater_id以确保代码仅在登录用户是发票创建者时才更新,否则系统将不会更新。
我最初打算使用AFFECTED_ROWS检查此情况。但最终经过多次挫折之后,我意识到如果所有新值与旧值相同,AFFECTED_ROWS将返回0。这意味着即使我对invoice_item有不同的值,也不会更新它们。
除了在UPDATE之前执行SELECT之外,是否有SQL查询或PHP函数会告诉我UPDATE是否匹配任何行,以便我可以相应地更新invoice_item?
答案 0 :(得分:1)
您可以使用ROW_COUNT(),如果您读到它,它会解释当连接到数据库时,您可以指定CLIENT_FOUND_ROWS标志,该标志将给出为更新找到的行数,无论它们是否具有相同的值您正在更新的内容。
希望这有帮助。
答案 1 :(得分:0)
我从我的代码中取得了这个,所以像$ link这样的东西需要到位 - 但它显示了你感兴趣的东西
function update() {
$q = "UPDATE table SET field1=? WHERE field2 = $value";
/* create a prepared statement */
$stmt = mysqli_stmt_init($link);
if (mysqli_stmt_prepare($stmt, $q)) {
mysqli_stmt_bind_param($stmt, "s", $field1);
mysqli_stmt_execute($stmt);
if(mysqli_stmt_errno($stmt)){
echo("Sql Error: ".$q. ' Sql error #: '.mysqli_stmt_errno($stmt). ' - ' . mysqli_stmt_error($stmt);
return false;
}
else{
$numrows = mysqli_stmt_affected_rows($stmt);
if (mysqli_stmt_errno($stmt) == 0 || mysqli_stmt_errno($stmt) ==''){
// numrows = -1 is flag no error and no rows affected
$numrows = ($numrows ==0?-1:$numrows);
}
else{
echo("Sql Error: ".$q. ' Sql error #: '.mysqli_stmt_errno($stmt). ' - ' . mysqli_stmt_error($stmt);
return false;
}
/* close statement */
mysqli_stmt_close($stmt);
return $numrows;
}
}
}
答案 2 :(得分:0)
根据ROW_COUNT()
上的文档:
ROW_COUNT()
返回上一个语句更改,删除或插入的行数(如果它是UPDATE
,DELETE
或INSERT
。对于其他陈述,该值可能没有意义。
您的查询:
除了在UPDATE之前执行SELECT之外,是否有SQL查询或PHP函数会告诉我UPDATE是否匹配任何行
您还可以在ROW_COUNT()
或任何其他UPDATE
或DDL
声明中使用DML
。
示例:使用您的伪代码:
// pseudocode
UPDATE invoice SET due_date=? WHERE invoice_id=? AND creater_id=?;
IF ( ROW_COUNT() >= 1 ) THEN
UPDATE invoice_item SET price=? WHERE invoice_id=?
END IF;
否则,您可以尝试:
UPDATE invoice SET due_date=? WHERE invoice_id=? AND creater_id=?;
UPDATE invoice_item SET price=
(case when ( row_count() >= 1 ) then ? else price end)
WHERE invoice_id=?;
在设置参数值之前,再次检查row_count()
值以决定是否为1个或更多参数设置值。
答案 3 :(得分:0)
您可以将其恢复为1个查询,而不用担心受影响的行:
UPDATE
invoice
left join invoice_item on invoice_item.invoice_id = invoice.invoice_id
SET
invoice.due_date = ?, -- the WHERE will only let this happen if it will be changed
invoice_item.price = ? -- the WHERE will only let this happen if it will be changed
WHERE
invoice.invoice_id = ?
and invoice.creater_id = ?
and invoice.due_date != ? -- here compare the new due_date to the one already in the db