Postgresqlに、テーブルT
があり、その列の1つがC1
であると仮定します。
新しいレコードがテーブルT
に追加されたときに関数をトリガーしたい。この関数は、新しいレコードの列C1
の値を確認し、null /空の場合、その値を'X'
に設定する必要があります。
これは可能ですか?
列のデフォルト値を設定しても機能しないため、トリガーが必要であることは正しいです。デフォルト値はnull
値に対してのみ機能し、空白値の防止には役立ちません。
Postgresには、トリガーを作成するためのいくつかの手順があります。
ステップ1:タイプtrigger
を返す関数を作成します。
CREATE FUNCTION my_trigger_function()
RETURNS trigger AS '
BEGIN
IF NEW.C1 IS NULL OR NEW.C1 = '''' THEN
NEW.C1 := ''X'';
END IF;
RETURN NEW;
END' LANGUAGE 'plpgsql'
ステップ2:beforeinsertを起動するトリガーを作成します。これにより、挿入される前に値を変更でき、上記の関数を呼び出します。
CREATE TRIGGER my_trigger
BEFORE INSERT ON T
FOR EACH ROW
EXECUTE PROCEDURE my_trigger_function()
これで完了です。
SQLFIddleで実行される上記のコード を参照してください。
コメントで、値'X'
は、サブクエリから取得されます。その場合、関連する行を次のように変更します。
NEW.C1 := (select some_column from some_table where some_condition);
可能ですが、代わりに列にデフォルトの制約を設定する方が良いでしょう。次のような表を作成する場合:
create table mytable as (
C1 thetype not null default X
);
これは、テーブルに行を追加し、C1の値を指定しない場合、代わりにXが使用されることを示しています。 not nullは必要ありませんが、更新がその列をnullにすることを防ぎます。
編集:これは定数Xに対してのみ機能します、あなたのコメントから、2つの可能な解決策があるようです。
トリガーを使用すると、次のようになります。
create function update_row_trigger() returns trigger as $$
begin
if new.C1 is NULL then
new.C1 := X;
end if;
return new;
end
$$ language plpgsql;
create trigger mytrigger before insert on mytable for each row execute procedure update_row_trigger();
トリガー関数のnew
変数は特別であり、挿入される行を表します。トリガーをbefore insert
トリガーとして指定すると、テーブルに書き込まれる前に行を変更できます。
2番目の解決策は、Postgresが異常な方法で定義する計算列を使用することです。
create or replace function C1(row mytable) returns columntype immutable as $$
begin
return X; -- where X is an expression using values from `row`
end
$$ language plpgsql;
これにより、テーブルの行を取得して値を返す関数が作成され、を使用して呼び出すことができます。ただし、できることを意味します:
select
*,
t.C1
from
mytable t;
不変の関数の宣言はオプションですが、「列」にインデックスを付ける場合に必要です。この列に次のようにインデックスを付けることができます。
create index on mytable (C1(mytable));