使用循环

时间:2016-08-08 09:09:29

标签: postgresql postgresql-9.1

之前从未在触发器中使用过循环,我有3个表格如下:

表1

  1_pk  |user   |tenant| filter
 ----------------------------------
|   1   | all   |  1   | O 
|   2   | john  |  1   | AA
|   3   | peter |  1   | AB
|   4   | pat   |  1   | AC
|   5   | all   |  2   | O
|   6   | tony  |  2   | AA
|   7   | jim   |  2   | AB

表2

  2_pk  |table1-FK|role  | tenant
 ----------------------------------
|   1   |   1    |  HR   | 1
|   2   |   2    | staff | 1
|   3   |   2    |  ceo  | 1
|   4   |   5    | staff | 2

表3

  3_pk  |table1-FK|table2-FK| tenant
----------------------------------
|   1   |    2    |   1     | 1
|   2   |    3    |   1     | 1
|   3   |    4    |   1     | 1
|   4   |    2    |   2     | 1
|   5   |    2    |   3     | 1
|   3   |    6    |   4     | 2
|   4   |    7    |   4     | 2

我想在表2上创建一个触发器,以便

  1. 在table2上创建记录,其中table1_Fk为1或5(例如:请参见表2),则触发器必须插入3条记录(如果table1_Fk = 1)或2条记录(如果table1_Fk = 5) )进入表3。 换句话说,如果过滤列(表1)='O',则触发器必须在该表3中为该特定租户插入X行数。

  2. 在table2上创建记录,其中table1_Fk为2,3,4,6或7(例如:请参见表2),则触发器只需在表3中插入1条记录。

  3. 我是否可以在此触发器中使用循环,因为我不知道每个租户在表1 中有多少条记录。

    由于

1 个答案:

答案 0 :(得分:1)

根本不需要循环。您可以使用基于Set的解决方案来实现。

CREATE OR REPLACE FUNCTION public.table2ins()
  RETURNS trigger AS
$BODY$ 
declare filt character varying(2);
BEGIN
filt := (SELECT filter FROM table1 WHERE "1_pk" = NEW."table1-FK");
IF filt = 'O' THEN
    INSERT INTO table3 ("table1-FK", "table2-FK", tenant) 
    SELECT table1."1_pk", NEW."2_pk", NEW.tenant FROM
    table1 WHERE table1.tenant = NEW.tenant
    AND table1.filter <> filt;
ELSE
    INSERT INTO table3 ("table1-FK", "table2-FK", tenant) 
    SELECT table1."1_pk", NEW."2_pk", NEW.tenant FROM
    table1 WHERE table1.tenant = NEW.tenant
    AND table1.filter = filt;
END IF; 
RETURN NEW;
END; 
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

IE如果过滤器对所有人都是“O”,则添加其他条目,否则只添加值本身。这种方法的优点是,您不需要知道“所有”记录的id值,您可以通过过滤器值找到它们(您也可以使用用户字段)。

BTW我假设table3中的主键是串行。

HTH 乔纳森