计算受DELETE影响的行

时间:2013-12-27 10:13:48

标签: sql postgresql plpgsql postgresql-9.1 postgresql-9.2

我使用此代码验证DELETE句子,但我相信您知道更好的方法:

CREATE OR REPLACE FUNCTION my_schema.sp_delete_row_table(table_name character varying
                                                       , id_column character varying
                                                       , id_value integer)
  RETURNS integer AS
$BODY$
  DECLARE
    BEFORE_ROWS integer;
    AFTER_ROWS integer;
  BEGIN
    EXECUTE 'SELECT count(*) FROM ' || TABLE_NAME INTO BEFORE_ROWS;
    EXECUTE 'DELETE FROM ' || TABLE_NAME || ' WHERE ' || ID_COLUMN || ' = ' || (ID_VALUE)::varchar;
    EXECUTE 'SELECT count(*) FROM ' || TABLE_NAME INTO AFTER_ROWS;

    IF BEFORE_ROWS - AFTER_ROWS = 1 THEN
      RETURN 1;
    ELSE
      RETURN 2;
    END IF;
  EXCEPTION WHEN OTHERS THEN
    RETURN 0;
  END;
$BODY$
  LANGUAGE plpgsql VOLATILE;

如何改进此代码?我需要它在Postgres 8.4,9.1和9.2中工作。

2 个答案:

答案 0 :(得分:1)

实际上,无法FOUNDEXECUTE一起使用。 The manual

  

特别注意EXECUTE会更改GET DIAGNOSTICS的输出,   但不会改变FOUND

还有一些其他方面可能会有所改进。首先,您的原始版本对SQL注入开放。我建议:

CREATE OR REPLACE FUNCTION my_schema.sp_delete_row_table(table_name regclass
                                                       , id_column  text
                                                       , id_value   int
                                                       , OUT del_ct int) AS
$func$
BEGIN
   EXECUTE format ('DELETE FROM %s WHERE %I = $1', table_name, id_column);
   USING id_value;                     -- assuming integer columns

   GET DIAGNOSTICS del_ct = ROW_COUNT; -- directly assign OUT parameter

EXCEPTION WHEN OTHERS THEN
   del_ct := 0;
END
$func$  LANGUAGE plpgsql;

format()需要Postgres 9.1或更高版本。您可以使用字符串连接替换它,但请确保使用quote_ident()正确使用对列名称的转义! 其余的也适用于8.4。

密切相关的答案:

答案 1 :(得分:0)

查看名为foundrow_count的变量:

http://www.postgresql.org/docs/current/static/plpgsql-statements.html#PLPGSQL-STATEMENTS-DIAGNOSTICS

如果任何行受到影响,则

found为真。 row_count为您提供受影响的行数。

IF FOUND THEN
  GET DIAGNOSTICS integer_var = ROW_COUNT;
END IF;