0

2つのテーブルがあるとしましょう

CREATE TABLE [dbo].[People](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Nom] [nvarchar](50) NOT NULL,
 CONSTRAINT [PK_People] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

CREATE TABLE [dbo].[Transactions](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [BUYER_ID] [int] NOT NULL,
    [SELLER_ID] [int] NOT NULL,
    [DateTransaction] [datetime] NOT NULL,
 CONSTRAINT [PK_Transactions] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

ロジックは、トランザクション テーブルが people テーブルからの 2 つのレコード、バイヤーとセラーを必要とすることです。

私がやろうとしているのは、BUYER_ID 列と SELLER_ID 列の両方にカスケード削除を実装することです。

ただし、問題なく1つ(どちらか)を追加できますが、2つ目を追加しようとすると、保存するときにエラーメッセージが表示されます...

Unable to create relationship 'FK_Transactions_Buyer'.  
Introducing FOREIGN KEY constraint 'FK_Transactions_Buyer' on table 'Transactions' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

トリガーを使用せずにこれを行う方法はありますか、またはトリガーがこれを行うための最良の方法です

4

2 に答える 2

1

トランザクションを参照する人の FK 制約が原因である可能性があります。そうでない場合は、両方のキーを 1 つの制約に含めることが答えになると思います。買い手と売り手の両方の ID が同じで、個人が削除された場合、両方の制約が同じ行を削除しようとする可能性があります。これは、SQLサーバーが回避しようとする可能性があると私が考えることができる唯一のシナリオです...

申し訳ありませんが、これ以上決定的なことはできません。

于 2013-09-27T13:57:15.233 に答える
0

これが私が最終的に行う方法であり、これが最善の方法であると真剣に疑っています。

外部キー制約を適用しないように外部キーを変更しました。

ALTER TABLE [dbo].[Transactions] NOCHECK CONSTRAINT [FK_Transactions_Buyer]

ALTER TABLE [dbo].[Transactions] NOCHECK CONSTRAINT [FK_Transactions_Seller]

また、トランザクション テーブルを変更して IsDeleted フィールドを追加しました。

[IsDeleted] [bit] NULL

最後に、People テーブルで Buyer_ID または Seller_Id が削除されるたびに、トランザクション テーブルで IsDeleted を TRUE に設定する Delete トリガーを People テーブルに追加しました。

最後に、トリガーの最後に、フラグ IsDeleted が true に設定されているトランザクション内のすべてのレコードを削除します。

CREATE TRIGGER [dbo].[deletePeople]
   ON  [dbo].[People]
   AFTER DELETE
AS 
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;


    DECLARE @DeletedId INT
  SELECT @DeletedId = id FROM deleted  
    -- Insert statements for trigger here
    Update dbo.Transactions SET IsDeleted = 1 WHERE BUYER_ID = @deletedId or SELLER_ID = @deletedId 
    DELETE FROM dbo.Transactions WHERE IsDeleted = 1
END

私が言ったように、これが適切な慣行であるとは思えません

于 2013-09-27T15:16:24.853 に答える