I want to update the column of a row if the row already exists, but if it doesn't exist yet then I want to insert a new row.
This type of question is popular for SQL in general
and SQLite in particular
I'm trying to save development time by using the SQLite.swift wrapper for iOS development. I chose this framework because it was recommended on raywenderlich.com. I think it would be useful to have an example of the syntax for an update or insert.
In this answer, Sam Saffron says:
If you are generally doing updates I would ..
- Begin a transaction
- Do the update
- Check the rowcount
- If it is 0 do the insert
- Commit
If you are generally doing inserts I would
- Begin a transaction
- Try an insert
- Check for primary key violation error
- if we got an error do the update
- Commit
This way you avoid the select and you are transactionally sound on Sqlite.
That makes sense to me, so in my answer below I am providing an example of the "generally doing updates".
The data modification clauses in SQLite are INSERT, UPDATE, and DELETE statements. It is used for inserting new rows, updating existing values, or deleting rows from the database.
Configure your Swift project to handle SQLite C calls: Create bridging header file to the project. See the Importing Objective-C into Swift section of the Using Swift with Cocoa and Objective-C. This bridging header should import sqlite3.
Introduction to SQLite UPDATE statement First, specify the table where you want to update after the UPDATE clause. Second, set new value for each column of the table in the SET clause. Third, specify rows to update using a condition in the WHERE clause. The WHERE clause is optional.
In this example, the user dictionary stores words that are typed on a custom keyboard. If the word is already in the dictionary, then that word's frequency count is incremented by 1. But if the word hasn't been entered before, then a new row is inserted with a default frequency of 1.
The table was created with the following schema:
let userDictionary = Table("user_dictionary")
let wordId = Expression<Int64>("id")
let word = Expression<String>("word")
let frequency = Expression<Int64>("frequency")
// ...
let _ = try db.run( userDictionary.create(ifNotExists: true) {t in
t.column(wordId, primaryKey: true)
t.column(word, unique: true)
t.column(frequency, defaultValue: 1)
})
Taken from the question, this is what we want to do:
- Begin a transaction
- Do the update
- Check the rowcount
- If it is 0 do the insert
- Commit
Here is how the code would look.
let wordToUpdate = "hello"
// ...
// 1. wrap everything in a transaction
try db.transaction {
// scope the update statement (any row in the word column that equals "hello")
let filteredTable = userDictionary.filter(word == wordToUpdate)
// 2. try to update
if try db.run(filteredTable.update(frequency += 1)) > 0 { // 3. check the rowcount
print("updated word frequency")
} else { // update returned 0 because there was no match
// 4. insert the word
let rowid = try db.run(userDictionary.insert(word <- wordToUpdate))
print("inserted id: \(rowid)")
}
} // 5. if successful, transaction is commited
See the SQLite.swift documentation for more help.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With