SQL Server删除困境

时间:2012-02-14 10:56:11

标签: sql-server referential-integrity

CREATE TABLE [dbo].[ProjectTasks]
(
    [TaskID] [int] IDENTITY(1,1) NOT NULL,
    ...
    [DefaultTaskValue] [int] NULL
)

ALTER TABLE [dbo].[ProjectTasks] ADD  CONSTRAINT [PK_ProjectTasks] PRIMARY KEY 
CLUSTERED 
(
    [TaskID] ASC
)

ALTER TABLE [dbo].[ProjectTasks] ADD CONSTRAINT [FK_ProjectTasks_TaskValues] 
FOREIGN KEY([TaskID], [DefaultTaskValue])
REFERENCES [dbo].[TaskValues] ([TaskID], [Value])
GO

CREATE TABLE [dbo].[TaskValues]
(
    [TaskID] [int] NOT NULL,
    [Value] [int] NOT NULL,
    ...
)

ALTER TABLE [dbo].[TaskValues] ADD  CONSTRAINT [PK_TaskValues] PRIMARY KEY CLUSTERED 
(
    [TaskID] ASC,
    [Value] ASC
)

ALTER TABLE [dbo].[TaskValues] ADD CONSTRAINT [FK_TaskValues_ProjectTasks] 
FOREIGN KEY([TaskID])
REFERENCES [dbo].[ProjectTasks] ([TaskID])
GO

鉴于上述情况,两个表中都没有记录可以删除 - 有没有任何简洁的解决方案?我喜欢做的是对设计进行排序,使链接表成为纯链接表,而不是自身携带值。到目前为止,这不是一个问题,因为永远不需要实际删除行(它们被标记,但实际上没有被删除),当然你可以插入,因为DefaultValue可以是NULL。

编辑:为了回应我的标记,我应该提到,我已经考虑了ON DELETE CASCADE和TRIGGER,我正在寻找这些场景的替代方案,显然ON DELETE SET NULL将不起作用。

2 个答案:

答案 0 :(得分:1)

我对你的陈述感到惊讶

  

当然你可以插入,因为DefaultValue可以是NULL

并且必须查找它。 MSKB

  

具体而言,如果已在列上定义了复合外键   在插入或插入时允许空值和至少一个列   更新一行,设置为null,然后外键约束将   满意。即使相关中没有行,也是如此   与任何相应列匹配的表。

我想我不知道这些信息。所以我建议使用以下命令:

UPDATE ProjectTasks SET DefaultTaskValue = NULL *W
DELETE TaskValues *W
DELETE ProjectTasks *W

* W是您的WHERE条件(在TaskID等上)

答案 1 :(得分:0)

一种解决方案是删除DefaultTaskValue列并创建另一个DefaultTaskvalues表。这样,所有列都可以设置为NOT NULL并根据需要设置级联效果。

ProjectTasks表:

CREATE TABLE [dbo].[ProjectTasks]
(
    [TaskID] [int] IDENTITY(1,1) NOT NULL,
    ...
                         --- removed: DefaultTaskValue] [int] NULL
)

ALTER TABLE [dbo].[ProjectTasks] 
  ADD CONSTRAINT [PK_ProjectTasks] 
  PRIMARY KEY CLUSTERED 
(
    [TaskID] ASC
)
GO

TaskValues表:

CREATE TABLE [dbo].[TaskValues]
(
    [TaskID] [int] NOT NULL,
    [Value] [int] NOT NULL,
    ...
)

ALTER TABLE [dbo].[TaskValues] 
  ADD CONSTRAINT [PK_TaskValues] 
  PRIMARY KEY CLUSTERED 
(
    [TaskID] ASC,
    [Value] ASC
)

ALTER TABLE [dbo].[TaskValues]
  ADD CONSTRAINT [FK_TaskValues_ProjectTasks] 
  FOREIGN KEY([TaskID])
  REFERENCES [dbo].[ProjectTasks] ([TaskID])
GO

DefaultTaskValues表:

CREATE TABLE [dbo].[DefaultTaskValues]
(
    [TaskID] [int] NOT NULL,
    [Value] [int] NOT NULL,
    ...
)

ALTER TABLE [dbo].[DefaultTaskValues] 
  ADD CONSTRAINT [PK_DefaultTaskValues] 
  PRIMARY KEY CLUSTERED 
(
    [TaskID] ASC
)

ALTER TABLE [dbo].[DefaultTaskValues] 
  ADD CONSTRAINT [FK_DefaultTaskValues_TaskValues] 
  FOREIGN KEY([TaskID], [Value])
  REFERENCES [dbo].[TaskValues] ([TaskID], [Value])
GO