我使用sql server和这样的表:
MyTbale(ID int IDENTITY, Type Char(1), ParentId int)
我想限制我的用户插入带有Type = 'O'
的一些ParentId的第一条记录,并且可以在每个类型中插入带有一些parentId的其他记录。换句话说,如果用户想要插入ParentId = 10的记录,则必须设置Type =' O'然后,可以使用ParentId = 10插入每个类型。
示例数据:
Id Type ParentId
1 O 10
2 I 10
3 I 10
4 M 10
5 N 10
6 O 12
7 M 12
8 I 12
这个问题的最佳解决方案是什么? (我认为我可以使用UDF约束并为此目的触发)。
修改
按照以下格式我可以添加检查约束:
Create FUNCTION [dbo].[f](@Id INT, @Date DATE) RETURNS BIT
AS BEGIN
DECLARE @R BIT = CASE WHEN EXISTS(SELECT Date FROM MyTable WHERE Date=@Date AND Id!=@Id) THEN 1 ELSE 0 END
RETURN @R
END
GO
ALTER TABLE [dbo].[MyTable] WITH CHECK ADD CONSTRAINT [CK_test] CHECK (([dbo].[F]([Id],[Date])=(0)))
并通过以下查询我可以为检查数据添加触发器:
CREATE TRIGGER dbo.tr_MyTable ON dbo.MyTable
INSTEAD OF INSERT
AS BEGIN
IF EXISTS(SELECT *
FROM Inserted i
LEFT JOIN MyTable t ON t.ParentId = i.ParentId AND t.Type = 'O'
WHERE i.Type <> 'O'
AND t.Id IS NULL) BEGIN
RAISERROR('Type must be equal to O in first row',16,1)
END
INSERT INTO dbo.MyTable(Type,ParentId)
SELECT Type, ParentId
FROM Inserted
END
答案 0 :(得分:0)
INTREAD OF TRIGGER将是最佳选择。此外,如果您不需要返回错误信息,您可以通过稍微修改的建议获得一些性能:
CREATE TRIGGER dbo.tr_MyTable ON dbo.MyTable
INSTEAD OF INSERT
AS BEGIN
INSERT INTO dbo.MyTable(Type,ParentId)
SELECT Type, ParentId
FROM Inserted
LEFT JOIN MyTable t ON t.ParentId = i.ParentId AND t.Type = 'O'
WHERE i.Type <> 'O'
AND t.Id IS NULL