我正在为大学工作建立数据库。在某些时候,我们必须创建一个触发器/函数,以考虑到不同的外键来限制在SQL Server Management Studio 17上插入记录。例如,我们可以有100条记录,但是同一外键只能有50条记录。
我们有这个约束:
CREATE TABLE [dbo].[DiaFerias] WITH CHECK
ADD CONSTRAINT [Verificar22DiasFerias]
CHECK (([dbo].[verificarDiasFerias]((22)) ='True'))
借助此功能:
ALTER FUNCTION [dbo].[verificarDiasFerias] (@contagem INT)
RETURNS VARCHAR(5)
AS
BEGIN
IF EXISTS (SELECT DISTINCT idFuncionario, idDiaFerias
FROM DiaFerias
GROUP BY idFuncionario, idDiaFerias
HAVING COUNT(*) <= @contagem)
RETURN 'True'
RETURN 'False'
END
答案 0 :(得分:2)
我会在这里使用触发器吗?是,很不情愿(请参阅Enforce maximum number of child rows,了解如何在不使用触发器的情况下以我从未推荐的方式进行操作)。我会使用该功能吗?不。
我将创建一个索引视图:
CREATE VIEW dbo.DiaFerias_Counts
WITH SCHEMABINDING
AS
SELECT idFuncionario, idDiaFerias, COUNT_BIG(*) as Cnt
FROM dbo.DiaFerias
GROUP BY idFuncionario, idDiaFerias
GO
CREATE UNIQUE CLUSTERED INDEX PK_DiaFerias_Counts on
dbo.DiaFerias_Counts (idFuncionario, idDiaFerias)
为什么这样做?因此,SQL Server会自动为我们维护这些计数,因此我们不必在触发器中编写范围广泛的查询。我们现在可以编写触发器,例如:
CREATE TRIGGER T_DiaFerias
ON dbo.DiaFerias
AFTER INSERT, UPDATE
AS
SET NOCOUNT ON;
IF EXISTS (
SELECT
*
FROM dbo.DiaFerias_Counts dfc
WHERE
dfc.Cnt > 22
AND
(EXISTS (select * from inserted i
where i.idFuncionario = dfc.idFuncionario AND i.idDiaFerias = dfc.idDiaFerias)
OR EXISTS (select * from deleted d
where d.idFuncionario = dfc.idFuncionario AND d.idDiaFerias = dfc.idDiaFerias)
)
)
BEGIN
RAISERROR('Constraint violation',16,1)
END
希望您能看到它是如何工作的-我们只想查询可能受到引起我们触发的因素影响的项目的计数-因此我们使用inserted
和deleted
来限制搜索。
我们拒绝任何大于22的更改,这与您的函数不同,后者仅在每个大于22时才开始拒绝行。