web-dev-qa-db-ja.com

以前のDELETEの影響を受けた行数を含む変数? (関数内)

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;
19
Bruno Bronosky

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

SQL%ROWCOUNT

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

例:

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年7月4日、カーティケヤンスンダラムは次のように書いています。

こんにちは、

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

挿入されたかどうか。

Oracleでは、このように言うことができます

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 [、...];このコマンドにより、システムステータスインジケーターを取得できます。各項目は、指定された変数(それを受け取るのに適切なデータ型である必要があります)に割り当てられる状態値を識別するキーワードです。現在使用可能なステータス項目は、SQLエンジンに送信された最後のSQLコマンドによって処理された行数であるROW_COUNT、および最新の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ステートメントは、FOUNDを1回以上繰り返す場合はtrueに設定し、それ以外の場合はfalseに設定します。これは、FORステートメントの3つのバリアントすべてに適用されます(整数FORループ、レコードセットFORループ、および動的レコードセットFORループ)。 FOUNDは、FORループの終了時にこのように設定されます。ループの実行内では、FOUNDはFORステートメントによって変更されませんが、ループ本体内の他のステートメントの実行によって変更される可能性があります。

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

11
UltraCommit

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

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;

合計を確認するには、このようにして任意の集計を取得し、グループ化してフィルタリングすることもできます。

9
Roelof Rossouw

私は自分のコードを共有したいと思います(私はRoelof Rossouwからこのアイデアを得ました):

CREATE OR REPLACE FUNCTION my_schema.sp_delete_mytable(_id integer)
  RETURNS integer AS
$BODY$
  DECLARE
    AFFECTEDROWS integer;
  BEGIN
    WITH a AS (DELETE FROM mytable WHERE id = _id RETURNING 1)
    SELECT count(*) INTO AFFECTEDROWS FROM a;
    IF AFFECTEDROWS = 1 THEN
      RETURN 1;
    ELSE
      RETURN 0;
    END IF;
  EXCEPTION WHEN OTHERS THEN
    RETURN 0;
  END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;