简体   繁体   English

对在FROM子句中有子查询的视图进行模棱两可的修改?

[英]Ambiguous modifications to a view that has a subquery in the FROM clause?

The SELECT statement cannot contain a subquery in the FROM clause. SELECT语句在FROM子句中不能包含子查询。

If you modify a view that contains such a subquery, why is the modifcation of the base relation on which it depends ambiguous? 如果修改包含此类子查询的视图,为什么对其依赖的基本关系的修改不明确?

EDIT : I've come closer to finding a solution. 编辑 :我已经接近寻找解决方案。 If you have a table that contains, student ID's and names, and you want to create a view that contains all non-unique names, as in: 如果您有一个包含学生证和姓名的表,并且您想要创建一个包含所有非唯一名称的视图,如下所示:

create view NonUnique as
select * from Student S1
where exists (select * from Student S2
              where S1.sID <> S2.sID
              and S2.name = S1.name)

then delete from NonUnique is specifying an ambiguous modifcation to the Student table, because you could clear out the view by deleting all students, or just a handful of students such that only uniquely named students remain. 然后delete from NonUnique将为Student表指定一个不明确的修饰,因为您可以通过删除所有学生或删除少数学生来清除视图,从而仅保留唯一命名的学生。

Are there any other examples of ambiguous modifications we could make to a view that contains a subquery? 我们还可以对包含子查询的视图进行模棱两可的修改的其他示例吗?

I don't see any ambiguity in the delete. 我看不到删除中的任何歧义。 DELETE FROM aView ; should delete (if allowed) all rows in the underlying table that are in the View. 应该删除(如果允许)视图中基础表中的所有行。

CREATE TABLE Student
  ( sid INT NOT NULL
  , name VARCHAR(20) NOT NULL
  , PRIMARY KEY (sid)
  ) ;

INSERT INTO Student
  (sid, name)
VALUES
  (1, 'Alex'),
  (2, 'Bill'),
  (3, 'Cate'),
  (4, 'Dean'),
  (5, 'Eve'),
  (6, 'Alex'),
  (7, 'Bill'),
  (8, 'Cate') ;

CREATE VIEW NonUnique AS
SELECT * 
FROM Student S1
WHERE EXISTS 
      ( SELECT * 
        FROM Student S2
        WHERE S1.sID <> S2.sID
          AND  S2.name = S1.name
      ) ;

DELETE FROM NonUnique ;

It works fine in SQL products that have implemented DELETE correctly. 在已正确实现DELETE SQL产品中,它可以正常工作。 See the SQL-Fiddles for SQL-Server and Oracle : 请参见SQL-Fiddles for SQL-ServerOracle

SELECT * FROM Student ;

Result: 结果:

sid | name
----------
  4 | Dean
  5 | Eve

MySQL provides error: The target table NonUnique of the DELETE is not updatable MySQL提供错误: The target table NonUnique of the DELETE is not updatable

Postgres gives: ERROR: cannot delete from view "nonunique": Postgres提供: ERROR: cannot delete from view "nonunique":


If you try this in MySQL: 如果您在MySQL中尝试此操作:

DELETE s 
FROM Student AS s
   JOIN 
     NonUnique AS n 
       ON n.sid = s.sid ;

or this: 或这个:

DELETE
FROM Student 
WHERE EXISTS
      ( SELECT *
        FROM NonUnique 
        WHERE NonUnique.sid = Student.sid 
      ) ;

the error is: The definition of table 'NonUnique' prevents operation DELETE on table 'Student'. 错误是: The definition of table 'NonUnique' prevents operation DELETE on table 'Student'.


In Postgres however, the second statement succeeds and deletes the correct rows. 但是,在Postgres中,第二条语句成功并删除正确的行。

MySQL succeeds only if you manage to hide the view inside a derived table: 仅当您设法将视图隐藏在派生表中时, MySQL才会成功:

DELETE s 
FROM Student AS s
   JOIN 
     ( SELECT *
       FROM NonUnique
     ) AS n 
     ON n.sid = s.sid ;

My instructor wrote this answer: 我的老师写了这个答案:

The SQL standard does not allow that view to be modified, because of the ambiguity. 由于含糊不清,SQL标准不允许修改该视图。

@ypercube makes the point that there does exist a well-defined way to translate modifications to that view to modifications to the base table. @ypercube指出确实存在一种定义明确的方法,可以将对该视图的修改转换为对基表的修改。 However, there are other modifications to the base table that could similarly modify the view. 但是,对基表还有其他修改,可以类似地修改视图。 Thus, I think "delete * from the-specificied-view" is actually ambiguous. 因此,我认为“从特定视图中删除*”实际上是模棱两可的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM