Sql server 在具有限制的表中插入记录
我使用sql server和如下表:Sql server 在具有限制的表中插入记录,sql-server,constraints,Sql Server,Constraints,我使用sql server和如下表: MyTbale(ID int IDENTITY, Type Char(1), ParentId int) 我想限制我的用户插入第一条记录时使用的ParentId类型为'O',并且可以插入其他记录时使用的ParentId类型为每种类型。换句话说,如果用户想要插入ParentId=10的记录,必须将Type设置为'O',然后可以插入ParentId=10的每个类型 样本数据: Id Type ParentId 1 O 10 2
MyTbale(ID int IDENTITY, Type Char(1), ParentId int)
我想限制我的用户插入第一条记录时使用的ParentId类型为'O',并且可以插入其他记录时使用的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
而不是触发器将是一条出路。此外,如果您不需要返回错误信息,您可能会通过此稍加修改的建议获得一些性能:
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
您绝对不能对此使用检查约束。我认为扳机是最好的选择。我编辑我的问题。我可以使用约束和触发器,但正在寻找最佳解决方案。您的条件错误,您必须使用I.Type='O'或t。Id不为null。