我在PostgreSQL 9.3中定义了一个触发器,它根据attribute_group_attribute.default_value
的值检查attribute_type.max_length
的长度:
CREATE OR REPLACE FUNCTION trigger_function()
RETURNS trigger AS
$BODY$
DECLARE
is_longer_than_max_length BOOLEAN;
BEGIN
IF (NEW.default_value IS NOT NULL) THEN
SELECT length(NEW.default_value) > attribute_type.max_length
INTO is_longer_than_max_length FROM attribute_group_attribute
JOIN attribute ON NEW.attribute_id = attribute.id JOIN attribute_type
ON attribute.attribute_type_id = attribute_type.id;
IF (is_longer_than_max_length) THEN
RAISE EXCEPTION 'Attribute type with id % has max length of %,
while attribute default value % has a length of %.',
attribute_type.id, attribute_type.max_length, NEW.default_value,
length(NEW.default_value) USING ERRCODE='20808';
END IF;
END IF;
RETURN NEW;
END
$BODY$
LANGUAGE 'plpgsql' SECURITY INVOKER
;
CREATE TRIGGER trigger_name BEFORE INSERT OR UPDATE ON attribute_group_attribute
FOR EACH ROW EXECUTE PROCEDURE trigger_function()
;
触发器在INSERT
上正常工作并提升EXCEPTION
。但在UPDATE
我收到此错误:
ERROR: missing FROM-clause entry for table "attribute_type" at character 8
QUERY: SELECT attribute_type.id
CONTEXT: PL/pgSQL function trg_func_attr_group_attr_attr_type() line 8 at RAISE
答案 0 :(得分:1)
查询:
SELECT length(NEW.default_value) > attribute_type.max_length
INTO is_longer_than_max_length FROM attribute_group_attribute
JOIN attribute ON NEW.attribute_id = attribute.id JOIN attribute_type
ON attribute.attribute_type_id = attribute_type.id;
没有感觉。 attribute_group_attribute
子句中有FROM
,但此表没有过滤器。
您需要以下内容:
SELECT length(NEW.default_value) > attribute_type.max_length
INTO is_longer_than_max_length
FROM attribute
JOIN attribute_type ON attribute.attribute_type_id = attribute_type.id
WHERE NEW.attribute_id = attribute.id;
您还需要先选择attribute_type.id, attribute_type.max_length
到函数变量中,然后才能在RAISE EXCEPTION
语句中使用它们。
答案 1 :(得分:0)
在Igor Romanchenko's suggestions的帮助下,我提出了这个能够实现我想要的解决方案:
CREATE OR REPLACE FUNCTION trigger_function()
RETURNS trigger AS
$BODY$
DECLARE
attribute_type_id numeric(12,0);
attribute_type_max_length numeric(9,0);
is_longer_than_max_length BOOLEAN;
BEGIN
IF (NEW.default_value IS NOT NULL) THEN
SELECT attribute_type.id, attribute_type.max_length,
length(NEW.default_value) > attribute_type.max_length
INTO attribute_type_id, attribute_type_max_length,
is_longer_than_max_length FROM attribute_group_attribute
JOIN attribute ON NEW.attribute_id = attribute.id JOIN attribute_type
ON attribute.attribute_type_id = attribute_type.id;
IF (is_longer_than_max_length) THEN
RAISE EXCEPTION 'Attribute type with id % has max length of %, while
attribute default value % has a length of %.', attribute_type_id,
attribute_type_max_length, NEW.default_value,
length(NEW.default_value) USING ERRCODE='20808';
END IF;
END IF;
RETURN NEW;
END
$BODY$
LANGUAGE 'plpgsql' SECURITY INVOKER
;
CREATE TRIGGER trigger_name BEFORE INSERT OR UPDATE ON attribute_group_attribute
FOR EACH ROW EXECUTE PROCEDURE trigger_function()
;