2012-03-01 8 views
4

テーブルがあり、3つの整数列c1、c2、c3を持つテーブルがあります。私は、C1に割り当てられるとc2は同じ値を持つようにしたい、私は現在やっているINSERT文の場合1つの列のデフォルト値をINSERT文の別の列に設定します。

not null default nextval 

:c1は、デフォルト値を持っています。これは私の挿入物の大部分では当てはまりませんので、c2をデフォルト値にするか、または更新時にトリガーを持つように定義するのは意味がありません。現在、私は二つの文をしています:

INSERT INTO t1 (c3) VALUES (val3); 
UPDATE t1 SET c2 = c1 WHERE //Get correct row 

答えて

7

セットの順序要素が処理されるという保証ありません。また、は必要ありません 2つの関数呼び出しを行う。サブ選択またはCTEを使用します。

INSERT INTO t (c1, c2, c3) 
SELECT x.s, x.s, val3 
FROM (SELECT nextval('c1_seq') AS s) x; 

またはCTEを有する:

WITH x(s) AS (SELECT nextval('c1_seq')) 
INSERT INTO t (c1, c2, c3) 
SELECT x.s, x.s, val3 
FROM x; 
+1

このタイプのCTEはバージョン9.1で新しく追加されました。旧バージョンでは機能しません。 –

1

明示的でdefaultでデフォルト値を求める場合は、そのための明示的な値を供給したり、もちろんしない場合c1のデフォルト値のみが使用されますあなたの価値。 VALUES内にnextval and currvalを使用して、自分自身でシーケンスに自由にアクセスすることもできます。 nextval関数はこれを行います:

アドバンスシーケンスと新しい値を返します。

currval:最近あなたはc1のための次のシーケンス値を取得するには、この操作を行うと同じ値を得ることができ、指定されたシーケンス

ためのnextvalで得られた

戻り値c2

insert into t1 (c1, c2, c3) values (nextval('c1_seq'), currval('c1_seq'), val3) 

c1_seqは、c1のデフォルト値を指定するために使用しているシーケンスの名前です。動作しませんこと、もちろん

ALTER TABLE 
    t1 
ALTER COLUMN 
    c2 
SET DEFAULT 
    CURRVAL(PG_GET_SERIAL_SEQUENCE('t1', 'c1')); 

:あなたのケースでは

2

、あなたはC1、すなわちに関連付けられたシーケンスの現在の値にC2のデフォルト値を設定する必要がありますあなたがc1の明示的な値を指定した場合、そのような場合がある場合は、c2常にが挿入時にc1と同じになるように、BEFOREトリガーを作成する必要があります。

CREATE FUNCTION sync_c2() RETURNS trigger AS $$ 
BEGIN 
    IF NEW.c2 IS NULL THEN 
    NEW.c2 := NEW.c1; 
    END IF; 

    RETURN NEW; 
END; 
$$ LANGUAGE plpgsql; 


CREATE TRIGGER 
    sync_c2 
BEFORE INSERT ON 
    t1 
FOR EACH ROW EXECUTE PROCEDURE 
    sync_c2(); 
+0

ご希望の場合、トリガーでIFチェックは、明示的にC1からC2異なるの値を指定するために、あなたに自由を与えますに。 –

関連する問題