2016-09-07 7 views
0

テーブルトリガを挿入してもPetaPoco/Npgsqlが失敗します。PostgreSQLで複数のトリガを持つテーブルでPetaPocoの挿入に失敗する

は、私は、これはPetaPoco insert fails on table with triggerに非常に似ていると信じて、その質問さの違いは、SQL 2008のためだったと私は複数のトリガーを持つテーブルでNpgsqlのC#のドライバを使用してのPostgreSQL 9.5.4ためです。私の主な問題は、PetaPoco database.Insert()の代わりに次あるOrderNoまたは現在の時刻を0とエポック時間の節約を主張していることである

CREATE TABLE procedures 
(
    recid serial NOT NULL, 
    orderno integer NOT NULL, 
    torder timestamp without time zone NOT NULL DEFAULT now(), 
    cpt_recid integer NOT NULL, 
    dx_recid integer, 
    send_out boolean, 
    modified timestamp without time zone NOT NULL DEFAULT now(), 
) 
WITH (
    OIDS=FALSE 
); 
ALTER TABLE procedures 
    OWNER TO postgres; 


CREATE TRIGGER update_modified 
    BEFORE UPDATE 
    ON procedures 
    FOR EACH ROW 
    EXECUTE PROCEDURE update_modified(); 

CREATE TRIGGER zzz_get_next_order_number_trigger 
    BEFORE INSERT 
    ON procedures 
    FOR EACH ROW 
    EXECUTE PROCEDURE getnextorderno(); 


CREATE OR REPLACE FUNCTION getnextorderno() 
    RETURNS trigger AS 
$BODY$ 

BEGIN 
    NEW.orderno := nextval('order_number_seq'); 
    Return NEW; 
END; 

$BODY$ 
    LANGUAGE plpgsql VOLATILE 
    COST 100; 
ALTER FUNCTION getnextorderno() 
    OWNER TO postgres; 

私の状況は次のように私は、PostgreSQLで定義された複数のトリガーを持つテーブルを持っているということです。

PetaPocoには、列のDEFAULTSのいずれかを尊重するか、トリガーを正しく機能させるための簡単な変更がありますか?

(私はPetaPocoの新機能です)

TIA

提案された変更後の​​編集#1は、テーブルには、今、以下のようになります。私がまだ抱えている問題は、のordernoはまだで埋められており、ユニーク制約に違反しているということです。

重複するキー値が一意制約 "procedure_order_unique" キー(あるOrderNo)=(0)すでに存在しているに違反します。

PetaPocoインサートとしてWCFサービスから呼び出されている:任意の助け

p = new procedure 
        { 
         cpt_recid = cpt.recid, 
         chart_recid = _procedure.chart_recid, 
         dx_recid = _procedure.dx_recid, 
         torder = _procedure.torder, 
         on_return_to_office = _procedure.on_return_to_office, 
         send_out = _procedure.send_out, 
         standing_order = _procedure.standing_order, 
         stat = _procedure.stat, 
         tstop = _procedure.tstop, 
         isprocedure = _is_procedure 
        }; 
        db.Insert(p); 

CREATE TABLE procedures 
(
    recid serial NOT NULL, 
    orderno integer NOT NULL DEFAULT nextval('order_number_seq'::regclass), 
    torder timestamp without time zone NOT NULL DEFAULT now(), 
    cpt_recid integer NOT NULL, 
    dx_recid integer, 
    send_out boolean, 
    modified timestamp without time zone NOT NULL DEFAULT now(), 
    stat boolean, 
    standing_order boolean, 
    tstop timestamp without time zone, 
    on_return_to_office boolean, 
    chart_recid integer NOT NULL, 
    isprocedure boolean NOT NULL DEFAULT false, 
    is_deferred boolean, 
    CONSTRAINT procedures_pk PRIMARY KEY (recid), 
    CONSTRAINT procedures_chart_fk FOREIGN KEY (chart_recid) 
     REFERENCES charts (recid) MATCH SIMPLE 
     ON UPDATE CASCADE ON DELETE RESTRICT, 
    CONSTRAINT procedures_cpt_fk FOREIGN KEY (cpt_recid) 
     REFERENCES cpt (recid) MATCH SIMPLE 
     ON UPDATE CASCADE ON DELETE RESTRICT, 
    CONSTRAINT procedures_dx_fk FOREIGN KEY (dx_recid) 
     REFERENCES dx (recid) MATCH SIMPLE 
     ON UPDATE CASCADE ON DELETE RESTRICT, 
    CONSTRAINT procedure_order_unique UNIQUE (orderno) 
) 
WITH (
    OIDS=FALSE 
); 
ALTER TABLE procedures 
    OWNER TO postgres; 

CREATE TRIGGER insert_modified 
    BEFORE INSERT 
    ON procedures 
    FOR EACH ROW 
    EXECUTE PROCEDURE update_modified(); 

CREATE TRIGGER update_modified 
    BEFORE UPDATE 
    ON procedures 
    FOR EACH ROW 
    EXECUTE PROCEDURE update_modified(); 

感謝。

答えて

1

注文番号のトリガーは必要ありません。列のシーケンスを設定し、トリガーの必要性を取り除くだけです。

POCOの変更されたプロパティがnullでないため、デフォルト値を送信しているため、変更が保存されています。これを防ぐには、変更前のトリガを更新前と更新前の両方で実行します。

BEFORE INSERT OR UPDATE

http://www.toptensoftware.com/petapoco/

ドキュメントには、主キーを持つクラス定義を飾るために言う:

[PetaPoco.PrimaryKey("orderno")]

は属性を持つテーブルを飾るとT4テンプレートを修正することを回避するために、代わりに列の名前をidにする必要があります。

PetaPocoは挿入時にこれを無視し、データベースがそれを処理できるようにします。

他の列名は非プライマリキーとみなされ、デフォルト値が送信されます。

PostgreSQLとSQL Serverは、挿入時に値が与えられたときにシナリオで起こっているように、SERIALIDENTITYの列を無視します。

+0

上記の編集#1を参照してください。 PetaPocoから呼び出されたときに、変更された時刻のInsertのトリガは正常に機能しますが、ordernoは正しいシーケンス番号ではなく0として挿入されています。何をすべきか??ありがとう。 –

+0

@AlanWayneあなたのモデル/コードをご提供ください。主キー属性でモデルを飾ったことはありますか?トリガでシーケンスを指定することはできず、単に通常はカラム制約として実行できますか? – Phill

+0

テーブルの主キーがrecidであり、正しく処理されています。私はT4テンプレートを使ってモデルを常に更新している "データベースファースト"モデルなので、デコレーションの変更/追加を避けようとしています。だから私はテンプレートを恒久的に変更しないようにしています。あなたの助けをありがとう:) –

0

フィルのリードを取る(上)とPostgreSQLの手順テーブル自体を変更したくない、私は次のように正常に動作するが見つかりました:

  1. でPetaPoco Database.tt T4テンプレートを「微調整」:

    tables["procedures"]["orderno"].PropertyType="int?";  // Setting default value of orderno to null forces PostgreSQL trigger. 
    
  2. 変更トリガプロシージャへ:

    CREATE OR REPLACE FUNCTION getnextorderno() 
        RETURNS trigger AS 
    $BODY$ 
    
    BEGIN 
    IF NEW.orderno is null THEN 
        NEW.orderno := nextval('order_number_seq'); 
    END IF; 
    
    Return NEW; 
    END; 
    
    $BODY$ 
    LANGUAGE plpgsql VOLATILE 
    COST 100; 
    ALTER FUNCTION getnextorderno() 
    OWNER TO postgres; 
    

上記のPhillによると、値0を使用すると、トリガーは無視されます。

関連する問題