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;
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関数内のローカル変数です。これを変更すると、現在の関数にのみ影響します。
非常に堅牢なソリューションの場合、これは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;
合計を確認するには、このようにして任意の集計を取得し、グループ化してフィルタリングすることもできます。
私は自分のコードを共有したいと思います(私は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;