web-dev-qa-db-ja.com

1つのSQLスクリプトで子行と親行を削除します

子行を削除してから別のsqlステートメントを記述して親行を削除する代わりに、両方を実行する1つのステートメントを使用したいと思いました。参考までに、Oracleデータベースを使用しています。

更新: CASCADEでDELETEを実行する権限がありません

17
WowBow

カスケード削除 で外部キーを定義します。次に、「親」行を削除するだけです。

14
Albin Sunnanbo
delete from 
(
select * from parent join child using (id)
where id = 1
)

警告!親行と子行の両方が存在する場所のみを削除します。子供のいない親は削除しません

4
grokster

あなたはそれをひどく行うことができます-すなわち、トリガーを使用して。

create table parent
(pid number,
   constraint parent_pk
     primary key (pid)
     using index
);

create table child
  (cid number,
   pid number,
   constraint child_pk
     primary key(cid)
     using index,
   constraint child_fk
     foreign key (pid)
     references parent (pid)
  );

create index child_fk on child (pid);

create trigger fake_delete_cascade
before delete on parent
for each row
begin
  delete from child where pid = :old.pid;
end;
/

insert into parent values (1);
insert into child values (1,1);
commit;
select count(*) from child;
delete from parent where pid = 1;
select count(*) from child;
2
Adam Musch

親行を削除するときに常に子を削除する場合は、外部キー制約を宣言して、Oracleが子削除を自動的に実行できるようにすることができます

create table parent (
  parentID number primary key,
  parentData varchar2(100)
);

create table child (
  childID number primary key,
  parentID number references parent( parentID ) on delete cascade,
  childData varchar2(100)
);

たとえば、親テーブルと子テーブルを宣言し、親行を削除すると自動的に子行を削除します。そのようなことを自動的に強制したくない場合、またはバックグラウンドで「自動的に」発生するときに追加される複雑さが気に入らない場合は、おそらく複数のDELETEステートメントを使用する必要があります。 。

1
Justin Cave

比較的大規模で非常に重要なデータベースでこの問題を経験した後、私は Silver bullet を作成することにしました! any が見つからなかったからです!実際、このスレッドの解決策/回答はどれも問題のニーズを満たしていません。

Githubで [〜#〜] cascadelete [〜#〜] リポジトリを参照してください。

1
faghani

別の(退屈な方法、これはデータベースにありますが、理由は不明ですが、外部キーを制約として使用しない-はい、はい)これを行うには、削除後(または削除前)にトリガーを作成します。

別の削除クエリを記述する必要がありますが、それはトリガー内のみです。

しかし、削除カスケードを配置できない場合、トリガーを追加できるかどうかわかりません...

0

それが他の誰かに役立つ場合、私は このStackoverflowの質問 の助けを借りて、テーブル内のすべての外部キー制約に対してこれを行うPLSQLスクリプトを作成しました。それが役に立てば幸い。

DECLARE
  CURSOR constraint_cursor IS SELECT *
                              FROM (SELECT a.table_name,
                                           a.constraint_name,
                                           a.column_name,
                                           c_pk.table_name r_table_name,
                                           b.column_name   r_column_name
                                    FROM user_cons_columns a
                                           JOIN user_constraints c ON a.owner = c.owner
                                                                        AND a.constraint_name = c.constraint_name
                                           JOIN user_constraints c_pk ON c.r_owner = c_pk.owner
                                                                           AND
                                                                         c.r_constraint_name = c_pk.constraint_name
                                           JOIN user_cons_columns b ON C_PK.owner = b.owner
                                                                         AND
                                                                       C_PK.CONSTRAINT_NAME = b.constraint_name AND
                                                                       b.POSITION = a.POSITION
                                    WHERE c.constraint_type = 'R'
                                      and c_pk.owner = 'YOUR SCHEMA HERE') tbl;
  sql_statement VARCHAR2(2048) := NULL;
  tab_row       constraint_cursor%rowtype;
BEGIN
  OPEN constraint_cursor;
  FOR i in 1..80 LOOP
    FETCH constraint_cursor into tab_row;
    EXECUTE IMMEDIATE 'ALTER table ' || tab_row.table_name || ' drop constraint ' || tab_row.constraint_name;
    EXECUTE IMMEDIATE 'ALTER table ' || tab_row.table_name || ' add constraint ' || tab_row.constraint_name || ' FOREIGN KEY (' ||
    tab_row.column_name || ') references ' || tab_row.r_table_name || '(' || tab_row.r_column_name || ') ON DELETE CASCADE ';
  end loop;
  close constraint_cursor;
end;
0
Katie.Sun