2009-05-10 24 views
3

私はdbに挿入する文字列のリストを持っています。彼らはユニークでなければなりません。私は挿入するとき、私はlast_insert_rowidを使用するので、彼らのID(別のテーブルの外来キーとして使用する)が欲しいです。私には2つの問題があります。Sqliteは一意の名前でIDを取得します

  1. 私は無視を使用する場合、ROWIDは、私は取得しない更新されません
  2. 休憩私のデシベル(エントリは 存在しないのIDを指して)、そのID (INTEGER PRIMARY KEY)の更新プログラムを置き換える使用している場合正しいID

どのようにIDを取得しますか?もしそれが存在しなければ、select文を使って文字列をチェックして挿入したいと思う必要はありません。私はどのようにこれを行う必要がありますか?

答えて

3

私は私が私のテキストのID(PK)を得last_insert_rowidたいエラーの現在

insert into tbl(c_name) select 'val' where not exists(select id from tbl where c_name ='val'); 
select id from tbl where c_name ='val'; 
1

「彼らは一意でなければなりません」とは、あなたが彼らが本当であると確信しているか、そうでない場合にエラーとして結果を望むという意味ですか?文字列そのものをテーブルのキーにするだけで、1または2のどちらが問題になるかはわかりません。不要な重複があった場合はエラーを表示し、そうでなければ正しいIDを返します。たぶん、使用しているSQLコードの小さな例、問題のテーブル、観察している動作、そして代わりに必要とする動作を使って質問を明確にすることはできますか?

編集:編集に感謝しますが、SQLが何を問題にしているかはまだ分かりません。あなたのテーブルには例えば、から来る場合:

CREATE TABLE Foo(
    theid INTEGER PRIMARY KEY AUTOINCREMENT, 
    aword TEXT UNIQUE ABORT 
) 

その後、重複単語を挿入しようとすると、(それがUNIQUEのデフォルトだとしてABORTキーワードは、オプションです)失敗する - それはあなたがをしたいものではありません「ユニークでなければならない」という言葉を言いますと、つまり、そうでない場合はエラーです。

+0

代わりに以下を使用します。これまでのエントリを壊すIDを変更すると、エラーによってROWIDが返されません。私は2つのステップでこれを行う必要があるように聞こえる?select文とinsert文が存在しない場合は –

8

UNIQUE制約違反が発生すると、REPLACEアルゴリズムは、現在の行を挿入または更新する前に制約違反の原因となっている既存の行を削除し、コマンドは正常に実行され続けます。これは、ROWIDを変化させると

create table b (c1 integer primary key, c2 text UNIQUE ON CONFLICT IGNORE); 

とあなたから「または交換」条項を削除するには、次のように次のような問題

Y:> **sqlite3 test** 
SQLite version 3.7.4 
Enter ".help" for instructions 
Enter SQL statements terminated with a ";" 
sqlite> **create table b (c1 integer primary key, c2 text UNIQUE);** 
sqlite> **insert or replace into b values (null,'test-1');** 
sqlite> **select last_insert_rowid();** 
1 
sqlite> **insert or replace into b values (null,'test-2');** 
sqlite> **select last_insert_rowid();** 
2 
sqlite> **insert or replace into b values (null,'test-1');** 
sqlite> **select last_insert_rowid();** 
3 
sqlite> **select * from b;** 
2|test-2 
3|test-1 

周りの作業は、C2列の定義を変更することで作成されます挿入物;第三の挿入後の変化の戻り値はあなたがルックアップする必要があるでしょう、あなたのアプリケーションに通知されますselect last_insert_rowid(), changes();

sqlite> **create table b (c1 integer primary key, c2 text UNIQUE ON CONFLICT IGNORE);** 
sqlite> **insert into b values (null,'test-1');** 
sqlite> **select last_insert_rowid(), changes();** 
1|1 
sqlite> **insert into b values (null,'test-2');** 
sqlite> **select last_insert_rowid(), changes();** 
2|1 
sqlite> **insert into b values (null,'test-1');** 
sqlite> **select last_insert_rowid(), changes();** 
2|0 

:テストは、あなたの挿入した後、あなたが実行するには、次のSQLが必要になり、その後

"test-1"のROWIDはすでにファイルに格納されていたためです。もちろん、これがマルチユーザーシステムの場合は、トランザクション内でこれをすべてラップする必要があります。

+0

bの値に挿入または置換すると(1、 'test-1'); '(1、val)を知ることができないので、代わりにnullを使用します。 b(c2)値(val)に挿入または置換し、同じ結果でb(c2)select valに挿入または置換すると同じ結果が得られます。ここに画像があります(なぜカント私は/ sqliteシェルからコピー/貼り付け!)http://i.imgur.com/2a6IY.png –

+0

答えに編集: – Noah

+0

ええと、私は基本的に変更をチェックし、その1私はROWIDを使用します。それ以外の場合はselect文が必要です。私の答えは以下のように聞こえる。 OKこれは容認できる解決策です、+1。私は成功としてmysqlの下でテストしたので、私は現在の答えを受け入れます。 –

関連する問題