为什么我们不能更新定义中有DISTINCT子句的视图?
如果视图的定义中有 DISTINCT 子句,则视图无法更新这一事实背后的逻辑我不明白。请举例指导。
回答
如果你有桌子:
CREATE TABLE table_name ( value1, value2 ) AS
SELECT 1, 1 FROM DUAL UNION ALL
SELECT 1, 1 FROM DUAL UNION ALL
SELECT 1, 2 FROM DUAL UNION ALL
SELECT 2, 1 FROM DUAL UNION ALL
SELECT 2, 2 FROM DUAL;
和观点:
CREATE VIEW view_name ( value1, value2 ) AS
SELECT DISTINCT value1, value2 FROM table_name;
你尝试做:
UPDATE view_name
SET value2 = 2
WHERE ( value1, value2 ) IN ( (1, 1) );
应该更新哪一行?
- 应该是第一行吗?还是第二排?两者都可以用作
DISTINCT值。在这种情况下,仍然会有DISTINCT一行具有1, 1配对,并且更新似乎什么也没做。 - 第一排和第二排?这样以后就没有
1, 1配对了吗?
预期的行为是模棱两可的,因为任何一个结果都可能是一个有效的解决方案。
Oracle 通过禁止更新聚合/不同视图来消除潜在的歧义。
从OracleUPDATE文档:
如果指定视图,则数据库更新视图的基表。如果视图
INSTEAD OF的定义查询包含以下结构之一,则不能更新视图,除非使用触发器:
- 集合运算符
- 一个
DISTINCT操作员- 聚合或分析函数
- 一
GROUP BY,ORDER BY,MODEL,CONNECT BY,或START WITH条款- ...