不同表上的列的唯一约束

时间:2014-02-12 04:12:27

标签: sql sql-server-2008-r2 unique-constraint

我有三个表a,b和c,每个表都有一个与子表相关的int IDENTITY PK字段。

    CREATE TABLE [dbo].[a]([aID] [int] IDENTITY(1,1) NOT NULL,[aCode] [varchar](20) NOT NULL,
    CONSTRAINT [PK_a] PRIMARY KEY CLUSTERED([aID] ASC)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]) ON [PRIMARY]
    GO
    CREATE TABLE [dbo].[b]([bID] [int] IDENTITY(1,1) NOT NULL,[aID] [int] NOT NULL, [bCode] [varchar](20) NOT NULL,
    CONSTRAINT [PK_b] PRIMARY KEY CLUSTERED([bID] ASC)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]) ON [PRIMARY]
    GO
    CREATE TABLE [dbo].[c]([cID] [int] IDENTITY(1,1) NOT NULL,[bID] [int] NOT NULL,[cCode] [varchar](20) NOT NULL,
    CONSTRAINT [PK_c] PRIMARY KEY CLUSTERED([cID] ASC)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]) ON [PRIMARY]
    GO
    ALTER TABLE [dbo].[b]  WITH CHECK ADD  CONSTRAINT [FK_b_a] FOREIGN KEY([aID])
    REFERENCES [dbo].[a] ([aID])
    GO
    ALTER TABLE [dbo].[b] CHECK CONSTRAINT [FK_b_a]
    GO
    ALTER TABLE [dbo].[c]  WITH CHECK ADD  CONSTRAINT [FK_c_b] FOREIGN KEY([bID])
    REFERENCES [dbo].[b] ([bID])
    GO
    ALTER TABLE [dbo].[c] CHECK CONSTRAINT [FK_c_b]
    GO

如何创建一个强制执行a.aID,c.cCode唯一条件的CONSTRAINT?

3 个答案:

答案 0 :(得分:0)

您可以按如下方式添加唯一约束:

ALTER TABLE [C] ADD CONSTRAINT [uc_C_cCode] UNIQUE NONCLUSTERED [cCode];

但是,您无法在表之间强制执行约束,这听起来就像您尝试的那样。

对于表A.aID,它是一个主键,它已经有一个唯一的约束。

答案 1 :(得分:0)

如果要在列a.aID, c.cCode的组合上寻找唯一约束,一种方法是更改​​表c并向其添加[aid]列并使用复合唯一键。

 ALTER TABLE [dbo].[c](
 [cID] [int] IDENTITY(1,1) NOT NULL,
 [bID] [int] NOT NULL,[cCode] [varchar](20) NOT NULL,
 [cCode] [varchar](20) NOT NULL,
 [aID] INT FOREIGN KEY REFERENCES [a]([aID]) NOT NULL,
 CONSTRAINT uq_cCode_aid UNIQUE NONCLUSTERED (cCode,aID),
 CONSTRAINT [PK_c] PRIMARY KEY CLUSTERED([cID] ASC)
 WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON)
 ON 
[PRIMARY]) ON [PRIMARY]
GO

答案 2 :(得分:0)

我找到了一种方法来使用索引视图来获得我想要的东西(我认为)。请评论这是否合适。到目前为止,我的测试结论是它确实有效。

我创建了一个带有schemabinding的视图,将c连接到a(通过b)。 我创建了一个聚簇索引来强制执行aID和cCode上的唯一索引。

这使我不需要在c表中包含aID,但仍然强制执行唯一约束。

    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    CREATE VIEW [dbo].[vw.aIDcCode] WITH SCHEMABINDING 
    AS
    SELECT     dbo.a.aID, dbo.c.cCode
    FROM         dbo.a 
                 INNER JOIN
                     dbo.b ON dbo.a.aID = dbo.b.aID
                         INNER JOIN
                             dbo.c ON dbo.b.bID = dbo.c.bID
    GO
    SET ARITHABORT ON
    GO
    SET CONCAT_NULL_YIELDS_NULL ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    SET ANSI_NULLS ON
    GO
    SET ANSI_PADDING ON
    GO
    SET ANSI_WARNINGS ON
    GO
    SET NUMERIC_ROUNDABORT OFF
    GO
    CREATE UNIQUE CLUSTERED INDEX [IDX_Unique_aIDcCode] ON [dbo].[vw.aIDcCode] 
    ([aID] ASC, [cCode] ASC)
    WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON)
    ON [PRIMARY]
    GO