2014-03-13 43 views
0

我已经定义在PostgreSQL的9.3触发器,检查的attribute_group_attribute.default_value长度的基础上attribute_type.max_length值:PostgeSQL触发引发异常工作在INSERT但不能在UPDATE


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

随着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() 
; 
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; 

不作SENS。 FROM子句中有attribute_group_attribute,但此表中没有过滤器。

你需要的东西,如:

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语句中使用它们。