我有一个包含这些字段的表格:
User_id, User_type, User_address
是否可以添加约束,其中只有一条记录可以存在,其中user_type ='xyz'每个user_id?可以有尽可能多的user_type ='abc',但只有一个'xyz'。
我知道这不是最好的设计,但它是目前的,我需要将其锁定一点。
由于
答案 0 :(得分:4)
你需要使用触发器......
CREATE TRIGGER yourTriggerName ON YourTableName
AFTER INSERT,UPDATE
AS
IF EXISTS (SELECT
y.User_id --,COUNT(y.User_Type)
FROM YourTableName y
INNER JOIN inserted i ON y.User_id=i.User_id
WHERE y.User_Type='xyz'
GROUP BY y.User_id
HAVING COUNT(y.User_Type)>1
)
BEGIN
ROLLBACK
END
go
另外,请确保User_id + User_type
上有索引答案 1 :(得分:3)
一个非常常见的问题。我的回答是:
Use Computed Columns to Implement Complex Business Rules
您还可以使用索引视图来完成相同的操作。请注意,如果一次修改多行或使用快照隔离,则将UDF包装在检查约束中可能不起作用:
Scalar UDFs wrapped in CHECK constraints are very slow and may fail for multirow updates
为什么我推荐索引而不是触发? 因为如果我有索引,我100%确定我的所有数据都是干净的。有了触发器,情况并非如此。有时触发器不会触发,有时它们会有错误。另一个触发器可以覆盖这一个。
答案 2 :(得分:1)
我有与Daniel相同的想法,但我认为您的约束需要检查最多1个XYZ类型PER USER:
CREATE FUNCTION CheckUserTypeXyzExistAtMostOnce(@User_id int)
RETURNS bit
AS
BEGIN
DECLARE @count int
SELECT @count = COUNT(*) FROM dbo.MyTable WHERE User_id = @User_id AND User_type = 'xyz'
RETURN @count <= 1
END;
ALTER TABLE dbo.MyTableADD CONSTRAINT UserTypeConstraint CHECK (dbo.CheckUserTypeXyzExistAtMostOnce(User_id));
答案 3 :(得分:0)
我不确定它是最好的方法,但你总能创建一个插入/更新触发器
答案 4 :(得分:0)
您可以使用检查约束来强制执行此规则。
CREATE FUNCTION CheckUserTypeXyzExistAtMostOnce()
RETURNS bit
AS
BEGIN
DECLARE @count int
SELECT @count = COUNT(*) FROM dbo.MyTable WHERE UserType = 'xyz'
RETURN @count <= 1
END;
ALTER TABLE dbo.MyTable
ADD CONSTRAINT UserTypeConstraint CHECK (dbo.CheckUserTypeXyzExistAtMostOnce());