条件に該当するデータが存在しない時だけ登録するSQL

条件に該当するデータが存在しない時だけ登録するSQL

insert into [テーブル名] (フィールド名)
select 登録する値
where NOT EXISTS (select 1 from [テーブル名] where 条件)

例1:テーブル「tbl1」のフィールド「f1」に「テストデータ」がなければ、「テストデータ」を登録する

insert into tbl1 (f1)
select 'テストデータ'
where NOT EXISTS (select 1 from tbl1 where f1='テストデータ')

例2:テーブル「tbl1」のフィールド「f1」に「テストデータ」がなければ、フィールド「f2」に「ダミーデータ」を登録する

insert into tbl1 (f2)
select 'ダミーデータ'
where NOT EXISTS (select 1 from tbl1 where f1='テストデータ')

SQLのCOUNT(*)とCOUNT(列名)では結果が異なる

NULLを含むとき、COUNT(*)とCOUNT(列名)では結果が異なります。

Col1
10
(NULL)
50
(NULL)
40

このようなTBL1テーブルを例にします。

COUNT(*)はNULLを含めてカウントします。

SELECT COUNT(*) FROM TBL1

count
-----
    5

COUNT(列名)はNULLを含めません。

SELECT COUNT(COL1) FROM TBL1

count
-----
    3

SQL ゼロからはじめるデータベース操作』によると、

集約関数はNULLを除外する。ただし「COUNT(*)」は例外的にNULLを除外しない。

SQL ゼロからはじめるデータベース操作

ということでした。

SQLiteで複数の行を1行のINSERT文でまとめて追加する

SQLite(バージョン 3.7.11以降)では、次のようにして複数のデータを1行のINSERT文でまとめてINSERT文で追加することができます。

insert into t1 (f1, f2, f3)
values ('a1', 'b1', 'c1'),
       ('a2', 'b2', 'c2'),
       ('a3', 'b3', 'c3')

サーチエンジンで検索すると、古いバージョンを元に書かれた記事がありますが、現在のバージョンでは上のようにして一括して登録することができます。

FirebirdのINSERT文で追加されたIDを取得するには

Firebird 2.0以降では、INSERT文にRETURNING句を加えることで、追加されたIDを取得できます。

INSERT INTO t1 (id, ...) VALUES (next value for gen_t1, ...) RETURNING id;

DelphiのTIBSQLでIDを取得するには次のようなコードになります。

IBSQL1.SQL.Text := 'INSERT INTO t1 (id, ...) VALUES (next value for gen_t1, ...) RETURNING id';
IBSQL1.ExecQuery;
ID := IBSQL1.FieldByName('id').AsInteger;
IBSQL1.Close;

DelphiでFireDacを使用する場合は次のようなコードになります。

FDQuery1.SQL.Text := 'INSERT INTO t1 (id, ...) VALUES (next value for gen_t1, ...) RETURNING id1';
FDQuery1.Open;
ID := FDQuery1.Fields[0].Value;