是否可以创建一个约束来阻止同一Col2
上的不同 Col1
,其中第一列不能是NULL
而不是第二列?< / p>
为了澄清我的要求,请考虑使用单行的示例数据:
MaterialNumber(varchar50, not null) fiModel(int, null, fk)
1234-4321 1
是否可以阻止具有相同MaterialNumber
但不同fiModel
的第二行?
Here's一个sql-fiddle,第二个INSERT
应该失败,因为它是一个具有相同数字的不同模型。
如果链接腐烂:
(简化)表:
CREATE TABLE [dbo].[tabSparePartMasterData](
[MaterialNumber] [varchar](50) NOT NULL,
[fiModel] [int] NULL)
两行,第二次插入不可能:
INSERT INTO tabSparePartMasterData(MaterialNumber,fiModel)
VALUES('1234-4321', 1);
INSERT INTO tabSparePartMasterData(MaterialNumber,fiModel)
VALUES('1234-4321', 2);
请注意,fiModel
可以是null
,但如果它不为空,则无法添加相同或不同 fiModel
的其他行。我已经使用计算列解决了MaterialNumber
+ fiModel
(非空)上的唯一索引。但我坚持如何阻止不同的fiModel
。
答案 0 :(得分:3)
您可以向表中添加持久列以支持此条件约束。如果您不想更改此表,则可以使用投影ChkMaterialNumber
列并对其执行唯一约束的视图实现相同的策略。
CREATE TABLE [dbo].[tabSparePartMasterData]
(
[YourPK] int identity(1,1) not null primary key,
[MaterialNumber] [varchar](50) NOT NULL,
[fiModel] [int] NULL
);
go
--add a computed column here to enforce the conditional constraint:
alter table [dbo].[tabSparePartMasterData] add [ChkMaterialNumber] as ( case when fiModel is null then cast(YourPK as varchar) else MaterialNumber end)
--now add unique constraint to the computed column:
create unique index ux_SparePartMasterData on [dbo].[tabSparePartMasterData]([ChkMaterialNumber]);
go
-- OK
INSERT INTO tabSparePartMasterData(MaterialNumber,fiModel)
VALUES('1234-4321', 1);
-- FAILS
INSERT INTO tabSparePartMasterData(MaterialNumber,fiModel)
VALUES('1234-4321', 2);
--OK
INSERT INTO tabSparePartMasterData(MaterialNumber,fiModel)
VALUES('1234-4321', null);
答案 1 :(得分:0)
在解决问题之后编辑我的答案。
我认为最好的解决方案,而不是使用触发器或函数是创建一个类型为UNIQUEIDENTIFIER的新列(我将其命名为fiModel1),应始终使用NEWID()填充。
然后创建一个计算列,如:
ALTER TABLE [dbo].[tabSparePartMasterData]
ADD UNIQUECONST as cast([MaterialNumber] as varchar(150)) + case when fiModel is null then cast(fiModel1 as varchar(150)) else '' end PERSISTED
之后,为此列创建一个约束,如:
ALTER TABLE [dbo].[tabSparePartMasterData]
ADD CONSTRAINT AK_MaterialNumber UNIQUE (UNIQUECONST);
最后,您可以添加前3个记录,但不能添加最后一个记录:
INSERT INTO tabSparePartMasterData(MaterialNumber,fiModel, fiModel1) VALUES('1234-4321', null, NEWID());
INSERT INTO tabSparePartMasterData(MaterialNumber,fiModel, fiModel1) VALUES('1234-4321', null, NEWID());
INSERT INTO tabSparePartMasterData(MaterialNumber,fiModel, fiModel1) VALUES('1234-4321', 1, NEWID());
INSERT INTO tabSparePartMasterData(MaterialNumber,fiModel, fiModel1) VALUES('1234-4321', 2, NEWID());
我认为这可以解决你的问题