2016-11-19 110 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