多次插入后使用触发器更新日志表

时间:2018-10-01 14:34:51

标签: sql sql-server triggers database-trigger

我有以下触发器:

ALTER TRIGGER [Staging].[tr_UriData_ForInsert]
ON [Staging].[UriData]
FOR INSERT 
AS
BEGIN
    DECLARE @_Serial NVARCHAR(50)
    DECLARE @_Count AS INT

    IF @@ROWCOUNT = 0
        RETURN

    SET NOCOUNT ON;

    IF EXISTS(SELECT * FROM inserted)
    BEGIN
        SELECT @_Count = COUNT(Id) FROM inserted
        SELECT @_Serial = SerialNumber FROM inserted

        INSERT INTO [Staging].[DataLog]
        VALUES (CURRENT_TIMESTAMP, @_Serial + ': Data Insert --> Rows inserted: ' + @_Count, 'New data has been received')
    END 
END

表一次接收多行。我希望能够在日志表中添加一行以告诉我插入已发生。

插入一行时效果很好,但是如果插入多行,触发器不会触发。我在这里还阅读了其他文章,很明显,您不应该使用ROW_NUMBER()

总结:当另一个表UriData中发生多行插入时,我想更新我的日志表。

使用以下命令从C#插入数据:

using (var sqlBulk = new SqlBulkCopy(conn, SqlBulkCopyOptions.Default, transaction))
            {
                sqlBulk.DestinationTableName = tableName;

                try
                {
                    sqlBulk.WriteToServer(dt);
                }
                catch(SqlException sqlEx)
                {
                    transaction.Rollback();
                    var msg = sqlEx.Message;
                    return false;

                }
                finally {
                    transaction.Commit();
                    conn.Close();                     
                }
            }

我不想知道要插入的内容,但是什么时候发生,所以我可以运行一组SPROCS来清理和旋转数据。

The table looks like the image shown

TIA

2 个答案:

答案 0 :(得分:6)

问题在于您的触发器假定将仅更新一行。标量变量只能有1个值。因此,例如,语句SELECT @_Serial = SerialNumber FROM inserted@_Serial设置为对象inserted返回的最后一个值。

按数据集的形式处理数据。这未经测试,但是,我怀疑这会为您提供所需的结果:

ALTER TRIGGER [Staging].[tr_UriData_ForInsert]
ON [Staging].[UriData]
FOR INSERT 
AS
BEGIN

    --No need for a ROWCOUNT. If there are no rows, then nothing was inserted, and this trigger won't happen.

    INSERT INTO [Staging].[DataLog] ({COLUMNS LIST})
    SELECT CURRENT_TIMESTAMP,
           SerialNumber + ': Data Insert --> Rows inserted: ' +
           CONVERT(varchar(10),COUNT(SerialNumber) OVER (PARTITION BY SerialNumber)), --COUNT returns an INT, so this statement would have failed with a conversion error too
           'New data has been received'
    FROM inserted;
END

请注意我的评论或大括号({})中的部分。

编辑:此后删除答案的肖恩(Sean)使用了GROUP BY。我复制了您使用的确切方法,但是,GROUP BY可能是您想要的子句,而不是OVER

答案 1 :(得分:0)

因此,在经过大量的研究和争论之后,我的托管公司告诉我,他们禁用了任何形式的散装插入物,而不必费心通知客户。