Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【PHP8.x】SQLite3::changes()メソッドの使い方

changesメソッドの使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

changesメソッドは、SQLite3クラスのインスタンスを通じて、直前のデータ操作文(INSERTUPDATEDELETE)によってデータベース内で実際に変更された行の数を取得するメソッドです。このメソッドは、最新のデータ操作がどれだけのレコードに影響を与えたかを確認する際に使用します。

具体的には、INSERT文が実行された場合は挿入された行の数を、UPDATE文が実行された場合は更新された行の数を、DELETE文が実行された場合は削除された行の数を整数値として返します。もし、UPDATE文やDELETE文が特定の条件に基づいて実行され、その条件に合致する行が一つもなかった場合、たとえ構文が正しくても変更された行は0とカウントされます。

このchangesメソッドは、トランザクション内で複数のデータ操作が行われた場合でも、それらの操作によって変更された行の合計数を返します。また、SELECT文のようなデータの参照のみを行う操作や、CREATE TABLEALTER TABLEなどのスキーマ定義文、VACUUMPRAGMAなどの管理コマンドを実行した直後では、常に0を返します。

この機能を利用することで、開発者はデータ操作の成否を検証したり、予期せぬ変更や期待通りの変更が行われたかどうかをプログラム内で確認したりすることが可能になります。例えば、ユーザーからの入力に基づいて特定のレコードを更新した際、実際にその更新が何件のデータに適用されたかを知りたい場合に役立ちます。

構文(syntax)

1<?php
2$db = new SQLite3('my_database.db');
3$db->exec('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)');
4$db->exec('INSERT INTO users (name) VALUES ("Alice")');
5$db->exec('UPDATE users SET name = "Bob" WHERE id = 1');
6$affectedRows = $db->changes();
7$db->close();
8?>

引数(parameters)

引数なし

引数はありません

戻り値(return)

int

SQLite3::changesメソッドは、最後に実行されたINSERT、UPDATE、DELETE操作によって影響を受けた行数を整数で返します。

サンプルコード

PHP SQLite3::changes で変更件数を取得する

1<?php
2
3/**
4 * SQLite3::changes メソッドの使用例を示します。
5 * このメソッドは、直前の INSERT, UPDATE, DELETE 文によって影響を受けた行数を整数値で返します。
6 * データベースへの変更が何件のレコードに影響を与えたかを確認でき、簡単な変更の記録として利用できます。
7 * システムエンジニアを目指す初心者が、データベース操作の変更結果を数値で把握するのに役立ちます。
8 */
9function demonstrateSqliteChangesExample(): void
10{
11    // データベースファイル名
12    $dbFile = 'my_app_data.db';
13    $db = null; // SQLite3 オブジェクトを初期化
14
15    try {
16        // SQLite3 データベースに接続または新規作成
17        // SQLITE3_OPEN_READWRITE: 読み書きモードで開く
18        // SQLITE3_OPEN_CREATE: データベースファイルが存在しない場合は作成する
19        $db = new SQLite3($dbFile, SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE);
20        echo "データベース '$dbFile' に接続しました。\n";
21
22        // 'products' テーブルが存在しない場合、作成するSQLクエリを実行
23        $db->exec('CREATE TABLE IF NOT EXISTS products (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, price REAL)');
24        echo "テーブル 'products' の準備ができました。\n";
25
26        // --- INSERT (挿入) 操作の例 ---
27        // 新しい製品レコードを挿入
28        $db->exec("INSERT INTO products (name, price) VALUES ('ノートパソコン', 120000.00)");
29        // 直前のINSERT文で変更された(挿入された)行数を取得
30        $insertedRows = $db->changes();
31        echo "INSERT操作: $insertedRows 件のレコードが挿入されました。\n"; // 通常、1を返す
32
33        $db->exec("INSERT INTO products (name, price) VALUES ('スマートフォン', 85000.00)");
34        $insertedRows = $db->changes();
35        echo "直後のINSERT操作: $insertedRows 件のレコードが挿入されました。\n"; // 通常、1を返す
36
37        // --- UPDATE (更新) 操作の例 ---
38        // 特定の製品の価格を更新
39        $db->exec("UPDATE products SET price = 115000.00 WHERE name = 'ノートパソコン'");
40        // 直前のUPDATE文で変更された(更新された)行数を取得
41        $updatedRows = $db->changes();
42        echo "UPDATE操作: $updatedRows 件のレコードが更新されました。\n"; // 条件に一致した行数
43
44        // 全ての製品の価格を10%値上げする (複数行を更新する例)
45        $db->exec("UPDATE products SET price = price * 1.1");
46        $updatedAllRows = $db->changes();
47        echo "複数行UPDATE操作: $updatedAllRows 件のレコードが更新されました。\n"; // 全レコード数
48
49        // --- DELETE (削除) 操作の例 ---
50        // 特定の製品レコードを削除
51        $db->exec("DELETE FROM products WHERE name = 'スマートフォン'");
52        // 直前のDELETE文で変更された(削除された)行数を取得
53        $deletedRows = $db->changes();
54        echo "DELETE操作: $deletedRows 件のレコードが削除されました。\n"; // 条件に一致した行数
55
56        // 全ての製品レコードを削除 (データベースをクリーンアップする目的)
57        $db->exec("DELETE FROM products");
58        $deletedAllRows = $db->changes();
59        echo "全レコードDELETE操作: $deletedAllRows 件のレコードが削除されました。\n";
60
61    } catch (Exception $e) {
62        // データベース操作中にエラーが発生した場合
63        echo "エラーが発生しました: " . $e->getMessage() . "\n";
64    } finally {
65        // データベース接続が確立されていれば、必ず閉じる
66        if ($db instanceof SQLite3) {
67            $db->close();
68            echo "データベース接続を閉じました。\n";
69        }
70        // サンプル実行後、データベースファイルを削除する場合は以下のコメントを外してください。
71        // if (file_exists($dbFile)) {
72        //     unlink($dbFile);
73        //     echo "データベースファイル '$dbFile' を削除しました。\n";
74        // }
75    }
76}
77
78// 関数を実行して、SQLite3::changes の動作を確認します。
79demonstrateSqliteChangesExample();

PHPのSQLite3::changesメソッドは、直前に実行されたデータベースのINSERT、UPDATE、またはDELETE文によって、具体的に何件のレコードが影響を受けたかを整数値で確認できる便利な機能です。このメソッドは引数を必要とせず、操作によって変更された行数をint型で返します。

サンプルコードでは、まずmy_app_data.dbというSQLiteデータベースに接続し、「products」テーブルを作成する準備をします。 その後、製品データを挿入するINSERT文を実行すると、changes()は挿入されたレコード数である「1」を返します。 次に、特定の製品の価格を更新するUPDATE文を実行すると、changes()はその更新が影響したレコード数を返します。ここでは単一の更新だけでなく、全ての製品の価格を一括で更新した場合の、複数件の変更数も確認できます。 最後に、特定の製品を削除するDELETE文を実行すると、changes()は削除されたレコード数を返します。例えば、全てのレコードを削除した場合は、その時点の全レコード数が返されます。

このようにSQLite3::changesを使用することで、データベース操作が意図通りに機能したか、どれだけのデータに変更が加えられたかを数値で正確に把握できます。これはシステムエンジニアを目指す初心者にとって、データベースの変更管理やデバッグに非常に役立つでしょう。

SQLite3::changes()メソッドは、直前のINSERT、UPDATE、DELETE文によって影響を受けた行数を整数値で返します。連続したデータベース変更操作を行う場合、このメソッドは常に直後の単一SQL文の結果のみを反映するためご注意ください。データを参照するだけのSELECT文や、データベースに変更がない操作の後では0を返します。データベース操作はエラーが発生しやすいため、サンプルコードのようにtry-catch-finally構文でエラーを適切に処理し、データベース接続を必ず閉じる習慣を身につけましょう。これにより、アプリケーションの安定性とリソース管理が向上します。

PHP 8 SQLite3::changes で変更行数を取得する

1<?php
2
3declare(strict_types=1);
4
5/**
6 * SQLite3::changes メソッドの使用例を示すクラス。
7 * PHP 8 環境での SQLite3 拡張機能の基本的な操作と、
8 * 直前のSQL文で変更された行数を確認する方法を実演します。
9 */
10class SQLite3ChangesExample
11{
12    private string $dbFile;
13    private ?SQLite3 $db = null;
14
15    /**
16     * コンストラクタ。使用するデータベースファイル名を指定します。
17     *
18     * @param string $dbFile データベースファイル名
19     */
20    public function __construct(string $dbFile = 'my_database.db')
21    {
22        $this->dbFile = $dbFile;
23    }
24
25    /**
26     * SQLite3::changes メソッドの動作を示すメインメソッド。
27     * データベースの作成、データの挿入、更新、削除を行い、
28     * 各操作後に変更された行数を表示します。
29     */
30    public function runExample(): void
31    {
32        // 既存のデータベースファイルがあれば削除し、クリーンな状態から開始
33        if (file_exists($this->dbFile)) {
34            unlink($this->dbFile);
35            echo "既存のデータベースファイル '{$this->dbFile}' を削除しました。\n";
36        }
37
38        try {
39            // データベースに接続または新規作成
40            $this->db = new SQLite3($this->dbFile);
41            echo "データベース '{$this->dbFile}' に接続しました。\n";
42
43            // 'users' テーブルを作成(もし存在しなければ)
44            $this->db->exec('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)');
45            echo "テーブル 'users' を作成しました(または既に存在します)。\n";
46
47            // --- INSERT 操作と変更行数の確認 ---
48            // データを挿入
49            $this->db->exec("INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com')");
50            echo "\nユーザー 'Alice' を挿入しました。\n";
51            // 直前のSQL文で変更された行数を取得
52            echo "INSERT後の変更行数: " . $this->db->changes() . "行\n"; // 1行が挿入される
53
54            $this->db->exec("INSERT INTO users (name, email) VALUES ('Bob', 'bob@example.com')");
55            echo "ユーザー 'Bob' を挿入しました。\n";
56            echo "INSERT後の変更行数: " . $this->db->changes() . "行\n"; // 1行が挿入される
57
58            // --- UPDATE 操作と変更行数の確認 ---
59            // データを更新
60            $this->db->exec("UPDATE users SET email = 'alice.smith@example.com' WHERE name = 'Alice'");
61            echo "\nユーザー 'Alice' のメールアドレスを更新しました。\n";
62            // 直前のSQL文で変更された行数を取得
63            echo "UPDATE後の変更行数: " . $this->db->changes() . "行\n"; // 1行が更新される
64
65            // 存在しないデータを更新しようとする場合
66            $this->db->exec("UPDATE users SET email = 'charlie@example.com' WHERE name = 'Charlie'");
67            echo "ユーザー 'Charlie' のメールアドレスを更新しようとしました。\n";
68            echo "UPDATE後の変更行数 (存在しないユーザー): " . $this->db->changes() . "行\n"; // 0行が更新される
69
70            // --- DELETE 操作と変更行数の確認 ---
71            // データを削除
72            $this->db->exec("DELETE FROM users WHERE name = 'Bob'");
73            echo "\nユーザー 'Bob' を削除しました。\n";
74            // 直前のSQL文で変更された行数を取得
75            echo "DELETE後の変更行数: " . $this->db->changes() . "行\n"; // 1行が削除される
76
77            // データベースの現在の状態を確認
78            $results = $this->db->query('SELECT * FROM users');
79            echo "\n現在のユーザーリスト:\n";
80            while ($row = $results->fetchArray(SQLITE3_ASSOC)) {
81                echo "  ID: {$row['id']}, Name: {$row['name']}, Email: {$row['email']}\n";
82            }
83
84        } catch (Exception $e) {
85            // エラーが発生した場合の処理
86            echo "エラーが発生しました: " . $e->getMessage() . "\n";
87        } finally {
88            // データベース接続を閉じる
89            if ($this->db instanceof SQLite3) {
90                $this->db->close();
91                echo "\nデータベース接続を閉じました。\n";
92            }
93            // 例示のためにデータベースファイルは残します。
94            // 完全にクリーンアップする場合は、以下の行のコメントを解除してください。
95            // if (file_exists($this->dbFile)) {
96            //     unlink($this->dbFile);
97            //     echo "データベースファイル '{$this->dbFile}' を削除しました。\n";
98            // }
99        }
100    }
101}
102
103// クラスのインスタンスを作成し、SQLite3::changes メソッドの動作例を実行
104$example = new SQLite3ChangesExample();
105$example->runExample();

PHP 8のSQLite3::changesメソッドは、直前のSQL文(INSERT、UPDATE、DELETEなど)がデータベース内で変更した行数を整数値で取得するためのメソッドです。このメソッドは引数を必要とせず、操作の結果として実際に影響を受けた行数をint型で返します。

システムエンジニアがデータベース操作を行う際、意図した通りのデータが挿入、更新、または削除されたかを確認することは非常に重要です。例えば、UPDATE文を実行した後にこのchanges()メソッドを呼び出すことで、実際に何行のデータが更新されたかを数値で正確に把握できます。これにより、予期せぬ挙動やバグの早期発見に役立てることが可能です。

提供されたサンプルコードでは、まずSQLite3データベースに接続し、テーブル作成後、データの挿入、更新、削除といった操作を順に行っています。それぞれのSQL文を実行した直後に$this->db->changes()を呼び出し、その操作が具体的に何行のデータに影響を与えたかを出力しています。挿入や削除が1行であれば1を、更新によって特定の条件に合致した1行が更新されれば1を返します。もし更新対象のデータが存在しなかった場合など、SQL文がどの行も変更しなかった場合は0を返すため、期待通りのデータ操作が行われたか検証する上で非常に便利なメソッドです。

SQLite3::changes()は、INSERTUPDATEDELETEといった直前のSQL文がデータベースで実際に変更した行数を整数で返します。SELECT文ではデータが変更されないため、このメソッドは常に0を返します。複数のSQL文を連続して実行する場合、changes()直前の1つのSQL文にのみ適用される点にご注意ください。データベース操作では、例外処理(try-catch)と接続の確実なクローズ(close())が非常に重要です。サンプルコードではexec()を使っていますが、SQLインジェクション対策として、実運用ではプリペアドステートメントの使用を強く推奨します。PHP 8では、プロパティや引数に型宣言を適切に用いることで、コードの品質と可読性が向上します。

PHP SQLite3::changes() で変更行数を確認する

1<?php
2
3// データベースファイル名
4// このファイルはスクリプト実行時に存在しない場合、自動的に作成されます。
5$dbFile = 'example.db';
6
7// SQLite3 データベース接続オブジェクトを格納する変数
8$db = null;
9
10try {
11    // SQLite3 データベースに接続します。
12    // 存在しない場合は新しいデータベースファイルが作成されます。
13    $db = new SQLite3($dbFile);
14    echo "データベース '$dbFile' に接続しました。\n";
15
16    // 'users' テーブルが存在しない場合のみ作成します。
17    // id は自動的に増加する主キーとなります。
18    $db->exec('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER)');
19    echo "テーブル 'users' を作成または確認しました。\n";
20
21    echo "--- データ操作と変更行数 (changes()) の確認 ---\n";
22
23    // --- データ挿入の例 ---
24    // 新しいユーザーデータを挿入します。
25    $db->exec("INSERT INTO users (name, age) VALUES ('Alice', 30)");
26    // SQLite3::changes() は、直前の INSERT/UPDATE/DELETE ステートメントによって変更された行数を返します。
27    // この場合、1行挿入されたので1を返します。
28    echo "1. データ挿入後の変更行数: " . $db->changes() . "行\n";
29
30    $db->exec("INSERT INTO users (name, age) VALUES ('Bob', 25)");
31    echo "2. 別のデータ挿入後の変更行数: " . $db->changes() . "行\n";
32
33    // --- データ更新の例 ---
34    // 'Alice' の年齢を更新します。
35    $db->exec("UPDATE users SET age = 31 WHERE name = 'Alice'");
36    // 1行更新されたので1を返します。
37    echo "3. データ更新後の変更行数: " . $db->changes() . "行\n";
38
39    // 存在しないユーザーの年齢を更新しようとします。
40    $db->exec("UPDATE users SET age = 40 WHERE name = 'Charlie'");
41    // WHERE句にマッチする行がないため、何も変更されません。
42    // この場合、changes() は 0 を返します。
43    echo "4. (更新対象がない場合の) 変更行数: " . $db->changes() . "行\n";
44
45    // --- データ削除の例 ---
46    // 'Bob' のデータを削除します。
47    $db->exec("DELETE FROM users WHERE name = 'Bob'");
48    // 1行削除されたので1を返します。
49    echo "5. データ削除後の変更行数: " . $db->changes() . "行\n";
50
51    // 存在しないユーザーのデータを削除しようとします。
52    $db->exec("DELETE FROM users WHERE name = 'David'");
53    // WHERE句にマッチする行がないため、何も変更されません。
54    // この場合、changes() は 0 を返します。
55    echo "6. (削除対象がない場合の) 変更行数: " . $db->changes() . "行\n";
56
57    // --- SELECT 文の実行と changes() の関係 ---
58    // SELECT 文はデータベースのデータを変更しないため、changes() は常に 0 を返します。
59    // changes() は直前のデータ操作言語 (DML: INSERT/UPDATE/DELETE) ステートメントにのみ関連します。
60    $result = $db->query('SELECT * FROM users');
61    echo "7. SELECT 文実行後の変更行数: " . $db->changes() . "行 (SELECT はデータを変更しないため 0)\n";
62    
63    // クエリ結果のリソースを解放します。
64    if ($result) {
65        $result->finalize();
66    }
67
68} catch (Exception $e) {
69    // データベース操作中にエラーが発生した場合、エラーメッセージを表示します。
70    echo "エラーが発生しました: " . $e->getMessage() . "\n";
71} finally {
72    // データベース接続が開いている場合、安全に閉じます。
73    if ($db) {
74        $db->close();
75        echo "データベース接続を閉じました。\n";
76    }
77
78    // 必要であれば、作成されたデータベースファイルを削除することもできます。
79    // 本番環境では注意して使用してください。
80    // if (file_exists($dbFile)) {
81    //     unlink($dbFile);
82    //     echo "データベースファイル '$dbFile' を削除しました。\n";
83    // }
84}

PHP 8で提供されるSQLite3拡張機能のSQLite3::changes()メソッドは、直前に実行されたデータベースのデータ操作文(DMLステートメント)によって、実際に変更された行数を取得するために使用されます。このメソッドは引数を受け取らず、整数値(int)を戻り値として返します。

サンプルコードでは、まずexample.dbというSQLiteデータベースファイルに接続し、usersテーブルを作成しています。その後、様々なデータ操作を行いながらchanges()メソッドの挙動を確認しています。

INSERT文で新しいデータを挿入したり、UPDATE文で既存のデータを更新したり、DELETE文でデータを削除したりした場合、changes()はその操作で変更された行の数を正確に返します。例えば、1行挿入されれば1を、1行更新されれば1を返します。もし指定した条件に合うデータがなく、何も変更されなかった場合は0を返します。

特に注意が必要なのは、データベースからデータを読み出すだけのSELECT文を実行した場合です。SELECT文はデータベースのデータを変更しないため、その後にchanges()メソッドを呼び出しても、常に0が返されます。これは、データが正しく取得されたかどうかとは関係なく、あくまで「データベースの変更行数」を返すためです。この特性を理解することで、「変更が反映されていない」といった誤解を防ぐことができます。

SQLite3::changes()は、INSERTUPDATEDELETEといったデータベースのデータ変更操作の直後に実行してください。このメソッドは、直前のSQLステートメントによって実際に変更された行数を返します。特に注意すべきは、SELECT文のようにデータを変更しないクエリの直後に呼び出すと、常に0を返す点です。これは初心者が誤解しやすいポイントです。また、UPDATEDELETEの条件に合致するデータがなく、結果的に何も変更されなかった場合も0が返されます。この関数を活用することで、実行したSQL操作がデータベースに正しく影響を与えたかを確認できます。

関連コンテンツ

関連プログラミング言語