2016-11-19 112 views
0

我不知道它是否可行。 我有一個表,爲圖書問題return.There的紀錄保持兩列是[狀態]和其他[bookid]。我想在sql中添加一個約束,將限制用戶插入重複記錄status = 「問題」與同一個bookid。SQL或LINQ到SQL基於兩列的唯一約束值

例如,如果已經有status ='issue'和bookid = 1的記錄,那麼它不允許插入status =「issue」和bookid = 1的其他記錄,但是我可以使用其他狀態像staus ='return'和bookid = 1可能會發生多次。

,或者可能使用LINQ在C#

+0

請用你正在使用的數據庫標記你的問題。 –

回答

1

你並不需要一個用戶定義的函數,在一般CHECK約束。在SQL Server(和許多其他數據庫),你可以使用篩選指標:

create unique index unq_bookissue 
    where status = 'issued' ; 

在早期版本的SQL Server,您可以與計算列做到這一點,假設你有諸如列的表:

  • BookId,它跨行重複。
  • Status,當值爲issue時應該是唯一的。
  • BookIssueId,它唯一地標識每一行。

然後,添加一個計算列保持status = 'issue'跟蹤:

create unique index unq_bookid_issue on (BookId, computed_bookissueid); 
+0

由於這是在語法 變化不大的工作創建唯一索引unq_bookissuedReference 對圖書(book_id),其中[狀態] =「發出」 – jitender

1

到SQL您有一個複雜的條件在這裏,所以UNIQUE約束不會幫助你解決。您將需要一個CHECK約束。

首先,您需要一個函數做你的檢查:

CREATE FUNCTION dbo.IsReturnDuplicate 
(
    @id INT, 
    @bookid INT, 
    @status VARCHAR(MAX) 
) 
RETURNS BIT 
AS 
BEGIN 
    RETURN (SELECT TOP 1 COUNT (*) FROM bookreturns WHERE (id <> @id) AND (status = @status) AND (bookid = @bookid) AND (status = 'issue') 
END 

這將返回1,如果已經存在具有狀態「的問題」,並有不同的ID的表中的行

然後,您可以創建一個使用此功能

CREATE TABLE bookreturns (
    --... 
    CONSTRAINT CK_bookreturns_status CHECK (dbo.IsReturnDuplicate(id, bookid, status) == 0) 
) 
0

使用Gordon answer

create unique index unq_bookissuedReference 
on Books(Book_id) where [status] = 'issued' 

alter table t add computed_bookissueid as (case when status = 'issue' then -1 else BookIssueId end); 

此列和BookId現在添加一個唯一索引

對我而言

+0

凡是工作。如果您的唯一索引變得太大,您仍然可以切換到檢查約束,這不會增加數據庫大小。 – Sefe

+0

@safe我也試過你的解決方案,它也能正常工作 – jitender