VIEW多表上的PostgreSQL UPDATE

时间:2017-05-16 15:19:00

标签: sql postgresql view rule-engine

我在PostgreSQL中有一个VIEW,它由2个类似的表组成。

基本上两个表都是这样的:

id | data
---+------
 1 | foo
 2 | bar
[...]

现在在VIEW中,我使用这个命令:

CREATE RULE "_RETURN" AS ON SELECT TO myView DO INSTEAD
SELECT id, data
  FROM table1
  UNION ALL
SELECT (id + (SELECT MAX(id) FROM table1)),   
    data
  FROM table2;

结果是数据集成方法的两个表的组合

id | data
---+------
 1 | foo
 2 | bar
 3 | foo
 4 | bar
[...]

现在我想在该VIEW上执行UPDATE(以及随后的DELETE)。意图是将操作转发到数据集所属的表。

目前我有一些链接:

CREATE RULE "_UPDATE0"
  AS ON UPDATE TO users 
  DO INSTEAD NOTHING;

PostgreSQL需要一个无条件规则,这是“_UPDATE0”

CREATE RULE "_UPDATE1" 
  AS ON UPDATE TO users 
  WHERE NEW.id <= (SELECT MAX(table1.id) from table1) 
  DO ALSO
  (
    UPDATE table1 SET 
      data = NEW.data,
    WHERE table1.id = NEW.id
  );

CREATE RULE "_UPDATE2" 
  AS ON UPDATE TO myView
  WHERE NEW.id > (SELECT MAX(table1.id) from table1) 
  DO ALSO
  (
    UPDATE table2 SET 
      data = NEW.data,
    WHERE table2.id IN 
      (SELECT NEW.id - MAX(table1.id) from table1)
  ); 

_UPDATE1有意将myView.id <= 2上的UPDATE转发到表1。

_UPDATE2,似乎根本不起作用。

编辑:经过进一步的fiddeling后,我想我可以在_UPDATE2中找到它想要减去ID偏移的部分,并在我的WHERE子句中使用它。

任何想法或解释?我做错了什么?

1 个答案:

答案 0 :(得分:1)

好的,为我的_UPDATE2找到了有效的解决方案。

我将NEW.id拖出了子选项。

CREATE RULE "_UPDATE2" 
  AS ON UPDATE TO myView
  WHERE NEW.id > (SELECT MAX(table1.id) from table1) 
  DO ALSO
  (
    UPDATE table2 SET 
      data = NEW.data,
    WHERE table2.id = NEW.id - (SELECT MAX(table1.id) from table1)
  ); 

然而,我不知道为什么会这样。进一步解释赞赏。