对2列中的任何一列的SQL唯一约束

时间:2015-11-20 13:07:09

标签: sql sql-server sql-server-2008

我在SQL中有一个表,我希望有一个唯一约束,以便两个值中的任何一个都不能存在。

例如,如果我有2列,如果B列中的值不存在于A列或B列中,我希望不插入。

这可能吗?如果可以的话怎么做?

示例:

Column A | Column B
--------------------
     4   |   6

我希望任何试图插入4或6的对象不允许进入表

3 个答案:

答案 0 :(得分:0)

您可以创建一个接受这些值的功能。在它上面创建一个检查约束(引用你的函数返回值)。

create table t11 (Code int, code2 int)

create function fnCheckValues (@Val1 int, @Val2 int)
Returns int /*YOu can write a better implementation*/
as
Begin
 DECLARE @CntRow int  
 IF(@Val1 IS NULL OR @Val2 IS NULL) RETURN 0    
 select @CntRow = count(*)  from t11   
    where Code in (@Val1,@Val2 ) or Code2 in (@Val1,@Val2 ) 

 RETURN @CntRow  
End

GO

alter table t11 Add constraint CK_123 check ([dbo].[fnCheckValues]([Code],[code2])<=(1))

答案 1 :(得分:0)

使用ROLLBACK TRANSACTION进行触发即可。

create trigger dbo.something after insert as
begin
    if exists ( select * from inserted where ...check here if your data already exists... )
    begin
        rollback transaction
        raiserror ('some message', 16, 1)
    end
end

答案 2 :(得分:0)

当想要强制执行数据库引擎不提供的多行约束时,显而易见的解决方案是使用触发器或存储过程。这通常不起作用,因为数据库隔离了触发器和存储过程运行的事务,允许违反并发性。

而是将约束转换为数据库引擎将强制执行的操作。

CREATE TABLE dbo.T (A INT, B INT)
GO

CREATE TABLE dbo.T_Constraint_Helper (ColumnName sysname PRIMARY KEY)
INSERT INTO dbo.T_Constraint_Helper (ColumnName)
VALUES ('A'), ('B')
GO

CREATE VIEW T_Constraint_VW 
WITH SCHEMABINDING AS 
SELECT CASE CH.ColumnName WHEN 'A' THEN T.A ELSE T.B END AS Value
FROM dbo.T
CROSS JOIN dbo.T_Constraint_Helper CH
GO

CREATE UNIQUE CLUSTERED INDEX FunnyConstraint_VW_UK ON dbo.T_Constraint_VW (Value)
GO

INSERT INTO T VALUES (1, 2)
-- works
INSERT INTO T VALUES (2, 3)
-- Msg 2601, Level 14, State 1, Line 1
-- Cannot insert duplicate key row in object 'dbo.T_Constraint_VW' with unique index 'T_Constraint_VW_UK'. The duplicate key value is (2).
INSERT INTO T VALUES (4, 4)
-- Msg 2601, Level 14, State 1, Line 1
-- Cannot insert duplicate key row in object 'dbo.T_Constraint_VW' with unique index 'T_Constraint_VW_UK'. The duplicate key value is (4).
INSERT INTO T VALUES (5, 6)
-- works