自动维护父表中子项的总数

时间:2017-01-18 20:06:50

标签: sql postgresql triggers plpgsql

我有父子表,我希望自动存储父记录中子项数的计数。更新不是很频繁,但是读取是,所以这是一个对我来说很容易缓存的数字。表格可能如下所示:

create table parent(
   id SERIAL PRIMARY KEY,
   numchildren integer not null default 0
);

create table child(
  id serial primary key
  parent_id integer NOT NULL REFERENCES parent(id)
);

我添加了一个更新numchildren的触发器,但它总是将numchildren设置为child表中的完整记录总数,而不仅仅是特定父项的计数

CREATE OR REPLACE FUNCTION run_after_change() RETURNS TRIGGER AS $$
BEGIN
  IF TG_OP = 'DELETE' THEN
    UPDATE parent 
       SET numchildren = (SELECT COUNT(*) FROM child WHERE OLD.parent_id = parent.id) 
    WHERE OLD.parent_id = parent.id;
    RETURN OLD;
  ELSIF TG_OP = 'UPDATE' OR TG_OP = 'INSERT' THEN
    UPDATE parent 
      SET numchildren = (SELECT COUNT(*) FROM child WHERE NEW.parent_id = parent.id) 
    WHERE NEW.parent_id = parent.id;
    RETURN NEW;
  END IF;
END; $$ language 'plpgsql';

CREATE TRIGGER after_change 
  AFTER DELETE OR INSERT OR UPDATE ON child 
  FOR EACH ROW EXECUTE PROCEDURE run_after_change();

我做错了什么?

1 个答案:

答案 0 :(得分:2)

count(*)查询的where子句是错误的。

parent.id应该是parent_id应该是:

SELECT COUNT(*) FROM child WHERE parent_id = NEW.parent_id

(或OLD.parent_id部分DELETE