2016-09-01 3 views
0

に応じて、SQLiteのテーブルを挿入または更新する私はこのようなSQLiteのテーブルを持っている:は、ID

CREATE TABLE test (id int PRIMARY KEY, Name text, Country text, ..., ...) 

私は列の値がidを除き、変更することができ、このテーブルのデータを取得しています。だから、特定のidがない場合は挿入したいが、新しい値でそのidのレコードを更新したい。

私はこれを試してみました: - 罰金である -

INSERT OR IGNORE INTO test (id, Name, ..., ...) VALUES (?,?, ....)" 

これは、重複id'sを作成しませんが、それは、レコードの残りの部分を更新しないのいずれかidはすでにテーブルに存在する場合。

idにはSELECTを使用しないようにして、それが存在するかどうかを確認してから、それに応じて更新または挿入してください。

答えて

1

INSERT OR REPLACEを試してみることもできます。これは最初に行を挿入しようとし、idと競合する場合は、古い行を削除してもう一度挿入を試みます。

INSERT OR REPLACEは、 "upsert"操作ごとに行のすべてのフィールドを指定する必要があるという欠点があります。これがうまく行かない場合は、SELECTの後にINSERTまたはUPDATEが続く唯一の方法があります。あなたはそれが気に入らないと言ったが、sqliteではこれは他のRDBMSほど悪くない。 sqliteは、クライアント/サーバRDBMSではなく、埋め込まれたRDBMSであるため、このような複数の操作を実行する際のコストははるかに小さくなります。しかし、トランザクションで2つの操作をラップすることを忘れないでください。

+0

を'SELECT'の結果です。 @CLは、私が他のところで見た解決策を示唆しています。その特定の 'id'で行を更新します。これは' id'があれば動作し、更新がない場合は 'INSERT' 。しかし、それは依然として2つのクエリソリューションです。私はどちらが速いのかわからない – chiapa

+0

私は 'INSERT OR REPLACE'が唯一のワンステップ解決策だと思います。なぜあなたは2つの操作を行うような嫌悪を持っているのですか? sqliteでは、包括的なソリューションであるため、従来のクライアント/サーバーRDBMSで支払うコストを支払う必要はありません。ネットワークスタックを介する往復やコンテキストスイッチなどがないためです。 – redneb

+0

嫌悪感ではなく、不必要な操作やオーバーヘッドを避けたいだけでした。 T-SQLでは、パフォーマンスを損なう可能性があるため、1つを使用できる場合は2つの操作を避けます – chiapa

1

あなただけのUPDATEを試みることができる、と何のレコードが実際に更新されなかった場合は、INSERTを実行:はい、私は依存 `SELECT`、その後` INSERT`または `UPDATE`を避けたい

ContentValues cv = new ContentValues(); 
cv.put("Name", ...); 
if (db.update("test", cv, "id = " + myID, null) < 1) { 
    cv.put("id", myID); 
    db.insert("test", null, cv); 
}