The .changes
dot command in SQLite is a helpful utility for developers working with databases, especially when tracking the number of rows affected by SQL statements like INSERT
, UPDATE
or DELETE
.
When used in the SQLite command-line interface, .changes
toggles an option that shows the count of modified rows after executing a command.
This article looks at how the .changes
command works, how it can be enabled or disabled, and provides an example to illustrate how it works.
What is the .changes
Command?
In SQLite, the .changes
command is a toggle that, when enabled, displays the number of rows affected by the most recent SQL command. It also displays the total number of rows that have been modified in the current connection.
This can be particularly useful for tracking the impact of modifications on the database and ensuring that operations are affecting the intended records. The .changes
command is specific to the SQLite command-line shell and is not an SQL statement itself—it is a “dot command,” used solely within SQLite’s interactive shell environment.
Purpose and Use Cases for .changes
The .changes
command can be used to:
- Verify Updates and Deletions: It can help to confirm that the correct number of rows have been updated or deleted. For example, if an
UPDATE
command is supposed to modify five records but.changes
shows a different number, it signals that something might have gone wrong. - Monitor Insertions: When inserting data, especially with bulk operations, the
.changes
command can provide quick feedback on how many rows were successfully inserted. - Debugging and Validation: For debugging purposes,
.changes
can be helpful when testing SQL commands and scripts, as it quickly provides feedback on the number of rows impacted.
How to Use the .changes
Command
The .changes
command works as a toggle switch within the SQLite command-line interface. When enabled, the number of affected rows from the most recent INSERT
, UPDATE
, or DELETE
operation is displayed whenever a query is run. This includes subsequent queries that don’t affect data (such as SELECT
statements). For these queries that don’t change data, .changes
simply repeats the numbers from the most recent operation that changed rows.
Executing .changes ON
enables this command, while .changes OFF
disables it.
Syntax
.changes [ON | OFF]
If no parameter is provided, the .changes
command shows its usage (i.e. Usage: .changes on|off
).
Enabling and Disabling .changes
To enable .changes
, simply type:
.changes ON
To disable .changes
so that the number of rows affected is no longer displayed, use:
.changes OFF
Once enabled, SQLite will display the number of rows impacted by any subsequent INSERT
, UPDATE
, or DELETE
commands until it is disabled again.
Example of Using .changes
Let’s look at an example that illustrates the use of .changes
. Assume we have a table named employees
and we insert four rows:
-- Create table
CREATE TABLE employees (
id INTEGER PRIMARY KEY,
name TEXT,
position TEXT,
salary REAL
);
-- Insert data
INSERT INTO employees (name, position, salary) VALUES ('Bryce', 'Manager', 75000);
INSERT INTO employees (name, position, salary) VALUES ('Ally', 'Developer', 65000);
INSERT INTO employees (name, position, salary) VALUES ('Sasha', 'Designer', 60000);
INSERT INTO employees (name, position, salary) VALUES ('Hesham', 'Designer', 55000);
Step 1: Enable .changes
First, we enable the .changes
command:
.changes ON
Step 2: Execute an Update Statement
Next, we run an UPDATE
statement to modify the salary of employees with the position “Developer”:
UPDATE employees SET salary = salary * 1.10 WHERE position = 'Designer';
Here’s the output I got on my system:
changes: 2 total_changes: 143
This output tells us that two rows were affected by the UPDATE
statement, meaning two employees with the position “Designer” had their salary updated. The total_changes
reflects how many rows have been changed in my current connection. So if I change one more row, it will display 144, and so on.
Step 3: Execute a Delete Statement
Suppose we want to delete all employees whose salary is below 65000:
DELETE FROM employees WHERE salary < 65000;
Output:
changes: 1 total_changes: 144
This output tells us that one row was deleted from the table. We can also see that total_changes
has incremented to 144 as expected.
Step 4: Run a Read-Only Query
The output of .changes
persists, even on queries that don’t change data. On such queries, it simply maintains the value based on the most recently changed rows.
We can run the following query to illustrate this:
SELECT * FROM employees;
Output:
+----+-------+-----------+---------+
| id | name | position | salary |
+----+-------+-----------+---------+
| 1 | Bryce | Manager | 75000.0 |
| 2 | Ally | Developer | 65000.0 |
| 3 | Sasha | Designer | 66000.0 |
+----+-------+-----------+---------+
changes: 1 total_changes: 144
We can see that the .changes
output is appended to the query results. The query didn’t change any rows, so .changes
maintained the output from the previous statement that changed rows (which in our case, was our DELETE
example above).
Step 5: Disable .changes
If we no longer want to display the row count after each operation, we can disable .changes
with:
.changes OFF
From this point onward, SQLite will stop showing the affected row count data.
Notes
Here are a few things to remember when using the .changes
command:
- Only Available in the SQLite CLI: The
.changes
command is specific to the SQLite CLI and will not work within SQL queries or scripts outside of the command-line shell. - Similar to
changes()
Function: SQLite also provides achanges()
SQL function, which returns the number of rows modified by the lastINSERT
,UPDATE
, orDELETE
statement. However,changes()
can be used in SQL queries, whereas.changes
is purely for command-line toggling. - Session-Based: The
.changes
command only applies to the active SQLite session and does not persist across different SQLite shell sessions.