我在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