https://www.sqlite.org/lang_conflict.html
・REPLACEとINSERT OR REPLACEは同じ
ここでいうORは制約エラーが発生した場合でUNIQUEやPRIMARY_KEYもしくはNOT NULL制約
UNIQUEやPRIMARY KEYの時はその行を削除してからINSERTが行われる。
NOT NULLの時はデフォルト値で置き換えられる。
とのことなのでREPLACEが使えるのはコラムを全部指定したときで一部しか指定しないと
他のコラムが消えるかデフォルト値で置き換えられるのだろう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
Use ".open FILENAME" to reopen on a persistent database. sqlite> create table mytable (cp integer primary key, c1,c2); sqlite> .table sqlite> insert into mytable values(1,'aaa','bbb'); sqlite> insert into mytable values(2,'xxx','yyy'); sqlite> insert into mytable values(3,'ccc','ddd'); sqlite> sqlite> select * from mytable; 1|aaa|bbb 2|xxx|yyy 3|ccc|ddd sqlite> insert into mytable values(1,'sss','ttt'); Error: UNIQUE constraint failed: mytable.cp sqlite> insert or replace into mytable values(1,'sss','ttt'); sqlite> select * from mytable; 1|sss|ttt 2|xxx|yyy 3|ccc|ddd sqlite> sqlite> insert into mytable(cp,c1) values(1,'vvv'); Error: UNIQUE constraint failed: mytable.cp sqlite> insert or replace into mytable(cp,c1) values(1,'vvv'); sqlite> select * from mytable; 1|vvv| 2|xxx|yyy 3|ccc|ddd sqlite> |
一部しか指定しないと他のコラムが消えてしまう。
1 2 3 4 5 6 7 8 9 |
sqlite> insert or replace into mytable ...> values(2,'AAA', ...> (select c2 from mytable where cp=2) ...> ); sqlite> select * from mytable; 1|vvv| 2|AAA|yyy 3|ccc|ddd sqlite> |
こう書けばOKだが、コラムが増えたとき対応できない。
やる方法もあるのかも知れないが返って複雑になりそうだから素直にUPDATEとINSERTに分けたほうがいいのか