2013-04-19 3 views
30

PostgresqlでテーブルTがあり、そのカラムの1つがC1であると仮定します。Postgresqlが値を設定するためにトリガを挿入する

新しいレコードがテーブルTに追加されたときに、関数をトリガーしたいと考えています。この関数は、新しいレコードの列C1の値をチェックし、NULL /空の場合は、その値を'X'に設定する必要があります。

これは可能ですか?

+0

Plsこの値Xは別のサブクエリから取得する必要があります。 – user1408470

答えて

52

列のデフォルト値を設定すると、あなたのために動作しませんので、あなたは、あなたが引き金を必要とすることを正しい - 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:前を発射トリガーを作成します上記の関数を呼び出す値を変更することができます。

あなたは完了です。

the above code executing on SQLFIddleを参照してください。正常に動作しています。


コメントでは、値'X'がサブクエリから取得されていると言います。そのような場合は、関連する行を次のように変更してください。

NEW.C1 := (select some_column from some_table where some_condition); 
+1

答えをありがとう。これはまさに私が望んでいたものです。 – user1408470

+5

なぜあなたは '$$'を使わずに '' 'を使うのですか? – displayname

6

可能ですが、列のデフォルトの制約を設定する方がよい場合があります。テーブルを作成するときのようになりますこと:

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)); 
+0

ありがとうございますが、私の場合、デフォルトの制約として値を設定するとエラーが発生します。この値Xはサブクエリによって取得されるため、許可されないためです。回避策を教えてもらえますか? – user1408470

+0

C1の値は、同じ行の他の値によって一意に決定されるのですか、時刻などの他の要素や他の表のデータに依存しますか? – Steve

+0

これは一意に決定されます。それは単に(name = 'Unique_Value'のTable2のidを選択して)検索されます。このIDは異なるDBで異なる可能性があるため、常にサブクエリから取得する必要があります。 – user1408470

関連する問題