我正在写一个验证触发器。触发器必须验证数组的总和等于另一个字段。由于我有很多这种验证的实例,因此我想编写一个过程并创建多个触发器,每个触发器都有一组不同的要检查的字段。
例如,我具有以下架构:
CREATE TABLE daily_reports(
start_on date
, show_id uuid
, primary key(start_on, show_id)
-- _graph are hourly values, while _count is total for the report
, impressions_count bigint not null
, impressions_graph bigint[] not null
-- interactions_count, interactions_graph
-- twitter_interactions_count, twitter_interactions_graph
);
验证必须确认impressions_count = sum(impressions_graph)
。
我被卡住是因为我不知道如何NEW
从plpgsql中动态访问字段:
CREATE FUNCTION validate_sum_of_array_equals_other() RETURNS TRIGGER AS $$
DECLARE
total bigint;
array_sum bigint;
BEGIN
-- TG_NARGS = 2
-- TG_ARGV[0] = 'impressions_count'
-- TG_ARGV[1] = 'impressions_graph'
-- How to access impressions_count and impressions_graph from NEW?
RETURN NEW;
END
$$ LANGUAGE plpgsql;
CREATE TRIGGER validate_daily_reports_impressions
ON daily_reports BEFORE INSERT OR UPDATE
FOR EACH ROW EXECUTE
validate_sum_of_array_equals_other('impressions_count', 'impressions_graph');
我试图执行动态命令这样做EXECUTE 'SELECT $1 FROM NEW' INTO total USING TG_ARGV[0]
,但是PL / pgSQL的抱怨,新的是一个未知的关系。
我专门针对PostgreSQL 9.1。
跨发布到PostgreSQL的普通邮件列表postgresql.org/message-id/...
—
弗朗索瓦博索莱伊
AFAIK目前动态访问字段的唯一方法
—
Craig Ringer 2014年
NEW
是使用hstore(NEW)
然后hstore
以列名作为键的值访问字段。太烂了,因为然后它们都被投射到了text
,如果您想以它们的原始类型来使用它们,则必须将它们抛回去。或者,您可以使用另一种过程语言(如PL / Python)编写触发器,该触发器对动态记录访问具有更好的支持。
@CraigRinger:嗯,不。你今天太悲观了。动态SQL有一种方法。
—
Erwin Brandstetter 2014年