【问题标题】:How to update existing rows via trigger with C# in SQL如何在 SQL 中使用 C# 触发器通过触发器更新现有行
【发布时间】:2016-07-24 19:13:54
【问题描述】:

我在 SQL 中有一个名为 EmpLog 的表,其中包含员工的“开始”和“结束”数据。我对如何在更新期间更改触发器中的变量感到非常困惑,因为它必须迎合所有不同的员工。对于每次插入,我是否需要通过 c# 中的 sql 参数更改触发器?还是有其他方法可以保持最小和高效?先感谢您。因为据我所知,触发器是硬编码到数据库中的,可以通过“ALTER”进行更改。如何通过触发器更改具有不同 ID 的现有行?

create trigger TrgEmpLog on EmpLog
AFTER UPDATE
AS
declare @shiftstart time;
declare @shiftend time;
declare @totalminutes decimal(18,2);

IF EXISTS (SELECT shiftend FROM EmpLog WHERE EmpID = "C# Variable" and CONVERT(date,LogDate) = CONVERT(date, GETDATE()) and shiftend is not null)
    BEGIN  
        IF EXISTS (SELECT EmpLog.TotalMinutes from EmpLog WHERE EmpID = "C# Variable" and CONVERT(date,LogDate) = CONVERT(date, GETDATE()) and TotalMinutes is not null)
            BEGIN
                ROLLBACK TRANSACTION
            END 
                ELSE
                select @shiftstart=EmpLog.ShiftStart from EmpLog where EmpID = "C# Variable" and CONVERT(date,LogDate) = CONVERT(date, GETDATE()) and TotalMinutes IS NULL; 
                select @shiftend=EmpLog.ShiftEnd from EmpLog where EmpID = "C# Variable" and CONVERT(date,LogDate) = CONVERT(date, GETDATE()) and TotalMinutes IS NULL;     
                select @totalminutes=DATEDIFF(MINUTE,@shiftstart, @shiftend);   
                UPDATE EmpLog
                SET TotalMinutes=@totalminutes/60.00
                WHERE EmpID= "C# Variable"and CONVERT(date,LogDate) = CONVERT(date, GETDATE());
    END
        ELSE
            BEGIN
                ROLLBACK TRANSACTION
            END

我用来提示触发器的代码是:

UPDATE EmpLog
SET ShiftEnd = 'current time'
WHERE EmpID='C# variable' and CONVERT(date,LogDate) = CONVERT(date, GETDATE());

下面的代码以触发器结束,但是当我删除'和 logDate = getdate() 时它可以工作。 UPDATE EmpLog SET ShiftEnd = '09:00:00' WHERE EmpID = 1 和 CONVERT(date, LogDate) = CONVERT(date, GETDATE())

【问题讨论】:

  • 你能具体说明问题是什么吗?
  • 很抱歉不清楚,我不熟悉 SQL。我无法理解我将如何使用具有不同“WHERE”变量的触发器的逻辑,因为据我所知它是硬编码到数据库中的。
  • 不能将参数传递给触发器。您可以使用存储过程来做到这一点。如果您的逻辑很复杂,而您的逻辑似乎很复杂,那么应该使用存储过程。触发器用于在插入、更新或删除数据时必须运行的轻量级操作,例如更新用户 ID 和记录上的更新日期。您的 TotalMinutes 字段甚至可以用于表格上的计算字段。
  • 我不同意。触发器可能非常复杂。您可以在触发器中执行任何操作。它只是一个存储过程,其中包含一个隐式可用的受影响行的虚拟表。此外,它提供了回滚数据操作的可能性。不要改变触发器。在绑定器中使用一个逻辑,该逻辑会考虑多种场景。
  • @Massimiliano Carosi 您如何建议我让触发器使用不同的变量?

标签: c# sql-server triggers sql-insert


【解决方案1】:

下面的代码通过一些快速测试对我有用。也许它会满足你的需要。实际的触发器部分可能就是你真正需要的,其余部分我用来测试。

这样写,它只会更新当前的相关记录(当时正在更新的记录)。加入inserted 表可确保发生这种情况。 Use the inserted and deleted Tables (MSDN)

CREATE TABLE EmpLog (EmpID int, ShiftStart time, Shiftend time, LogDate date, TotalMinutes decimal(18,2));
GO

-- Trigger starts here
CREATE TRIGGER TrgEmpLog ON EmpLog
AFTER UPDATE
AS

IF EXISTS (SELECT * 
    FROM EmpLog A JOIN inserted B 
    ON A.EmpID = B.EmpID
    WHERE CONVERT(date, A.LogDate) = CONVERT(date, GETDATE()) 
        AND A.shiftend IS NOT NULL)
BEGIN  
    IF EXISTS (SELECT * 
            FROM EmpLog A JOIN inserted B 
            ON A.EmpID = B.EmpID        
            WHERE CONVERT(date, A.LogDate) = CONVERT(date, GETDATE()) 
            AND A.TotalMinutes IS NOT NULL)
        BEGIN
            ROLLBACK TRANSACTION
        END 
            UPDATE EmpLog
            SET TotalMinutes=DATEDIFF(MINUTE, A.ShiftStart, A.Shiftend)/60.00
            FROM EmpLog A JOIN inserted B 
            ON A.EmpID = B.EmpID;
END
ELSE
BEGIN
    ROLLBACK TRANSACTION
END

GO
-- Trigger End here

INSERT INTO EmpLog (EmpID, ShiftStart, Shiftend, LogDate) VALUES (1, '00:00:00', NULL, GETDATE()),
    (2, '08:00:00', NULL, GETDATE()),
    (3, '16:00:00', NULL, GETDATE());

SELECT * FROM EmpLog;

UPDATE EmpLog SET Shiftend = '08:00:00' WHERE EmpID = 1;

SELECT * FROM EmpLog;

DROP TABLE EmpLog;

如果IF EXISTS 不完全按照你的逻辑,你可能不得不玩弄它们。

正如@massimiliano 在 cmets 中提到的,如果您愿意,触发器可能会变得非常复杂。对我来说,我避免这种情况。在解决问题时,触发器始终是我认为最后要看的地方之一。个人喜好!

祝你好运!

【讨论】:

  • 虽然我想知道为什么当我将“LogDate”添加到 WHERE 时它会显示“事务以触发器结束。批处理已中止”。我会把它编辑到原帖上
  • 您可能需要考虑从中删除 ROLLBACK TRANSACTION 语句。我把它们留在里面是因为我认为你可能有理由保留它们。触发器,正如它所写的那样,只有在满足IF EXISTS 条件时才会进行更新,因此如果不满足,则无需回滚任何内容。
猜你喜欢
  • 2012-06-17
  • 1970-01-01
  • 2016-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-29
  • 2015-01-20
  • 1970-01-01
相关资源
最近更新 更多