Sql server 2005 - 在所有相关表中删除级联

时间:2010-10-28 11:16:02

标签: sql-server-2005

CREATE Table A
(
 AId int ,
 AName varchar(100)
)

CREATE Table B
(
 BId int,
 AId int,
 CId int,
 BName varchar(100)
)

CREATE Table C
(
 CId int,
 CName varchar (100)

)

“A”在“B”中有外键,“C”在B中也有外键。两个外键都启用了级联删除。

外键: -

/****** Object:  ForeignKey [FK_B_A]    Script Date: 10/28/2010 17:20:16 ******/
ALTER TABLE [dbo].[B]  WITH CHECK ADD  CONSTRAINT [FK_B_A] FOREIGN KEY([AId])
REFERENCES [dbo].[A] ([AId])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[B] CHECK CONSTRAINT [FK_B_A]
GO
/****** Object:  ForeignKey [FK_B_C]    Script Date: 10/28/2010 17:20:16 ******/
ALTER TABLE [dbo].[B]  WITH CHECK ADD  CONSTRAINT [FK_B_C] FOREIGN KEY([CId])
REFERENCES [dbo].[C] ([CId])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[B] CHECK CONSTRAINT [FK_B_C]
GO

- 样本数据

INSERT INTO A
VALUES (1, 'Ashish')
INSERT INTO A
VALUES (2, 'Sanjay')
INSERT INTO A
VALUES (3, 'Vivek')

INSERT INTO B
VALUES
(1,1,10,'Ashish1')
INSERT INTO B
VALUES
(2,1,11,'Ashish2')
INSERT INTO B
VALUES
(3,1,12,'Ashish3')


INSERT INTO B
VALUES
(4,2,13,'Ashish1')
INSERT INTO B
VALUES
(5,2,14,'Sanjay')
INSERT INTO B
VALUES
(6,3,15,'Vivek')

INSERT INTO C
VALUES
(10, 'Ashish Data1')
INSERT INTO C
VALUES
(11, 'Ashish Data2')

INSERT INTO C
VALUES
(12, 'Ashish Data3')

INSERT INTO C
VALUES
(13, 'Ashish Data4')

INSERT INTO C
VALUES
(14, 'sanjay Data1')

INSERT INTO C
VALUES
(15, 'Vivek Data1')

我认为以下会删除所有表格中的所有数据: -

DELETE a FROM A a
INNER JOIN B ON A.AId = B.AId
INNER JOIN C ON B.CId = C.CID

相反,我不得不写这个: -

DELETE a FROM A a
INNER JOIN B ON A.AId = B.AId

DELETE b FROM B b
INNER JOIN C ON B.CId = C.CID

有没有办法删除单个删除语句中的所有数据?

4 个答案:

答案 0 :(得分:1)

基本上,如果我理解正确,你只能删除'b'中的数据,它会删除'a'和'c'中的数据。

A< - B [删除] - > ç

来自Microsoft website

  

ON DELETE CASCADE

     

指定如果尝试使用其他表中现有行中的外键引用的键删除行,则还会删除包含这些外键的所有行。如果还在目标表上定义了级联引用操作,则还会对从这些表中删除的行执行指定的级联操作。

答案 1 :(得分:1)

级联删除意味着当对父表执行删除时,子表中相应的行也会删除对父表的引用。

因此,在您的情况下,表B是表A和表C的子表。

因此,您不能使用一个delete语句来删除所有表中的数据。相反,您可以从表A中删除一行,它将从表B中删除相应的子行。

类似地,从表C中删除将从表B中删除其对应的子行。

编辑 - 您编写的查询是删除而没有where子句。因此,如果您尝试删除表A和表C中的所有行,并删除表B中的所有引用行,则可以使用此 -

DELETE FROM A --deletes all rows in A and corresponding referenced rows in B

DELETE FROM C --deletes all rows in C and corresponding referenced rows in B

答案 2 :(得分:0)

嗯,是否可以改变约束?

我看到的问题是C有一个1到多个A,而B有1到多个C,所以不是让AI成为B中的外键,而是让AI成为C中的外键, 因此,如果您从A中删除某个人,它将级联到C,它将级联到B. 如果你从C中删除一个项目,它将级联到B,但不是A,如果你从B中删除一个项目,它将不会影响其他两个表格。

我的建议:

CREATE TABLE [A] (
    [AId] [int] NOT NULL ,
    [AName] [varchar] (100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
    CONSTRAINT [PK_A] PRIMARY KEY  CLUSTERED 
    (
        [AId]
    )  ON [PRIMARY] 
) ON [PRIMARY]
GO

CREATE TABLE [C] (
    [CId] [int] NOT NULL ,
    [CName] [varchar] (100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
    [AId] [int] NULL ,
    CONSTRAINT [PK_C] PRIMARY KEY  CLUSTERED 
    (
        [CId]
    )  ON [PRIMARY] ,
    CONSTRAINT [FK_C_A] FOREIGN KEY 
    (
        [AId]
    ) REFERENCES [A] (
        [AId]
    ) ON DELETE CASCADE 
) ON [PRIMARY]
GO

CREATE TABLE [B] (
    [BId] [int] NOT NULL ,
    [AId] [int] NULL ,
    [CId] [int] NULL ,
    [BName] [varchar] (100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
    CONSTRAINT [PK_B] PRIMARY KEY  CLUSTERED 
    (
        [BId]
    )  ON [PRIMARY] ,
    CONSTRAINT [FK_B_C] FOREIGN KEY 
    (
        [CId]
    ) REFERENCES [C] (
        [CId]
    ) ON DELETE CASCADE  NOT FOR REPLICATION 
) ON [PRIMARY]
GO

通过此设置,Delete From A将一次性清除所有3个表。

编辑:您可以将AI保留在B中以使连接更容易,但它与删除级联没有任何关系。

答案 3 :(得分:0)

您无法使用单个语句从AC删除记录,因为此表不具有传递引用关系。

如果要删除ACB中具有DELETE a FROM a JOIN b ON b.aid = a.aid DELETE c FROM c JOIN b ON b.cid = c.cid 中相应记录的所有记录,则应使用以下两种语句:

{{1}}