触发器停止在不同的表上插入相同的数据

时间:2014-05-07 23:14:37

标签: sql postgresql

我创建了三个表,如下所示,我想创建一个触发器,当我尝试将新记录插入table_2而该记录已经在table_3时,会出现错误消息显示,并防止插入重复数据。这也应该反过来,两个表中都不能存在相同的数据。

create table table_1 (
  a varchar(255),
  b integer,
  d varchar(255),
  primary key(a, b)
);

create table table_2 (
  a varchar(255),
  b integer,
  c varchar(255),
  primary key(a, b, c),
  foreign key(a, b) references table_1(a, b)
);

create table table_3 (
  a varchar(255),
  b integer,
  c varchar(255),
  primary key(a, b, c),
  foreign key(a, b) references table_1(a, b)
);

1 个答案:

答案 0 :(得分:1)

如果要避免在两个不同的表中插入相同的数据,则需要在插入时测试数据是否已存在于另一个表中。请注意,在更新两个表中任何一个表中的记录时,也应该执行此测试。您可以使用单个触发器功能在两个方向上执行这两个操作:

CREATE FUNCTION check_duplicates_in_tables_2_3() RETURNS trigger AS $$
BEGIN
  -- Check if the new data is in either of the two tables, works for inserts and updates
  PERFORM * FROM table_2 WHERE a = NEW.a AND b = NEW.b AND c = NEW.c;
  IF FOUND THEN
    RAISE 'Data is already present in table_2';
  END IF;
  PERFORM * FROM table_3 WHERE a = NEW.a AND b = NEW.b AND c = NEW.c;
  IF FOUND THEN
    RAISE 'Data is already present in table_3';
  END IF;

  -- Data is unique so let the insert or update operation succeed.
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

对于两个表中的每一个,您应该定义一个调用触发器函数的触发器:

CREATE TRIGGER table_2_duplicate_check
  BEFORE INSERT OR UPDATE ON table_2
  FOR EACH ROW EXECUTE PROCEDURE check_duplicates_in_tables_2_3();

CREATE TRIGGER table_3_duplicate_check
  BEFORE INSERT OR UPDATE ON table_3
  FOR EACH ROW EXECUTE PROCEDURE check_duplicates_in_tables_2_3();

请注意,触发器函数会因table_2和table_3上存在索引而大大受益。