4

ステートメントの句SELECTにサブクエリを含めることはできません。FROM

そのようなサブクエリを含むビューを変更すると、依存するベース リレーションの変更があいまいになるのはなぜですか?

編集:私は解決策を見つけることに近づきました。学生 ID と名前を含むテーブルがあり、一意でない名前をすべて含むビューを作成する場合は、次のようになります。

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、テーブルに対してあいまいな変更を指定していStudentます。これは、すべての学生を削除するか、一意の名前の学生だけが残るように少数の学生だけを削除してビューをクリアできるためです。

サブクエリを含むビューに対して行うことができるあいまいな変更の例は他にありますか?

4

2 に答える 2

6

削除にあいまいさはありません。DELETE FROM aView ;ビューにある基になるテーブルのすべての行を削除する必要があります (許可されている場合)。

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 ;

DELETE正しく実装されている SQL 製品では問題なく動作します。SQL-ServerおよびOracleの SQL-Fiddles を参照してください。

SELECT * FROM Student ;

結果:

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

MySQL はエラーを提供します:The target table NonUnique of the DELETE is not updatable

Postgres は以下を提供します:ERROR: cannot delete from view "nonunique":


MySQL でこれを試すと、次のようになります。

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

またはこれ:

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

エラーは次のとおりです。The definition of table 'NonUnique' prevents operation DELETE on table 'Student'.


ただし、Postgres では、2 番目のステートメントが成功し、正しい行が削除されます。

MySQLは、派生テーブル内でビューを非表示にできた場合にのみ成功します。

DELETE s 
FROM Student AS s
   JOIN 
     ( SELECT *
       FROM NonUnique
     ) AS n 
     ON n.sid = s.sid ;
于 2012-08-08T18:51:47.977 に答える
0

私のインストラクターはこの答えを書きました:

SQL 標準では、あいまいさのため、そのビューを変更することはできません。

@ypercubeは、そのビューへの変更をベーステーブルへの変更に変換する明確に定義された方法が存在することを指摘しています。ただし、同様にビューを変更する可能性のあるベース テーブルへの他の変更があります。したがって、「特定のビューから * を削除する」というのは、実際にはあいまいだと思います。

于 2012-08-09T00:01:01.777 に答える