TRIGGER FUNCTION等级检查PostgreSQL

时间:2014-03-19 13:17:18

标签: sql function postgresql triggers plpgsql

我创建了奖学金数据库,并使用表格

 applyid |  studid   |    gpa    | other |  sch_id  |    date    | sem | sy
---------+-----------+-----------+-------+----------+------------+-----+----
       1 | 2010-0000 | 1.5       |       |        1 |            |     |
       2 | 2010-0001 | 1.5       |       |        7 | 2014-03-13 |     |
       3 | 2010-0003 |           |       |        1 | 2014-03-13 |     |
       4 | 2010-0003 |           |       |        1 | 2014-03-13 |     |
       5 | 2010-0003 |           |       |        1 | 2014-03-13 |     |
    2308 | 2012-0004 | 1.5       |       |        1 | 2014-03-19 |     |
    4593 | 2012-0004 | 1.5       |       |        1 | 2014-03-19 |     |
    4596 | 2012-0004 | 1.5       |       |        1 | 2014-03-19 |     |
    4597 | 2012-0004 | 1.5       |       |        1 | 2014-03-19 |     |
(9 rows)

目前正致力于此触发功能,可检查特定学生的成绩是否为INC,DRP,5.00。

CREATE FUNCTION fail_check() RETURNS TRIGGER AS $$
DECLARE
one RECORD;
two RECORD;

BEGIN

   SELECT * INTO one FROM grade, registration;

   IF (SELECT COUNT(g.grade)::int  
       FROM grade g
         INNER JOIN registration r ON r.grade_id = g.grade_id
       WHERE g.grade IN ('INC', 'DRP', '5.00')
     AND studid=new.studid) <= 1 
   THEN 
    SELECT studid, gpa, sch_name INTO two
        FROM apply WHERE studid=new.studid;

    INSERT INTO apply(studid, gpa, sch_name)
    VALUES (new.studid, new.gpa, new.sch_name);

   END IF;

  RETURN NEW;

END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER fail
BEFORE INSERT ON apply
FOR EACH ROW
EXECUTE PROCEDURE fail_check();

但是当我输入时:

INSERT INTO apply(studid, gpa, sch_name) 
VALUES ('2012-0004', '1.5', 1);

学生编号为&#34; 2012-0004&#34;具有INC DRP等级和5.00。 SELECT查询完全正常并返回值3.由于3大于1,这与IF语句IF .... <= 1相反,我预计会出错这说得不能插入,因为&#34;学生&#34;有超过1个等级的INC,DRP,5.00。

但我得到了这个错误:

ERROR:  stack depth limit exceeded 
HINT:  Increase the configuration parameter "max_stack_depth" (currently 2048kB), after ensuring the platform's stack depth limit is adequate. 
CONTEXT:  SQL statement "SELECT (SELECT COUNT(g.grade) 
       FROM grade g
         INNER JOIN registration r ON r.grade_id = g.grade_id
       WHERE g.grade IN ('INC', 'DRP', '5.00')   AND studid=new.studid) <= 1" PL/pgSQL function fail_check() line 12 at IF SQL statement "INSERT INTO apply(studid, gpa, sch_name)  VALUES (new.studid, new.gpa, new.sch_name)" PL/pgSQL function fail_check() line 21 at SQL statement SQL statement "INSERT INTO apply(studid, gpa, sch_name)     VALUES (new.studid, new.gpa, new.sch_name)"

我哪里出错?这个max_stack_depth究竟意味着什么?我的代码的哪一部分导致了这个max_stack_depth错误?

目前正在使用PostgreSQL 9.3.2

1 个答案:

答案 0 :(得分:0)

您的触发器BEFORE INSERT会触发更多INSERT到同一个表,从而导致无限循环。因此堆栈溢出。您似乎认为在触发器中需要这个:

INSERT INTO apply(studid, gpa, sch_name)   
VALUES (new.studid, new.gpa, new.sch_name);

但你不是。 RETURN NEW;足以让原始INSERT通过。

你的触发器的其余部分似乎没有做任何有用的事情,但这可能只是一种简化。