Transaction Management and Rollback
INSERT OR IGNORE silently skips an insertion if it would violate a constraint, allowing your program to continue without an error.
A Duplicate That Need Not Crash
Suppose an application receives a username that may already be stored. A normal insertion that violates a constraint raises an error and rejects the operation. That behavior protects the database from invalid data, but it may not match the application's goal. Sometimes the correct response is to reuse the existing record and continue. SQLite's INSERT OR IGNORE directive supports this behavior: if the attempted insertion would violate a constraint, the insertion is silently skipped and the program continues.
INSERT OR IGNORE has two possible outcomes: a valid new row is inserted, or an insertion that would violate a constraint is quietly skipped.
Tracing the Two Outcomes
The important distinction is between the insertion attempt and the final table state. INSERT OR IGNORE does not update an existing row when a conflict occurs. It leaves the attempted row out of the table. If no constraint would be violated, the new row is added normally.
What do you think happens?
A table already contains the unique username sam. What should happen when INSERT OR IGNORE attempts to add sam again?
Reveal answer
Answer: The attempted insertion is skipped and the program continues
The duplicate violates the uniqueness constraint, so INSERT OR IGNORE silently ignores that insertion. The existing row remains.
Why Uniqueness Matters
The duplicate-handling behavior depends on a constraint that can identify a conflict. A UNIQUE constraint restricts duplicate values in one or more columns. If a username column is UNIQUE, two rows cannot have the same username, so attempting to insert an existing username creates a constraint violation that INSERT OR IGNORE can skip.
| Column situation | Attempted duplicate | Result with INSERT OR IGNORE |
|---|---|---|
| A UNIQUE constraint is present | The value violates the constraint | The insertion is skipped |
| No UNIQUE constraint is present | The value is allowed to repeat | The row is inserted, assuming no other constraint is violated |
Finding the Record ID
Skipping a duplicate is useful, but an application often needs the record's primary key afterward. The practical pattern is a two-step sequence: first attempt the insertion with INSERT OR IGNORE, then run SELECT to retrieve the primary key for the unique value. If the value was new, SELECT finds the row just inserted. If the value already existed, SELECT finds that existing row.
INSERT OR IGNORE INTO users (username) VALUES ('sam'); SELECT user_id FROM users WHERE username = 'sam';
The SELECT follow-up is reliable only when the value used in the search is unique. If several rows could share that value, the SELECT would not identify one specific record. This is why the UNIQUE constraint is central to the pattern rather than an optional detail.
Choosing the Pattern Carefully
Use this pattern when the application needs to ensure that a record exists and then use its primary key. User registration, tag or category management, and reference-data linking are examples of workflows where an existing record can be reused or a missing record can be created.
Do not choose this pattern when the application must know whether the insertion actually occurred. INSERT OR IGNORE intentionally hides the constraint-violation error by skipping the insertion. If later logic depends on distinguishing a newly created row from an ignored duplicate, a different approach is needed, such as checking existence before insertion or using a more complex conditional statement.
Assuming every repeated value will be ignored.
INSERT OR IGNORE only skips an insertion when the new row would violate a constraint.
Fix:
Identify the UNIQUE constraint or another relevant constraint before relying on duplicate handling.Using SELECT after INSERT OR IGNORE without a unique lookup value.
The SELECT may not identify one specific record when the value maps to multiple rows.
Fix:
Use a value protected by a UNIQUE constraint when the goal is to retrieve one record's primary key.Treating an ignored insertion as an update.
The conflicting insertion is skipped; INSERT OR IGNORE does not replace the existing row.
Fix:
Use this pattern only when reusing the existing record is the intended behavior.Using INSERT OR IGNORE when the program must report a duplicate.
The pattern is designed to continue without raising an error for the violation.
Fix:
Use an approach that explicitly checks or distinguishes the insertion result.
Apply the Workflow
A tags table stores a tag name under a UNIQUE constraint. The application receives the tag name python, but it does not know whether that tag already exists. Describe the two database actions you would use to ensure the tag exists and obtain its primary key.
Hints
- The first action should attempt the insertion without allowing a duplicate to raise an error.
- The second action should search by the unique tag name and return the tag's primary key.
- Explain why the UNIQUE constraint makes the lookup reliable.
Reusing a tag or creating it
An application needs the primary key for the tag named news, whether news is already stored or must be added.
Attempt the insertion: Use INSERT OR IGNORE with news. A missing tag can be inserted, while an existing tag protected by UNIQUE causes the insertion to be skipped.
Search for the tag: Use SELECT with the unique tag value news to retrieve its primary key.
Use the returned key: The application can use the primary key to link another record to the tag.
The workflow continues with the primary key for the newly inserted or already existing news tag.
Essential Takeaways
- INSERT OR IGNORE silently skips an insertion that would violate a constraint and lets the program continue.
- A successful insertion changes the table; an ignored duplicate leaves the existing table row in place.
- A UNIQUE constraint is what makes duplicate handling meaningful and makes a follow-up SELECT reliable for one primary key.
- The two-step pattern is INSERT OR IGNORE followed by SELECT for workflows that need a record to exist and need its primary key.
- Use another approach when the application must know whether a new row was inserted rather than merely ensuring that a record exists.
Key Takeaways
- INSERT OR IGNORE prevents a constraint violation from interrupting the program by skipping the conflicting insertion.
- Pairing it with SELECT lets an application retrieve the primary key of either a newly created or already existing record.
- The pattern depends on a UNIQUE constraint when duplicate values must map to exactly one row.
- Without a uniqueness constraint, repeated values are normally accepted unless another constraint is violated.
- This approach is best when the application needs a record to exist, not when it must distinguish a new insertion from an ignored duplicate.