2012-05-04 19 views
0

私は、挿入操作中に挿入するのではなく更新する可能性があるテーブルにUPSERTトリガを持っています。私はそのテーブルに挿入を行う機能を持っていて、returning idしかし、挿入するのではなく更新するとidを返さない。どちらの場合でもIDを取得したい。PostgreSQL UPSERTトリガが返すID

トリガ・コード

perform 1 from tera_subject 
where id = new.subject_id and owner = new.user_id; 

if found then 
    return null; 
else 
    select id into vote_id from tera_votes where 
    user_id = new.user_id and 
    subject_id = new.subject_id; 
    if not found then 
    return new; 
    else 
     -- raise notice 'vote_id: % ; vote: %',vote_id,new.vote; 
     if(tg_op = 'INSERT') then 
      begin 
      -- raise notice 'redirecting to update'; 
      update tera_votes 
       set vote=new.vote 
       WHERE id = vote_id; 
      end; 
     elsif(tg_op = 'UPDATE') then 
      -- raise notice 'in update'; 
      return new; 
     end if; 
     -- raise notice 'end of trigger %',tg_op; 
     return null; 
    end if; 
end if; 
end; 
+1

コードを表示 –

+0

トリガーコードで更新しました。関数は単に 'RETURNING id 'を持つINSERTクエリです。 –

+0

完全定義のようには見えません、' DESCRIBE'セクションがありません。 – vyegorov

答えて

2

私はあなたがトリガによって、「返された」何かを持って管理しないと思います。

あなたが内部のやっていることである:あなたの条件に基づいて更新を実行している

  • トリガーを発生させた文を抑制するINSERT

これは、INSERTが簡単な方法で(例外なく)終了することを意味しますが、トリガー関数が値を返さないため、詳細を指定することはできません。

UPSERTで編集したアイテムのIDを取得する必要がある場合は、常にIDを返す関数、たとえばthis oneを使用することを検討してください。

+0

私が理解できなかったことは、その機能で 'LOOP'が何をしているのですか?それは何を繰り返しますか? –

+0

このようなループは必要ありません。機能の一般的なアイデアはあなたのニーズに合っています。このループは、 'UPDATE'が行を見つけずに行を見つけた後、' INSERT'の直前に並列セッションが対応する行をINSERTするように管理していた場合にcase文が失敗した場合に文を再発行する必要があります。 – vyegorov

+0

とにかく私はループを守っていますが、http://pastebin.com/mVQHEiyeが私に与えています 'LOOP'の近くの構文エラー –