条件に該当するデータが存在しない時だけ登録する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='テストデータ')

FirebirdでRows句を利用して指定した範囲の行を取得する

Firebirdでは、指定した件数のみ取得したいときはROWS句を使用します。

SELECT <columns> FROM ... ROWS 取得件数

たとえば次のように記述します。

SELECT * FROM t1 ROWS 3;

上記の場合、先頭の行から3行目までを取得します。

指定した範囲の行を取得するときは ROWS ~ TO ~ を使用します。

SELECT * FROM t1 ROWS 開始位置 TO 終了位置

たとえば次のように記述します。

SELECT * FROM t1 ROWS 3 TO 5

上記の場合、3行目から5行目までの3行を取得します。

ROWS句はUPDATE文やDELETE文にも使用できます。

UPDATE t1 SET f1=100 ROWS 3 TO 5

DELETE FROM t1 ROWS 3 TO 5

LibreOffice 4.2のBaseでFirebird Embeddedが使用可能になりました。

LibreOffice 4.2のBaseでFirebird Embeddedが使用可能になりました。

初期設定では使用できませんので、次のように設定を変更します。

メニューの「ツール」→「オプション」を選択します。

001

「LibreOffice」→「詳細」→「実験的な機能を有効にする」をチェックします。

002

設定を変更した後、Baseデータベースを新規に作成すると、

003

内蔵データベースのプルダウンメニューで「Firebird Embedded」を選択できるようになります。

004

追記

LO Embedded Firebird/HSQLDB performance comparison | AHunt.org」によると、HSQLDBよりもFirebirdのほうがかなり高速のようです。
HSQLDBが遅いのはJava/C++間の変換によるところが大きいと考えられるとのこと。

graph_firebirdhsqldb
グラフは「LO Embedded Firebird/HSQLDB performance comparison | AHunt.org」より引用。

追記

SQLiteを使う案もあったが、以下の理由で採用されなかった。
(「Bug 38811 – default to SQLite not HSQLDB in Base」)

  • SQLiteは機能が貧弱。標準SQLの多くの機能が不足している。
  • SQLiteはデータ型が弱い。日時型がない。

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;