2010-07-15 5 views
0

Я пытаюсь установить отношение внешнего ключа между таблицей 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" 

ответ

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 (INT, IDENTITY) на вашей таблице Parts, что также упростит ограничение FK!

+0

Этот оператор создает синтаксическую ошибку TSQL –

+0

, поэтому имеет частичный идентификатор (INT IDENTITY) в частях, а затем, каков будет идентификатор связывания в таблице order_items? Я решил, что если бы у меня был номер product_number с самой частью, это логически связало бы эти два.Потому что продукты состоят из частей. Вы можете иметь много частей для одного продукта. – 2010-07-15 21:26:15

+0

@Jose Basilio: thanks - Я пропустил один из многих «E» в ключе «REFERENCES» - исправлен. –

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]) 
+0

На самом деле, да, вы можете иметь этот сценарий - если вы ** можете ** установить УНИКАЛЬНЫЙ ИНДЕКС на Parts.product_number, то вы ** можете ** ссылаться на это как FK из Order_Items, даже если PK все еще (part_number, номер продукта). FK может ** также ** ссылаться на уникальный индекс! –

+0

@Jose: Это не может быть правильно, потому что это делает Order_Items зависимыми от деталей. Я думаю, что было бы наоборот. Поскольку части составляют Заказы. Если вы отмените Order_Items и Parts, я приму это в качестве ответа. – 2010-07-16 01:33:25

+0

@ Чанлинг: у вас здесь все смешалось - Хосе абсолютно прав. То, что вам нужно, это ссылка с Order_Items на Part - не наоборот! Каждый Order_Item имеет/имеет/отправляет ровно одну часть, правильно? –

Смежные вопросы