2017-03-13 56 views
2

我有兩個表頭和Item,它們有一對多關係。阻止在C#或SQL中插入或更新數據

頭表

Id  StartDate EndDate 
--------------------------------------- 
1  1999/1/1 1999/5/1   
2  2000/1/1 2000/4/1 
3  2000/1/1 2000/5/1 

和項目表

Id  HeaderRef SLRef 
------------------------------------- 
101  1   201 
102  2   201 

如何預防與HeaderRef=3添加項目和SLRef=201,因爲它具有相同的SLRef,並且HeaderRef referd它具有StartDate and EndDate頁眉行另一個項目相同SLRef指該範圍內的Header

+1

你試過插入/更新觸發器嗎?你可以寫一些。 – pwas

+1

你想保持在ItemTable中唯一的headerRef和SLRef嗎? –

+1

是的我想保持headerRef和SLRef在添加到Hedar的日期範圍中唯一。 –

回答

2

假設你正在使用的MS SQL Server有才達到你所尋找的兩種方法:

1)由其他用戶儘量使用觸發器。觸發器將用於INSERT/UPDATE,它將檢查日期範圍,並允許添加新值或引發錯誤。

2)您可以在ItemTable使用複合主鍵:

CREATE TABLE [dbo].[ItemTable](
    [Id] [int] IDENTITY(1,1) NOT NULL, 
    [HeaderRef] [int] NOT NULL, 
    [SLRef] [int] NOT NULL, 
PRIMARY KEY CLUSTERED 
(
    [HeaderRef] ASC, 
    [SLRef] 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 

現在,這將提上ItemTable和SQL Server的限制將不允許headerRef和SLRef INT值(鍵)的重複組合。

回到您的HeaderTable,你可以把唯一約束制止重複開始和結束日期

CREATE TABLE [dbo].[HeaderTable](
    [ID] [int] IDENTITY(1,1) NOT NULL, 
    [STARTDATE] [datetime] not NULL, 
    [ENDDATE] [datetime] not NULL, 
CONSTRAINT [PK_HeaderTable] PRIMARY KEY CLUSTERED 
(
    [ID] 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 

的範圍現在您可以創建開始和結束日期上HeaderTable唯一索引。

/****** Object: Index [IX_HeaderTable] Script Date: 03/13/2017 12:24:51 ******/ 
CREATE UNIQUE NONCLUSTERED INDEX [IX_HeaderTable] ON [dbo].[HeaderTable] 
(
    [ENDDATE] ASC, 
    [STARTDATE] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
GO 

你也可以在HeaderTable上添加另一個約束來檢查開始日期是否在結束日期之前。

ALTER TABLE [dbo].[HeaderTable] WITH CHECK ADD CONSTRAINT [CheckEndLaterThanStart] CHECK (([ENDDATE]>=[STARTDATE])) 
GO 

ALTER TABLE [dbo].[HeaderTable] CHECK CONSTRAINT [CheckEndLaterThanStart] 
GO 

希望這有助於!

1

您正在尋找一種DML觸發器,簡單來說,它是某種SQL函數或過程,當用戶試圖通過添加或刪除來更改數據庫內部的數據時會自動調用,同時觸發器的主體可以包含一些驗證邏輯,所以它不會插入數據,除非它滿足一定的條件