【发布时间】:2021-07-06 21:20:44
【问题描述】:
我正在尝试创建一个在插入新行时执行的触发器。 触发器的目标是每次雇主借钱时向表中添加信息。
插入触发器的表:Employer.Loan
ID ToolId CardId Time
1 4 1001 2021-05-08 15:41:47
触发器应该插入信息的表:Employer.LoanStats
CardId Year Month Quantity
例如,我想向 Loan 表添加值:
INSERT INTO Employer.Loan(ToolId,CardId,Time) *ID is automatic
VALUES (3, 1005, GETDATE() - 40, 3, 1005, GETDATE(), (4, 1002, GETDATE())
LoanStats 表中的结果很好:
CardId Year Month Quantity
1005 2021 4 1
1005 2021 3 1
1002 2021 4 1
但是,当我尝试添加更多值时,它会停止工作并给出 NULL 值:
INSERT INTO Employer.Loan(ToolId,CardId,Time) *ID is automatic
VALUES (3, 1005, GETDATE() - 40, (4, 1003, GETDATE())
结果:
CardId Year Month Quantity
---------------------------
1005 2021 4 2
1005 2021 3 NULL
1002 2021 4 1
1003 2021 4 NULL
我尝试了以下方法:
CREATE TRIGGER AddStats
ON Employer.Loan
FOR INSERT
AS
IF (SELECT COUNT(*) FROM inserted) > 0
BEGIN
DECLARE @CardId int,
@Year int,
@Month int,
@Time DATE
DECLARE Updated CURSOR FOR
SELECT CardId, Time
FROM inserted
OPEN Updated
FETCH NEXT FROM Updated INTO @CardId, @Time
WHILE (@@FETCH_STATUS = 0)
BEGIN
SET @Year = DATEPART(YEAR, @Time)
SET @Month = DATEPART(MONTH, @Time)
IF EXISTS (SELECT * FROM Employer.LoanStats
WHERE CardId = @CardId AND Year = @Year AND Month = @Month)
BEGIN
UPDATE Employer.LoanStats
SET Quantity = (SELECT Employer.LoanStats.Quantity + 1
FROM inserted
WHERE inserted.CardId = Employer.LoanStats.CardId
AND Employer.LoanStats.Month = @Month
AND Employer.LoanStats.Year = @Year)
WHERE CardId IN (SELECT CardId FROM inserted)
END
ELSE
BEGIN
INSERT INTO Employer.LoanStats (CardId, Year, Month, Quantity)
VALUES (@CardId, @Year, @Month, 1)
END
FETCH NEXT FROM Updated INTO @CardId, @Time
END
CLOSE Updated
DEALLOCATE Updated
END
【问题讨论】:
-
拜托 - 光标在任何地方都不好 - 但在 触发器 中,这可能只是你 WORST 的事情可以做!您应该将触发器重写为正确地基于集合 - 不要使用触发器!很可能,这也可以解决您遇到的问题....
-
你的触发器只需要一个
insert和update语句来做你正在做的事情,不需要游标(通常不需要)。因为这将消耗比必要更多的资源,执行插入的事务的所有部分。
标签: sql sql-server tsql triggers