2012-08-03 51 views
0

我在视图上创建了一个ON DELETE规则,该规则将OLD选择到临时表中,然后调用一个函数,该函数使用旧。该规则在运行SELECT INTO TEMPORARY TABLE之前删除临时表,以防在执行SELECT dropTempTable()时在会话期间多次调用该规则。这一切都正常工作,除非没有东西需要删除,例如当有与“李四”的名称没有记录运行下面的查询:即使规则没有行作用,Postgres也会创建SELECTed INTO表

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; 
+1

“*触发器不适用于我的特殊问题*”。为什么? – 2012-08-03 08:38:27

+2

我会**从不**删除并在规则内创建表。决不。海事组织的重写规则在这种情况下不会太困难;基本上是从存在的temptable中删除(select * from realtable where keyfield = temptable.keyfield and realtable.keyfield = OLD.keyfield);'顺便说一句:你是否意识到这条规则是根据语句调用的? – wildplasser 2012-08-03 08:54:25

+0

感谢您的回复。我不能使用触发器,因为我有几个传统客户端正在与Postgres进行通信,而且我需要一段时间才能替换它们。同时,为了继续支持传统客户端,我们正在迁移到新的后端,我使用Postgres的内置语言来编写函数,这些语言桥接Postgres和新的后端。在某些情况下,实际上没有数据会被写入Postgres表中,触发器将适用于此表。当然,我有SELECT,INSERT和UPDATE规则支持这一点。我知道这听起来很乱,但我有几个选项,它的工作 – user1545610 2012-08-04 02:41:14

回答

0

我结束了移动我打电话给dropTempTable功能了删除规则,并添加一条EXCEPTION语句进入SELECT规则,如下所示:

我删除表功能:

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

这是一个黑客攻击的一位,但它的作品。

相关问题