简体   繁体   中英

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

The SELECT statement cannot contain a subquery in the FROM clause.

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.

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. See the SQL-Fiddles for SQL-Server and Oracle :

SELECT * FROM Student ;

Result:

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

MySQL provides error: The target table NonUnique of the DELETE is not updatable

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


If you try this in 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'.


In Postgres however, the second statement succeeds and deletes the correct rows.

MySQL succeeds only if you manage to hide the view inside a derived table:

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.

@ypercube makes the point that there does exist a well-defined way to translate modifications to that view to modifications to the base table. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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