在PostgreSQL中,我创建了触发器过程,以便在插入或更新表中的行之前进行一些验证和执行一些查询。对于插入操作,我的触发器工作良好,因此我正在执行一些查询,但对于更新,我无法执行查询。
CREATE FUNCTION RECORDS_VALIDATE() RETURNS TRIGGER AS $$
DECLARE
tblVar text := dynamically im creating table name;
BEGIN
IF NEW.date <= CURRENT_DATE THEN
RAISE NOTICE 'DATE IS LESS THAN THE CURRENT DATE';
RETURN NULL;
END IF;
IF (TG_OP = 'UPDATE') THEN
EXECUTE 'UPDATE '|| tblVar || ' SET id = $1,date = $2 where id = $3'
USING NEW.id,NEW.date,OLD.id;
RETURN NULL;
END IF;
IF(TG_OP = 'INSERT') THEN
EXECUTE 'INSERT INTO ' || tblVar || ' VALUES($1,$2)'
USING NEW.id, NEW.date;
RETURN NULL;
END IF;
END;
$$ LANGUAGE plpgsql;
触发
CREATE TRIGGER RECORDS BEFORE INSERT OR UPDATE ON RECORDS
FOR EACH ROW EXECUTE PROCEDURE RECORDS_VALIDATE();
注:
记录是我的基表,从这个基表名我正在动态创建表,所以我不想在记录中插入行这就是为什么我返回空值我需要在新创建的表中插入行,所以使用execution命令我正在运行查询以在新创建的表中插入行。
插入
这将在新创建的表中插入行,而不是在记录中插入行
INSERT INTO BILLING_RECORDS VALUES(1,date '2013-10-15');
更新
在新创建的表中运行这些行时没有更新。也没有给出错误。我将输出为更新0
UPDATE RECORDS SET id = 10,date = date '2013-12-30' where id=1;
最佳答案
我想你是在这里建立分区自动触发器。我最近一直在研究同样的问题。
只对基表使用ON INSERT
触发器(我想是的)。
这个触发器将把记录移动到所需的分区中。
对于records
部分,向基表添加触发器没有意义,因为根据您的设计,它是空的。相反,您应该为正在使用的每个分区创建这样一个触发器,如果您是动态创建它们的,那么您应该确保每个这样的分区都有自己的触发器。不过,它们都可以共享一个函数。
还有一件事要记住。
更新分区键列时,必须格外小心:
如果使用ON UPDATE
约束来限制分区内的键范围,则会出现异常;
如果不进行检查,可能会导致数据布局混乱。
因此,如果新值对应于不同的分区,则应该改为CHECK
+UPDATE
,而不是分区键列的DELETE
。
另一种方法是完全限制对partitiong键列的更改。你可以做到:
在触发器中,比较INSERT
和OLD
值;
只为那些不属于分区键的列授予NEW
特权。
关于postgresql - 将UPDATE传播到动态确定的表,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19315565/