我有一个用作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;
我想在NOTICE中添加一个指示有多少行受影响(也就是:已删除)。我该怎么做(使用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;
答案 0 :(得分:11)
在Oracle PL / SQL中,用于存储已删除/插入/更新的行数的系统变量是:
SQL%ROWCOUNT
在DELETE / INSERT / UPDATE语句和BEFORE COMMITTING之后,您可以将SQL%ROWCOUNT存储在NUMBER类型的变量中。请记住,COMMIT或ROLLBACK将SQL%ROWCOUNT的值重置为ZERO,因此您必须在变量BEFORE 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年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
是否插入。
在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相同的内容?请帮忙。
关心skarthi
也许:
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仅在INSERT命令进入表后才有用 包含OID。
一个例子:
GET DIAGNOSTICS integer_var = ROW_COUNT;第二种方法 确定命令的效果是检查特殊变量 名为FOUND,类型为boolean。 FOUND在内部开始是假的 每个PL / pgSQL函数调用。它由以下各种类型设置 声明:
如果指定了行,则SELECT INTO语句将FOUND设置为true,如果为,则设置为false 没有返回任何行。
如果PERFORM语句产生(并丢弃)a,则它将FOUND设置为true row,如果没有生成行,则为false。
UPDATE,INSERT和DELETE语句设置FOUND为真,如果至少有一个 row受影响,如果没有行受影响,则为false。
如果FETCH语句返回一行,则设置FOUND为true,如果没有行则设置为false 退回。
FOR语句如果迭代一次或多次,则设置FOUND为true,否则为 假。这适用于FOR语句的所有三个变体 (整数FOR循环,记录集FOR循环和动态记录集FOR 循环)。当FOR循环退出时,FOUND以这种方式设置;在 - 的里面 执行循环时,FOR语句不修改FOUND, 虽然可以通过执行其他语句来改变它 循环体。
FOUND是每个PL / pgSQL函数中的局部变量;任何变化 它只影响当前的功能。
答案 1 :(得分:9)
对于非常强大的解决方案,这是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;
要查看总计,通过这种方式,您可以获得任何聚合甚至组并对其进行过滤。
答案 2 :(得分:1)
我想分享我的代码(我从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;