2010年9月28日

[pgsql-jp: 40434] Re:「行が存在していなかったらinsert」の処理

 板垣様

 武田です。迅速なご回答ありがとうございます。

>> ■案3(これがNGなのが痛い)
>> ====================================
>> insert into t(pkey) select [_pkey]
>> where not exists(select 1 from t where pkey = [_pkey]) ;

>> ====================================
>現状、同時挿入は行ロックでは防げないので、「エラーが起こったら無視」
>という方針が妥当と思います。案3の処理を、PL/pgSQL の BEGIN?EXCEPTION
>ブロック (try?catch 相当) で囲むのが一般的ではないでしょうか。

 ありがとうございます。言われてみるとそうですよね。参考URLまで貼りつけて頂いて、大変助かりました。

(ご案内頂いたドキュメントより)
=============================
EXCEPTION句を含んだブロックの実行に要する時間は、含まないブロックに比べてとても長くなります。したがって、必要のない時にEXCEPTIONを使用してはいけません。
=============================

 ここが不安だったのですが、ベンチマークしたところ、実際ほとんど変らないようですね。


 MERGEは初耳でした。9.1に期待したいと思います。

-----Original Message-----
From: pgsql-jp-bounces@xxxxx [mailto:pgsql-jp-bounces@xxxxx] On Behalf Of Itagaki Takahiro
Sent: Monday, September 27, 2010 6:57 PM
To: PostgreSQL Japanese Mailing List
Subject: [pgsql-jp: 40432] Re: 「行が存在していなかったらinsert」の処理

2010/9/27 武田 憲太郎 <takeda@xxxxx>:
> ・行が存在しなかった場合のみinsertする。
> ・存在した場合は何もしない。
> ・アプリケーション側の処理は行ないたくない。SQLのみで完結したい。
> ・ストアドプロシージャを使うのはOK

> ■案3(これがNGなのが痛い)
> ====================================
> insert into t(pkey) select [_pkey]
> where not exists(select 1 from t where pkey = [_pkey]) ;
> ====================================

現状、同時挿入は行ロックでは防げないので、「エラーが起こったら無視」
という方針が妥当と思います。案3の処理を、PL/pgSQL の BEGIN?EXCEPTION
ブロック (try?catch 相当) で囲むのが一般的ではないでしょうか。

ドキュメントにある 例 38-2. UPDATE/INSERTの例外 も参考になるかもしれません。
http://www.postgresql.jp/document/current/html/plpgsql-control-structures.html#PLPGSQL-ERROR-TRAPPING


ちなみ、お求めの動作は標準SQLの MERGE というコマンドに相当します。
目下 9.1 に向けて開発中です。
https://commitfest.postgresql.org/action/patch_view?id=365

--
Itagaki Takahiro

投稿者 xml-rpc : 2010年9月28日 11:36
役に立ちました?:
過去のフィードバック 平均:(0) 総合:(0) 投票回数:(0)
本記事へのTrackback: http://hoop.euqset.org/blog/mt-tb2006.cgi/98683
トラックバック
コメント
コメントする




画像の中に見える文字を入力してください。