The*_*lin 1 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
Run Code Online (Sandbox Code Playgroud)
该表一次接收多行.我希望能够在日志表中添加一行告诉我插入已经发生.
插入一行时效果很好,但是有多行,触发器不会触发.我在这里阅读了其他项目,很明显你不应该使用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();
}
}
Run Code Online (Sandbox Code Playgroud)
我不想知道插入了什么,但是当它发生时,我可以运行一组SPROCS来清理和转动数据.
TIA
问题是您的触发器假定只更新一行.标量变量只能有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
Run Code Online (Sandbox Code Playgroud)
请注意我在braces({})中的注释或部分.
编辑:肖恩,他已经删除了他的答案,使用GROUP BY.我复制了你的确切方法,但是,很GROUP BY可能是你想要的条款,而不是OVER.