LoginSignup
10
16

More than 1 year has passed since last update.

【MySQL】UPDATE・DELETE・INSERT実行後に処理件数を取得する方法

Last updated at Posted at 2022-03-14

UPDATE・DELETE・INSERT実行後に出力されるQuery OK, 1 row affectedの件数を取得する方法です。

mysql> UPDATE animals SET name = 'cat' WHERE name = 'lion';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

SQLとPHP、2種類の方法を説明します。

SQLで取得する

ROW_COUNT()関数で取得できます。
必ずステートメント(UPDATE、DELETE、INSERTなどの実行単位)の完了直後に実行してください。

ROW_COUNT()の使い方

SELECT ROW_COUNT();を実行します。

-- UPDATE
mysql> UPDATE animals SET name = 'dog' WHERE name = 'wolf';
Query OK, 7 rows affected (0.00 sec)
Rows matched: 7  Changed: 7  Warnings: 0

mysql> SELECT ROW_COUNT();
+-------------+
| ROW_COUNT() |
+-------------+
|           7 |
+-------------+
1 row in set (0.00 sec)

-- DELETE 
mysql> DELETE FROM animals WHERE id = 3;
Query OK, 1 row affected (0.00 sec)

mysql> SELECT ROW_COUNT();
+-------------+
| ROW_COUNT() |
+-------------+
|           1 |
+-------------+
1 row in set (0.00 sec)

-- INSERT
mysql> INSERT INTO animals (name) VALUES('dog'), ('cat'), ('rabbit');
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> SELECT ROW_COUNT();
+-------------+
| ROW_COUNT() |
+-------------+
|           3 |
+-------------+
1 row in set (0.00 sec)

ROW_COUNT()とは

  • MySQLの情報関数
  • 直前のステートメントで影響を受けた行数を返す
  • UPDATE・DELETE・INSERTの直後は変更、削除、または挿入された行数を返す
  • ステートメントの実行直後に呼び出すことができる

以下、MySQL公式マニュアルからの引用です。

ROW_COUNT()

ROW_COUNT() は、mysql_affected_rows() C API 関数から取得される値と同様で、ステートメントの実行後に mysql クライアントに表示される行数です。

mysql_affected_rows()

mysql_affected_rows() は、mysql_query() または mysql_real_query() によるステートメントの実行直後に呼び出すことができます。それは、最後のステートメントが UPDATE、DELETE、または INSERT であった場合に、それによって変更、削除、または挿入された行数を返します。SELECT ステートメントの場合、mysql_affected_rows() は mysql_num_rows() のように動作します。

events_statements_current テーブル

ROWS_AFFECTED
ステートメントに影響を受けた行数。「影響を受けた」の意味については、セクション23.7.7.1「mysql_affected_rows()」を参照してください。

ROW_COUNT()はAPIのmysql_affected_rows()やステートメントイベントを格納するテーブルevents_statements_currentROWS_AFFECTEDカラムの値と同じです。

PHPで取得する

PDOクラスとmysqliクラスを利用します。
PHP公式マニュアル: どのAPIを使うか

PDOクラス

PDOクラスのexec()は戻り値が処理件数です。
PHP公式マニュアル: PDO::exec

pdo_test1.php
$dbh = new PDO($dsn, $user, $password);
$count = $dbh->exec("INSERT INTO animals (name) VALUES('rabbit'), ('wolf')");

echo $count; # 2を返す

rowCount()でステートメントの実行直後に処理件数を取得することもできます。
PHP公式マニュアル: PDOStatement::rowCount

pdo_test2.php
$dbh = new PDO($dsn, $user, $password);
$del = $dbh->prepare("INSERT INTO animals (name) VALUES('rabbit'), ('wolf')");
$del->execute();
$count = $del->rowCount();

echo $count; # 2を返す

mysqliクラス

mysqliクラスはステートメントの実行直後にaffected_rowsプロパティから処理件数を取得できます。

PHP公式マニュアル: mysqli::$affected_rows

mysqli_test.php
$mysqli = new mysqli($host, $user, $password, $database);
$result = $mysqli->query("INSERT INTO animals (name) VALUES('rabbit'), ('wolf')");
$count = $mysqli->affected_rows;

echo $count; # 2を返す

他のRDMSでは使えるのか

MySQL以外のRDMSにもROW_COUNT()に相当する機能は存在しますが、RDMS毎に仕様が異なるようです。
公式マニュアルで仕様を確認した後で利用しましょう。

PHP公式マニュアル: PDOStatement::rowCountでも説明されています。

関連する PDOStatement によって実行された直近の SQL ステートメントが SELECT 文の場合、いくつかのデータベースは文によって返された 行数を返すかも知れません。しかしながら、 この振る舞いは全てのデータベースで保証されていません。 さまざまな場所で使用するアプリケーションでは、 これに頼ってはいけません。

このメソッドは SQLite ドライバの場合はあらゆる場合に "0" (ゼロ) を返します。 PostgreSQL ドライバの場合は ステートメント属性 PDO::ATTR_CURSOR の設定が PDO::CURSOR_SCROLL の場合にだけ "0" (ゼロ) を返します。

まとめ

多くのORMはSQL実行メソッドの戻り値=処理件数なので、利用機会は少なさそう。

採用PR

弊社で一緒に働く仲間を募集しています。
全てのオタクを幸せにしたい方、是非ご覧ください!

10
16
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
16