0

我在一个视图上创建了一个 ON DELETE 规则,该规则将 OLD 选择到一个临时表中,然后调用一个使用 OLD 值执行操作的函数。该规则会在运行 SELECT INTO TEMPORARY TABLE 之前删除临时表,以防在会话期间通过执行 SELECT dropTempTable() 多次调用该规则。这一切都很好,除非没有什么可以删除,例如当没有名称为“John Doe”的记录时运行以下查询:

DELETE FROM myview WHERE name = 'John Doe';

在这种情况下,临时表是由计划程序创建的,以准备使用它,即使它不会被使用,但是我的 dropTempTable() 语句从未被调用,所以第二次在我的视图上执行 DELETE 时,它会失败,因为临时表已经存在。任何有关如何解决此问题的建议将不胜感激。我意识到使用触发器可以更好地解决此示例,但出于本文的目的,我已经对其进行了简化,并且触发器不适用于我的特定问题。

我的观点:

CREATE VIEW myview 
AS SELECT * FROM mytable

我的规则:

CREATE RULE myview_delete
AS ON DELETE TO myview
DO INSTEAD (
     SELECT dropTempTable();
     SELECT OLD INTO TEMPORARY TABLE myTempTable;
     SELECT myDeleteFunction();
);

我的放置表功能:

CREATE FUNCTION dropTempTable()
RETURNS void AS $$
BEGIN
     DROP TABLE IF EXISTS myTempTable;
END;
$$ LANGUAGE plpgsql;
4

1 回答 1

0

我最终将对 dropTempTable 函数的调用从 DELETE 规则中移到 SELECT 规则中,并添加了一个 EXCEPTION 语句,因此它看起来像:

我的放置表功能:

CREATE FUNCTION dropTempTable()
RETURNS void AS $$
BEGIN
     DROP TABLE IF EXISTS myTempTable;
EXCEPTION
     WHEN OTHERS THEN
END;
$$ LANGUAGE plpgsql;

这有点骇人听闻,但它确实有效。

于 2012-08-06T10:01:29.797 回答