22

INSERT トリガーとして使用される関数があります。この関数は、挿入される行と競合する行を削除します。それは美しく機能するので、このコンセプトのメリットについて議論したくありません。

DECLARE
re1 feeds_item.shareurl%TYPE;
BEGIN
SELECT regexp_replace(NEW.shareurl, '/[^/]+(-[0-9]+\.html)$','/[^/]+\\1') INTO re1;
RAISE NOTICE 'DELETEing rows from feeds_item where shareurl ~ ''%''', re1;

DELETE FROM feeds_item where shareurl ~ re1;
RETURN NEW;
END;

通知に、影響を受ける (別名: 削除される) 行数の表示を追加したいと思います。どうすればそれを行うことができますか (LANGUAGE 'plpgsql' を使用)?

更新: 「チキン・イン・ザ・キッチン」の優れたガイダンスに基づいて、次のように変更しました。

DECLARE
re1 feeds_item.shareurl%TYPE;
num_rows int;
BEGIN
SELECT regexp_replace(NEW.shareurl, '/[^/]+(-[0-9]+\.html)$','/[^/]+\\1') INTO re1;

DELETE FROM feeds_item where shareurl ~ re1;
IF FOUND THEN
    GET DIAGNOSTICS num_rows = ROW_COUNT;
    RAISE NOTICE 'DELETEd % row(s) from feeds_item where shareurl ~ ''%''', num_rows, re1;
END IF;
RETURN NEW;
END;
4

3 に答える 3

13

Oracle PL/SQL では、削除/挿入/更新された行数を格納するシステム変数は次のとおりです。

SQL%ROWCOUNT

DELETE / INSERT / UPDATE ステートメントの後、BEFORE COMMITTING で、SQL%ROWCOUNT を NUMBER 型の変数に格納できます。COMMIT または ROLLBACK は SQL%ROWCOUNT の値を 0 にリセットするので、SQL%ROWCOUNT の値を BEFORE COMMIT または ROLLBACK の変数にコピーする必要があることに注意してください。

例:

BEGIN
   DECLARE
      affected_rows   NUMBER DEFAULT 0;
   BEGIN
      DELETE FROM feeds_item
            WHERE shareurl = re1;

      affected_rows := SQL%ROWCOUNT;
      DBMS_OUTPUT.
       put_line (
            'This DELETE would affect '
         || affected_rows
         || ' records in FEEDS_ITEM table.');
      ROLLBACK;
   END;
END;

この興味深いソリューションも見つけました(ソース:http://markmail.org/message/grqap2pncqd6w3sp

2007 年 4 月 7 日、Karthikeyan Sundaram は次のように書いています。

やあ、

I am using 8.1.0 postgres and trying to write a plpgsql block.  In that I am inserting a row.  I want to check to see if the row has been

挿入されているかどうか。

オラクルでは、このように言うことができます

begin
  insert into table_a values (1);
  if sql%rowcount > 0
  then
    dbms.output.put_line('rows inserted');
  else
    dbms.output.put_line('rows not inserted');
 end if;  end;

postgres に sql%rowcount に等しいものはありますか? 助けてください。

よろしくスカルティ

多分:

http://www.postgresql.org/docs/8.2/static/plpgsql-statements.html#PLPGSQL-STATEMENTS-SQL-ONEROW

上記のリンクをクリックすると、次のコンテンツが表示されます。

37.6.6. 結果ステータスの取得 コマンドの効果を判断するには、いくつかの方法があります。最初の方法は、次の形式の GET DIAGNOSTICS コマンドを使用することです。

GET DIAGNOSTICS variable = item [ , ... ]; このコマンドを使用すると、システム ステータス インジケータを取得できます。各項目は、指定された変数 (変数を受け取るのに適切なデータ型である必要があります) に割り当てられる状態値を識別するキーワードです。現在使用可能なステータス項目は、ROW_COUNT (SQL エンジンに送信された最後の SQL コマンドによって処理された行数) と RESULT_OID (最新の SQL コマンドによって挿入された最後の行の OID) です。RESULT_OID は、OID を含むテーブルへの INSERT コマンドの後でのみ役立つことに注意してください。

例:

GET DIAGNOSTICS integer_var = ROW_COUNT; コマンドの効果を判断する 2 番目の方法は、ブール型の FOUND という名前の特殊変数をチェックすることです。FOUND は、各 PL/pgSQL 関数呼び出し内で false から始まります。次の各タイプのステートメントによって設定されます。

SELECT INTO ステートメントは、行が割り当てられている場合は FOUND を true に設定し、行が返されない場合は false に設定します。

PERFORM ステートメントは、行を生成 (および破棄) する場合は FOUND を true に設定し、行が生成されない場合は false に設定します。

UPDATE、INSERT、および DELETE ステートメントは、少なくとも 1 つの行が影響を受ける場合は FOUND を true に設定し、影響を受ける行がない場合は false を設定します。

FETCH ステートメントは、行を返す場合は FOUND を true に設定し、行が返されない場合は false に設定します。

FOR ステートメントは、1 回以上繰り返す場合は FOUND を true に設定し、そうでない場合は false に設定します。これは、FOR ステートメントの 3 つのバリアント (整数 FOR ループ、レコード セット FOR ループ、および動的レコード セット FOR ループ) のすべてに適用されます。FOR ループが終了すると、FOUND はこのように設定されます。ループの実行内では、FOUND は FOR ステートメントによって変更されませんが、ループ本体内の他のステートメントの実行によって変更される可能性があります。

FOUND は、各 PL/pgSQL 関数内のローカル変数です。それに対する変更は、現在の機能にのみ影響します。

于 2010-06-25T06:10:45.093 に答える
12

非常に堅牢なソリューションの場合、これは plpgsql だけでなく PostgreSQL SQL の一部であり、次のこともできます。

with a as (DELETE FROM feeds_item WHERE shareurl ~ re1 returning 1)
select count(*) from a;

実際には、次のようなより多くの情報を取得できます。

with a as (delete from sales returning amount)
select sum(amount) from a;

合計を表示するには、この方法で集計を取得し、グループ化してフィルター処理することもできます。

于 2013-11-12T06:27:49.243 に答える