Sql server 如何在SQL Server的打印行中写入新的更新输入名称

Sql server 如何在SQL Server的打印行中写入新的更新输入名称,sql-server,triggers,Sql Server,Triggers,我想用这个触发器更新表staff上的staff的名称,然后在更新后用打印行打印新名称,触发器工作正常,但我正在寻找一种写入名称的方法。。。有什么帮助吗 CREATE TRIGGER EditNameStuff ON STAFF AFTER UPDATE AS DECLARE @editName CHAR, @ID_S INT SELECT @editName = DELETED.SNAME FROM DELETED WHERE STAFF_ID = DELE

我想用这个触发器更新表staff上的staff的名称,然后在更新后用打印行打印新名称,触发器工作正常,但我正在寻找一种写入名称的方法。。。有什么帮助吗

CREATE TRIGGER EditNameStuff ON STAFF
AFTER UPDATE
AS
    DECLARE @editName CHAR, @ID_S INT

    SELECT @editName = DELETED.SNAME 
    FROM DELETED 
    WHERE STAFF_ID = DELETED.STAFF_ID;

    IF @editName != (SELECT inserted.SNAME 
                     FROM INSERTED 
                     WHERE STAFF_ID = inserted.STAFF_ID)
    BEGIN
        SELECT @editName = STAFF_ID FROM INSERTED;

        UPDATE STAFF
        SET SNAME = @editName
        WHERE STAFF_ID = @ID_S ;

        PRINT 'Name has been succesfull changed to' [**Name should be here**] ;
    END
GO

更新:marc_s关于避免使用光标的说法是正确的。它们是资源密集型的。如果您的目标是使用触发器打印输出,则可以构建一个要打印的字符串,将其粘贴到变量中,然后打印变量的值。由于一次可以更新多行,并且触发器将一次处理所有行,因此可以使用STUFF和FOR XML PATH为每次更新基本上构建一个以行分隔的语句列表。下面是一个例子:

CREATE TRIGGER TriggerName
ON dbo.Staff
AFTER UPDATE
AS
BEGIN
    SET NOCOUNT ON;     

    DECLARE @output NVARCHAR(MAX)

    SELECT @output = STUFF((SELECT CHAR(10) + 'Name has been changed to ' + ISNULL(SNAME, 'NULL') + ' where STAFF_ID = ' + CAST(STAFF_ID AS VARCHAR(10))
    FROM INSERTED i
    FOR XML PATH ('')), 1, 1, '')

    PRINT @output
END
GO
这里有一个基于光标的解决方案,这也是最好避免的,除非这是一个轻微更新的表,并且很可能扩展到一个高度更新的表

CREATE TRIGGER TriggerName
ON dbo.Staff
AFTER UPDATE
AS
BEGIN
    SET NOCOUNT ON;
    DECLARE @STAFF_ID INT, @ORIG_SNAME VARCHAR(100), @NEW_SNAME VARCHAR(100)

    DECLARE cur CURSOR FOR   
    SELECT i.STAFF_ID, d.SNAME, i.SNAME
    FROM inserted i
    INNER JOIN deleted d ON i.STAFF_ID = d.STAFF_ID
    WHERE (d.SNAME IS NULL AND i.SNAME IS NOT NULL) OR (d.SNAME IS NOT NULL AND i.SNAME IS NULL) OR d.SNAME <> i.SNAME

    OPEN cur  

    FETCH NEXT FROM cur   
    INTO @STAFF_ID, @ORIG_SNAME, @NEW_SNAME

    WHILE @@FETCH_STATUS = 0  
    BEGIN   
        -- custom code goes here!
        PRINT 'Name has been changed to ' + ISNULL(@NEW_SNAME, 'NULL') + ' where STAFF_ID = ' + CAST(@STAFF_ID AS VARCHAR(10))

        FETCH NEXT FROM cur   
        INTO @STAFF_ID, @ORIG_SNAME, @NEW_SNAME
    END   
    CLOSE cur;  
    DEALLOCATE cur;  
END
GO

您的触发器有一个主要缺陷,您似乎认为它每行调用一次,但事实并非如此。每个语句触发一次触发器,因此如果UPDATE语句影响25行,则触发一次触发器,但Inserted和Deleted语句将分别包含25行。您的代码将在此处选择这25行中的哪一行??从插入的位置选择xx,其中….-这是不确定的。你需要重写你的触发器来考虑这一点!在基于此触发器集之后,您希望PRINT语句做什么?您的用户肯定没有直接使用数据库吗?因此,PRINT语句不会对您有任何帮助。您应该不惜一切代价避免使用游标,因为它们是RBAR处理—一行一行地处理—最肯定的是在触发器中!这将扼杀你所有的系统性能-说真的-不要这样做!您需要将其转换为一个适当的、基于集合的solution@marc_s避免使用光标通常是正确的!它们速度慢而且资源密集。不过,我讨厌那种绝对的说法。这不会降低系统性能,除非这是一个频繁使用和更新的表。但是,如果它定期更新,或者您预计它可能会以这种方式扩展,那么您应该避免使用光标。