在限制表中插入记录

时间:2014-08-02 10:18:33

标签: sql-server constraints

我使用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

1 个答案:

答案 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