Raj*_*mar 4 c# sql-server triggers sqlbulkcopy winforms
我正在使用SqlBulkCopy类在表中一次插入50k行tbl_records
我After Insert在此表上设置了一个触发器并使用以下代码
SqlBulkCopy SqlBc1 = new SqlBulkCopy(strConnString, SqlBulkCopyOptions.FireTriggers);
// Set DataReader For SqlBulkCopy
sqlComm = new SqlCommand(strQuery, sqlTemCon);
sqlComm.CommandTimeout = 3600000;
sqlComm.CommandType = System.Data.CommandType.Text;
SqlDataReader dReader = sqlComm.ExecuteReader();
SqlBc1.WriteToServer(dReader);
Run Code Online (Sandbox Code Playgroud)
但执行前后.它只触发First 50k插入的行
我想它应该为每一行开火.我怎样才能做到这一点??
触发器永远不会每行触发.它们为相应的DML语句的所有行触发.重写您的触发器,以便它可以处理INSERTED包含许多行的表.无论如何,这是最佳实践和必要的练习.
它只触发了从50k行插入的第一行的触发器
您必须误解情况,可能是因为您不知道触发器可以在虚拟表中包含多个行.
如果其他人遇到这个问题并寻找解决方案,我也会在这里发布我的发现。
重要提示:usr 已经给出了答案,但我会稍微解释一下。
首先,这是微软文档中关于批量插入的内容,
如果未指定 FIRE_TRIGGERS,则不会执行任何插入触发器。
FIRE_TRIGGERS 指定在大容量导入操作期间执行在目标表上定义的任何插入触发器。如果为目标表上的 INSERT 操作定义了触发器,则每个完成的批次都会触发它们。
FIRE_TRIGGERS是与 T-SQL 语句一起使用的参数BULK INSERT。
如果您尝试将批量插入与SqlBulkCopy类(.Net Framework/Core)一起使用,则必须使用SqlBulkCopyOptionsEnum (文档)。
构造 SqlBulkCopy 实例时可以使用 SqlBulkCopyOptions 枚举来更改该实例的 WriteToServer 方法的行为方式。
这是一个样本,
var options = SqlBulkCopyOptions.CheckConstraints | SqlBulkCopyOptions.FireTriggers | SqlBulkCopyOptions.KeepIdentity;
var bulkCopy = new SqlBulkCopy(connectionString, options);
Run Code Online (Sandbox Code Playgroud)
好的。现在触发器将通过批量插入运行,但为什么只针对一条记录。FIRE_TRIGGER再次阅读微软关于争论的说法。
如果为目标表上的 INSERT 操作定义了触发器,则每个完成的批次都会触发它们。
这意味着您的触发器将同时运行整个批次。但您的批次包含不止一行。因此,您的触发算法(您应该对单个记录执行的操作)将适用于一条记录,而不是所有记录。
现在您知道为什么它不适用于所有人,因此解决方案是改进触发器以处理多行。这意味着迭代抛出临时表附带的所有行INSERTED并对所有记录执行算法。您可以使用CURSOR或简单的WHILE LOOP. 由你决定。
您可以在此处找到示例。