我有一张员工表,上面有他们的ID,名字和老板的ID
| emp_id | name | boss_id |
|--------|--------|---------|
| 100 | John | NULL |
| 110 | Carl | 100 |
| 120 | Andrew | 100 |
| 130 | Peter | 100 |
| 140 | Chris | 130 |
| 150 | Mary | 120 |
| 160 | Wayne | 110 |
然后,我必须创建一个视图,该视图将显示员工的姓名和他/她的老板的姓名。我使用自我连接来做到这一点:
CREATE OR REPLACE VIEW emps_and_bosses
AS SELECT e.name AS employee, b.name AS boss
FROM employees e JOIN employees b ON e.boss_id = b.emp_id
现在,如果我想更新视图中的日期(例如,设置其他名称),则会引发错误:
ERROR: cannot update view "emps_and_bosses"
DETAIL: Views that do not select from a single table or view are not automatically updatable.
HINT: To enable updating the view, provide an INSTEAD OF UPDATE trigger or an unconditional ON UPDATE DO INSTEAD rule.
所以问题是,如何在满足以下条件的情况下创建视图-仅使用一个FROM基础(不进行自我连接,以使视图可更新)?
答案 0 :(得分:1)
就像消息和doc(滚动到可更新视图)所说的那样,有一些条件可以使视图可更新。
由于您使用的是JOIN
,因此不满足其中一个条件。
提示建议创建一个触发器或无条件规则,这是我在下面所做的。
CREATE RULE UpdateBoss AS ON UPDATE TO emps_and_bosses
DO INSTEAD
UPDATE EMPLOYEES SET name = new.employee, Boss_id = (SELECT emp_id from employees where name = new.boss)
WHERE name = old.employee
重要提示:我假设您的employees
表在primary key
上有一个emp_id
,该视图未显示。
视图上的更新要小心,因为您的列都不是唯一的,因此当您只打算更新1时,您很可能会更新几条记录。
答案 1 :(得分:0)
好吧,解决方案之一是使用满足视图可更新条件的查询。
我们需要使用子查询来代替联接。
CREATE OR REPLACE VIEW emps_and_bosses
AS SELECT name, (SELECT name FROM employees b WHERE b.emp_id = e.boss_id) AS boss
FROM employees e
通过这种方式,我们正在创建的视图默认情况下是可更新的。