问题设置外键

时间:2010-07-15 20:50:52

标签: sql sql-server-2005

我正在尝试在Order_Items表和Parts表之间设置外键关系。我想通过外键将部件链接到Order_Items表中的产品。我对其他表格没有任何问题。

以下是Order_Items表的定义方式:

CREATE TABLE [dbo].[Order_Items](
    [order_id] [uniqueidentifier] NOT NULL,
    [product_number] [varchar](50) NOT NULL,
    [quantity_ordered] [int] NOT NULL,
    [product_tested] [bit] NULL,
 CONSTRAINT [PK_Order_Items] PRIMARY KEY CLUSTERED 
(
    [order_id] ASC,
    [product_number] 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
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[Order_Items]  WITH CHECK ADD  CONSTRAINT [FK_Order_Items_Orders] FOREIGN KEY([order_id])
REFERENCES [dbo].[Orders] ([order_id])
GO
ALTER TABLE [dbo].[Order_Items] CHECK CONSTRAINT [FK_Order_Items_Orders]

和零件表:

CREATE TABLE [dbo].[Parts](
    [part_number] [varchar](50) NOT NULL,
    [product_number] [varchar](50) NOT NULL,
    [part_description] [varchar](max) NULL,
    [part_tested] [bit] NULL,
 CONSTRAINT [PK_Parts_1] PRIMARY KEY CLUSTERED 
(
    [part_number] ASC,
    [product_number] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

我尝试在两个product_number列上设置唯一约束,但我仍然在SQL Server 2005 Management Studio Express中收到错误消息:

"The columns in table 'Order_Items' do not match an existing primary key or UNIQUE constraint"

3 个答案:

答案 0 :(得分:3)

问题:如果[product_number]表中的Parts可以通过唯一约束使其唯一 - 为什么它本身不是主键?

我的直觉:[product_number] Parts并非真正独特 - 只有(part_number, product_number)的组合才是唯一的。

如果您可以仅在UNIQUE INDEX列上创建product_number,您应该能够创建FK约束 - 试试这个:

CREATE UNIQUE INDEX UIX01_Parts ON dbo.Parts(product_number)

ALTER TABLE dbo.Order_Items
  ADD CONSTRAINT FK_OrderITems_Parts
    FOREIGN KEY(product_number) REFERENCES dbo.Parts(product_number)

有用吗?如果没有 - 你得到什么错误,以及在哪里??

如果这不起作用,并且只有(part_number, product_number)才真正唯一,那么您需要在外键约束中引用这两列:

ALTER TABLE dbo.Order_Items
  ADD CONSTRAINT FK_OrderItems_Parts
  FOREIGN KEY(part_number, product_number)
    REFERENCES dbo.Parts(part_number, product_number)

当然,这也意味着您需要在Order_Items表中同时包含这两列,以便能够使外键约束起作用。

正如旁注:拥有两个VARCHAR(50)列的复合主键并使Parts表上的聚簇索引成为最佳选择。如果可能的话,尝试使这些“数字”中的一个或两个真正成为数字类型 - 例如INT列。或者,如果不可能,请考虑在PartID表上设置代理Parts列(INT,IDENTITY),这样可以使FK约束更容易!

答案 1 :(得分:2)

为了使这种关系起作用,Parts表不能有复合键。换句话说,您需要使用product_number作为主键,因为它是它们共有的列。您目前将part_number和product_number作为主键。

完成更改后,此声明将起作用:

ALTER TABLE [dbo].[Order_Items]  WITH CHECK 
ADD  CONSTRAINT [FK_Order_Items_Parts] FOREIGN KEY([product_number])
REFERENCES [dbo].[Parts] ([product_number])

答案 2 :(得分:0)

我最终重组了整个数据库,以使其工作并简化表连接。