1

我想在 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 是否匹配任何行,以便我可以相应地继续 UPDATE invoice_item?

4

4 回答 4

1

您可以使用ROW_COUNT()并且如果您读到它解释说,当连接到数据库时,您可以指定 CLIENT_FOUND_ROWS 标志,该标志将给出为更新找到的行数,无论它们是否具有与您相同的值更新。

希望这可以帮助。

于 2014-03-21T05:47:58.477 回答
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;
        }
    }
}   
于 2014-03-21T05:46:02.723 回答
0

根据文档ROW_COUNT()

ROW_COUNT()如果是 、 或 ,则返回最后一条语句更改、删除或插入的UPDATEDELETEINSERT。对于其他语句,该值可能没有意义。

您的查询:

除了在 UPDATE 之前执行 SELECT 之外,是否有 SQL 查询或 PHP 函数会告诉我 UPDATE 是否匹配任何行

您也可以ROW_COUNT()在一个UPDATE或任何其他DDLDML语句中使用。

示例:使用您的伪代码:

// 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 个或多个参数设置值。

于 2014-03-21T06:12:19.110 回答
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
于 2014-03-21T06:14:58.557 回答