0

私はテーブルUniversitiesとテーブルCitiesを持っています。それらの間にはam:nの関係があるため、関係はCityUniversitiesと呼ばれる別のテーブルに保存されます。ここで、大学から大学を削除するときに、CitiesとUniversitiesのテーブル間のすべての関係を削除するトリガーを作成したいと思いました。しかし、それは機能していません。大学を削除しようとすると、常に次のエラーメッセージが表示されます。

「メッセージ547、レベル16、状態0、2行目DELETEステートメントがREFERENCE制約「FK_CityUniversities_Universities」と競合しました。データベース「Alumni_Dev」、テーブル「dbo.CityUniversities」、列「UniversityId」で競合が発生しました。ステートメントは終了しました。」

これが、私が実装して正常に実行したトリガー(テーブル大学の場合)です。

USE [Alumni_Dev]
GO
/****** Object:  Trigger [dbo].[deleteUni]    Script Date: 05/02/2012 11:42:43 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER TRIGGER [dbo].[deleteUni]
ON  [dbo].[Universities] 
FOR DELETE
AS 
DECLARE @UniId int
SELECT @UniId = (SELECT UniversityId FROM deleted)
BEGIN
--Remove constraints
DELETE FROM dbo.CityUniversities WHERE UniversityId = @UniId;
END  

私はすでに自分の解決策をいくつかの参考文献と比較しましたが、間違っている可能性のあるものは何も見つかりません。影響を受けるテーブルの1つに間違った設定がある可能性がありますか?

何か提案をいただければ幸いです。


私はついに次のトリガー(ニコラへのthx)で私の問題を解決しました:

ALTER TRIGGER [dbo].[deleteUni]
ON  [dbo].[Universities] 
INSTEAD OF DELETE
AS 
DECLARE @UniId int
SELECT @UniId = UniversityId FROM deleted
BEGIN
--Remove constraints
DELETE FROM dbo.CityUniversities WHERE UniversityId = @UniId;
DELETE FROM dbo.Universities WHERE UniversityId = @UniId;
END
4

1 に答える 1

4

トリガーが実行される前に制約がチェックされるため、トリガーを使用して他のテーブルから孤立したレコードを削除することはできません。代わりに、 ONDELETECASCADEを設定する必要があります。

削除する前にチェックを実行する場合にもINSTEADOFトリガーを使用できますがdelete Universities where ...、実際にレコードを削除するには、トリガーの最後に追加することを忘れないでください。

トリガーに関する2つのポイント:

  • トリガー本体の先頭にSETNOCOUNTONを追加して、トリガー内のSQLステートメントが、コードの呼び出しで必要になる可能性のある「影響を受ける行」の値を変更する可能性を回避します。
  • 削除および挿入されたテーブルを、1つのレコードのみが含まれているように扱わないでください。2つの大学を削除しようとすると、厄介な驚きがあります。削除または挿入されたテーブルを使用して作業するテーブルを、それらをフィルターとして使用して結合するか、次のように使用する必要があります。

    delete dbo.CityUniversities
      from dbo.CityUniversities
     inner join deleted
        on dbo.CityUniversities.UniversityId = deleted.UniversityId 
    

また

delete dbo.CityUniversities
 where exists (select null
                 from deleted
                where deleted.UniversityId =dbo.CityUniversities.UniversityId)

ああ、そして

SELECT @UniId = (SELECT UniversityId FROM deleted)

と同等です:

SELECT @UniId = UniversityId FROM deleted
于 2012-05-02T10:03:52.843 に答える