2024 日本 PHP 研討會

mysqli::$affected_rows

mysqli_affected_rows

(PHP 5, PHP 7, PHP 8)

mysqli::$affected_rows -- mysqli_affected_rows取得前一次 MySQL 操作影響的資料列數目

說明

物件導向風格

程序式風格

mysqli_affected_rows(mysqli $mysql): int|string

回傳最後一個 INSERTUPDATEREPLACEDELETE 查詢所影響的資料列數。對於 SELECT 陳述式,其作用方式類似於 mysqli_num_rows()

參數

mysql

僅限程序式風格:由 mysqli_connect()mysqli_init() 回傳的 mysqli 物件。

回傳值

大於零的整數表示受影響或擷取的資料列數。零表示 UPDATE 陳述式沒有更新任何記錄,查詢中的 WHERE 子句沒有符合任何資料列,或者尚未執行任何查詢。-1 表示查詢回傳錯誤,或針對未緩衝的 SELECT 查詢呼叫了 mysqli_affected_rows()

注意事項:

如果受影響的資料列數大於最大整數值 (PHP_INT_MAX),則受影響的資料列數將以字串形式回傳。

範例

範例 #1 $mysqli->affected_rows 範例

物件導向風格

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");

/* 插入資料列 */
$mysqli->query("CREATE TABLE Language SELECT * from CountryLanguage");
printf("受影響的資料列數 (新增): %d\n", $mysqli->affected_rows);

$mysqli->query("ALTER TABLE Language ADD Status int default 0");

/* 更新資料列 */
$mysqli->query("UPDATE Language SET Status=1 WHERE Percentage > 50");
printf("受影響的資料列數 (更新): %d\n", $mysqli->affected_rows);

/* 刪除資料列 */
$mysqli->query("DELETE FROM Language WHERE Percentage < 50");
printf("受影響的資料列數 (刪除): %d\n", $mysqli->affected_rows);

/* 查詢所有資料列 */
$result = $mysqli->query("SELECT CountryCode FROM Language");
printf("受影響的資料列數 (查詢): %d\n", $mysqli->affected_rows);

/* 刪除 Language 表格 */
$mysqli->query("DROP TABLE Language");

程序式風格

<?php

mysqli_report
(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* 插入資料列 */
mysqli_query($link, "CREATE TABLE Language SELECT * from CountryLanguage");
printf("受影響的資料列數 (新增): %d\n", mysqli_affected_rows($link));

mysqli_query($link, "ALTER TABLE Language ADD Status int default 0");

/* 更新資料列 */
mysqli_query($link, "UPDATE Language SET Status=1 WHERE Percentage > 50");
printf("受影響的資料列數 (更新): %d\n", mysqli_affected_rows($link));

/* 刪除資料列 */
mysqli_query($link, "DELETE FROM Language WHERE Percentage < 50");
printf("受影響的資料列數 (刪除): %d\n", mysqli_affected_rows($link));

/* 查詢所有資料列 */
$result = mysqli_query($link, "SELECT CountryCode FROM Language");
printf("受影響的資料列數 (查詢): %d\n", mysqli_affected_rows($link));

/* 刪除 Language 資料表 */
mysqli_query($link, "DROP TABLE Language");

以上範例會輸出

Affected rows (INSERT): 984
Affected rows (UPDATE): 168
Affected rows (DELETE): 815
Affected rows (SELECT): 169

另請參閱

新增筆記

使用者貢獻的筆記 3 則筆記

匿名
13 年前
在 "INSERT INTO ON DUPLICATE KEY UPDATE" 查詢中,雖然有人可能預期 affected_rows 在成功的查詢中每列只會返回 0 或 1,但實際上它可能會返回 2。

來自 MySQL 手冊:「使用 ON DUPLICATE KEY UPDATE,如果該列作為新列插入,則每列的 affected-rows 值為 1,如果更新現有列,則為 2。」

參見:https://mysqldev.dev.org.tw/doc/refman/5.0/en/insert-on-duplicate.html

以下是 _每列_ 的總和細分
+0:列未被更新或插入(可能是因為該列已存在,但在 UPDATE 期間實際上沒有欄位值被更改)
+1:插入了一列
+2:更新了一列
Jacques Amar
7 年前
使用預備語句時,即使沒有結果集(例如在 UPDATE 或 DELETE 中),您仍然需要在 affected_rows 返回實際數字之前儲存結果

<?php
$del_stmt
->execute();
$del_stmt->store_result();
$count = $del_stmt->affected_rows;
?>

否則事情會變得令人沮喪..
Michael
10 年前
如果您需要明確知道 UPDATE 操作的 WHERE 條件是否未能匹配任何列,或者只是沒有列需要更新,您需要改為檢查 mysqli::$info。

由於這會返回一個需要解析的字串,您可以使用以下方法將結果轉換為關聯陣列。

物件導向風格

<?php
preg_match_all
('/(\S[^:]+): (\d+)/', $mysqli->info, $matches);
$info = array_combine ($matches[1], $matches[2]);
?>

程序式風格

<?php
preg_match_all
('/(\S[^:]+): (\d+)/', mysqli_info ($link), $matches);
$info = array_combine ($matches[1], $matches[2]);
?>

然後您可以使用該陣列來測試不同的條件

<?php
if ($info ['Rows matched'] == 0) {
echo
"這個操作沒有匹配任何資料列。\n";
} elseif (
$info ['Changed'] == 0) {
echo
"這個操作匹配了資料列,但沒有任何資料列需要更新。\n";
}

if (
$info ['Changed'] < $info ['Rows matched']) {
echo (
$info ['Rows matched'] - $info ['Changed'])." 個資料列匹配但未被更改。\n";
}
?>

這種方法適用於任何 mysqli::$info 支援的查詢 (INSERT INTO、LOAD DATA、ALTER TABLE 和 UPDATE),對於其他任何查詢,它會返回一個空陣列。

對於任何 UPDATE 操作,返回的陣列將包含以下元素

陣列
(
[匹配的資料列數] => 1
[已更改的資料列數] => 0
[警告數量] => 0
)
To Top