2011-08-08 4 views
4

Delphi 7とベース7の使用1つのsqlを使用してマスターディテールレコードを削除する方法は?

マスターディテールレコードとそのネストされたすべての詳細レコードを1つのSQL文で削除できますか?

例:

表1
ID - 整数
TITLE - VARCHAR(80)

表2
ID - 整数
Table1_ID - 整数
TITLE - VARCHAR(80)

表3
ID - 整数
Table2_ID - 整数
TITLE - VARCHAR(80)

Iが表に表1からのID 10を削除して、その一致するレコード(Table1_ID)のすべての表2に、そのすべての一致するレコード(Table2_ID)になります3

私はこれを1つのsqlで行うことはできませんが、私は複数のsqls(正しい順序のステートメントを呼び出す)でやりますか?

+6

カスケードオプションを使用して外部キー参照を作成する場合、親レコードを削除するとすべての詳細も削除されます。他の制限がこれを妨げない限り。 – mjn

+0

すでにRDBMSを使用しているので、Wikipediaまたは他の場所で[参照整合性の利点](http://en.wikipedia.org/wiki/Referential_integrity#Benefits_of_Referential_Integrity)を参照してください。 –

答えて

1

表3 FROM DELETE WHERE Table2_ID IN

Table1_IDは= XXXX

表1 FROM DELETE FROM表2 DELETE(Table1_ID = XXXX Table_2 FROM SELECT ID)WHERE ID =に加えXXXX

+0

その1つのステートメントではありませんが、私は私の記事の最後の文で言ったように "もし私が1つのSQLでこれを行うことはできません、私は複数のsqls(正しい順序でステートメントを呼び出す)? - これは私が働くことができるものです。ありがとう! – IElite

1

1つの文ではできませんが、代わりにDelphiでトランザクションを使用して、文がすべて実行されているかどうかを確認してください。

BDEを使用している場合は、TDatabaseコンポーネントをドロップしてデフォルトのプロパティを設定し、次のコードを記述します。

try 
    Database1.StartTransaction; 
    //Execute first query 
    //Execute second query 
    //Execute third query 
    Database1.Commit; 
except on E: Exception do 
    Database1.Rollback; 
end; 

あなたはそれがために、いくつかのSQLのdeleteingをwitnヨが行うことができますADOConnection1.BeginTrans;ADOConnection1.CommitTrans;ADOConnection1.RollbackTrans;

+0

私はSQlと私は削除を行う注文、次に取引部分 – IElite

+0

@シェーン、これは重要な答えです。外部キーやトリガーがなければ、1つのコマンドで必要な操作を行うことはできません。トランザクション内での削除は、すべてまたは何も必要ないので、重要です。注文について不思議ならば、詳細からマスターに削除してください。 – johnny

+0

私の投稿の最後の文章は "1つのSQLでこれを行うことができない場合、私は複数のsqls(正しい順序で文を呼び出す)でそれをどうやって行うのですか? – IElite

10

を使用するADOを使用している場合は、表3、表2およびTABLE1上のレコード。一意の操作のようにそれを行うための1つのトランザクション内のすべて。

1つの代替方法は、table1でレコードを1つ削除するとtable2に関連するレコードを削除し、table3で関連するレコードを削除するにはtable2で同等のレコードを削除するトリガーです。

テーブル1のレコードを削除すると、ON CASCADE DELETE(または同様のもの)を使用してtabla2およびtable3上の関連レコードを削除できます(SGBD /データベースのヘルプまたはドキュメントを参照)。

私は英語で間違いを犯しています。私の自然言語ではありません。

よろしくお願いいたします。

3

親レコードが削除されたときに、外部キーを使用して子レコードにカスケード削除を行うことができます。

次のコマンドは、Table1(ID)のレコードが削除されたときに、Table2(Table1_ID)のレコードを削除する外部キーを作成する必要があります。

ALTER TABLE TABLE2 ADD CONSTRAINT FK_TABLE2_TABLE1 
FOREIGN KEY (Table1_ID) REFERENCES TABLE1 (ID) 
ON DELETE CASCADE; 

データベースエンジンはそうあなたがする必要があるすべての子テーブルの削除の世話をする。この方法ではある

delete from TABLE1 where ID = :ID_VALUE 

よろしく、

1

あなたはCASCADEオプションで外部キー参照を作成した場合、削除親レコードはすべての詳細も削除します(他の制限がこれを防止しない限り)。

SQL:このソリューションは、クライアントアプリケーションの協力を必要としない

ALTER TABLE Table2 ADD CONSTRAINT Table2_Table1_ID 
    FOREIGN KEY(Table1_ID) REFERENCES Table1(ID) ON DELETE CASCADE 

、サーバーは、一貫性のあるデータモデルを維持します。

1

複数のSQL文、外部キー関係、およびトリガーで既に与えられている回答。 InterBaseでは、マスターレコードと詳細レコードを削除するストアドプロシージャを記述することもできます。次に、プログラムには1つのSQL文しか必要ありません。

この状況では、2種類のストアドプロシージャを使用できます。
最初のものはHeartWaveの回答とほぼ同じですが、その後はストアドプロシージャです。

CREATE PROCEDURE DELETEMASTERDETAIL_WITHOUTINFO(
    pMasterID INTEGER) 
RETURNS (
    rResult INTEGER) 
AS 
declare variable vTable2ID integer; 
begin 
    /* don't return information about deleted records */ 
    rResult = 0; 

    for select id 
     from table2 
     where table1_id = :pMasterID 
     into :vTable2ID do 
    begin 
    delete from table3 
    where table2_id = :vTable2ID; 
    end 

    delete from table2 
    where table1_id = :pMasterID; 

    delete from table1 
    where id = :pMasterID; 

    rResult = rResult + 1; 

    suspend; 
end 

このストアドプロシージャを呼び出すためのSQL文は次のとおりです。

select rresult 
from deletemasterdetail_withoutinfo(:pMasterID) 

秒1は、テーブルごと削除されたレコードの量に関する情報を返します。私はあなたがそれを必要とするかどうかは分かりませんが、おそらくそれは他の人にとって有益です。 Table1のIDフィールドがプライマリキーの場合、最初のselectステートメントは少し過剰です。

CREATE PROCEDURE DELETEMASTERDETAIL_WITHINFO(
    pMasterID INTEGER) 
RETURNS (
    rTable1Deleted INTEGER, 
    rTable2Deleted INTEGER, 
    rTable3Deleted INTEGER) 
AS 
declare variable vTable1ID integer; 
declare variable vTable2ID integer; 
declare variable vTable3ID integer; 
begin 
    /* return information about deleted records */ 
    rTable1Deleted = 0; 
    rTable2Deleted = 0; 
    rTable3Deleted = 0; 

    for select id 
     from table1 
     where id = :pMasterID 
     into :vTable1ID do 
    begin 
    for select id 
     from table2 
     where table1_id = :vTable1ID 
     into :vTable2ID do 
    begin 
     for select id 
      from table3 
      where table2_id = :vTable2ID 
      into :vTable3ID do 
     begin 
     rTable3Deleted = rTable3Deleted + 1; 

     delete from table3 
     where id = :vTable3ID; 
     end 

     rTable2Deleted = rTable2Deleted + 1; 
     delete from table2 
     where id = :vTable2ID; 
    end 

    rTable1Deleted = rTable1Deleted + 1; 
    delete from table1 
    where id = :vTable1ID; 
    end 

    suspend; 
end 

このストアドプロシージャを呼び出すためのSQL文は次のとおりです。ところで

select rtable1deleted, rtable2deleted, rtable3deleted 
from deletemasterdetail_withinfo(:pMasterID) 

。私はほとんど常にSPの少なくとも1つのリターンパラメータを使用します。これにより、クエリコンポーネントを使用してストアドプロシージャを呼び出すことができます。
結果パラメータがない場合は、SPを実行するためにストアドプロシージャコンポーネントを使用する必要があります。

関連する問題