我在SQL Server 2008中如何防止一個條目在一個表中現有另一個表
- 俱樂部3代表與ID的PK和名稱。
- 有ID的PK,ClubID的FK,名稱,短代碼和關鍵字的產品。
- 有一個英國強制執行ShortCode /關鍵字組合沒有重複的關鍵字。
- ProductAdditionalShortCodes。這具有ID的PK,產品ID的FK和關鍵字
我們的想法是,以防止產品的任何短碼/關鍵詞組合,以指向不同的俱樂部,同時也防止重複的短/代碼關鍵字組合的創建
我有一個可以工作的解決方案,但感覺笨重,並且如果多個用戶同時更新多個條目,可能會在某些情況下失敗。 (假設)
如何向數據庫添加某種形式的約束以防止主表中的關鍵字與附加表中的相同並且相反?
以下是一個示例腳本,用於創建場景以及一些我想要阻止的示例。如果改變的影響不會破壞解決方案的其他方面,我並不反對改變DB設計。 (我意識到這是主觀的)
use Tinker
if exists (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'dbo.ProductAdditionalKeywords') AND type in (N'U'))
drop table dbo.ProductAdditionalKeywords
go
if exists (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'dbo.Products') AND type in (N'U'))
drop table dbo.Products
go
if exists (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'dbo.Clubs') AND type in (N'U'))
drop table dbo.Clubs
go
create table dbo.Clubs (
ID int not null identity(1,1)
,Name varchar(50) not null
,constraint PK_Clubs primary key clustered (ID)
)
go
alter table dbo.Clubs add constraint UK_Clubs__Name unique (Name)
go
create table dbo.Products (
ID int not null identity(1,1)
,ClubID int not null
,Name varchar(50) not null
,ShortCode varchar(50) not null
,Keyword varchar(50) not null
,constraint PK_Products primary key clustered (ID)
)
go
alter table dbo.Products add constraint UK_Products__ShortCode_Keyword unique (ShortCode , Keyword)
go
alter table dbo.Products add constraint UK_Products__Name unique (Name)
go
alter table dbo.Products add constraint FK_Products_ClubID foreign key (ClubID) references dbo.Clubs (ID)
go
create table dbo.ProductAdditionalKeywords (
ID int not null identity(1,1)
,ProductID int not null
,Keyword varchar(50) not null
,constraint PK_ProductAdditionalKeywords primary key clustered (ID)
)
go
alter table dbo.ProductAdditionalKeywords add constraint FK_ProductAdditionalKeywords_ProductID foreign key (ProductID) references dbo.Products (ID)
go
alter table dbo.ProductAdditionalKeywords add constraint UK_ProductAdditionalKeywords__Keyword unique (Keyword)
go
insert into dbo.Clubs (Name)
select 'Club 1'
union all select 'Club 2'
insert into dbo.Products (ClubID,Name,Shortcode,Keyword)
select 1,'Product 1','001','P1'
union all select 1,'Product 2','001','P2'
union all select 1,'Product 3','001','P3'
union all select 2,'Product 4','002','P4'
union all select 2,'Product 5','002','P5'
union all select 2,'Product 6','002','P6'
insert into dbo.ProductAdditionalKeywords (ProductID,Keyword)
select 1,'P1A'
union all select 1,'P1B'
union all select 2,'P2A'
union all select 2,'P2B'
/*
What can be done to prevent the following statements from beeing allowed based on the reason in the comments?
*/
--insert into dbo.ProductAdditionalKeywords (ProductID,Keyword) values (1 , 'P2') -- Main keyword for product 2
--update dbo.Products set Keyword = 'P1A' where ID = 2 -- Additional keyword for product 1
--insert into dbo.ProductAdditionalKeywords (ProductID,Keyword) values (3 , 'P1') -- Main ShortCode/Keyword combination for product 1
/*
At the moment I look at the following view to see if the proposed(new/updated) Keyword/Shortcode combination already exists
If it already exists I pevent the insert/update
Is there any way to do it in the DB via constraints rather than in the BLL?
*/
select ShortCode,Keyword,count([ClubID]) as ClubCount from
(
select p.ClubID,p.ShortCode,p.Keyword,p.ID
from dbo.Products p
union all
select p.ClubID,p.ShortCode,PAK.Keyword,PAK.ID * -1
from dbo.ProductAdditionalKeywords as PAK
inner join dbo.Products P on PAK.ProductID = P.ID
) as FullList
group by Shortcode,Keyword
order by Shortcode,Keyword
「產品」表中的關鍵字有什麼特殊之處,與「ProductAdditionalShortCodes」表中的(似乎命名錯誤的)表中的不同? – 2011-05-05 12:49:41
@damien:這是「主要」關鍵字。額外的/其他的是人們使用和期望工作的錯誤拼寫。感謝錯誤命名的地方。我已糾正它。 :) – 2011-05-05 14:04:08