Fire trigger for every inserted row using SqlBulkCopy

前端 未结 4 1075
清歌不尽
清歌不尽 2021-01-19 03:31

I am using SqlBulkCopy class to insert 50k rows at a time in table tbl_records I have set a After Insert trigger on this table and usi

4条回答
  •  逝去的感伤
    2021-01-19 04:09

    In case another person come across this problem and looking for a solution, here I will post my findings as well.

    IMPORTANT: usr has already given the answer, but I will explain it a little bit.

    First, this is what Microsoft documentation says about bulk insert,

    If FIRE_TRIGGERS is not specified, no insert triggers execute.

    FIRE_TRIGGERS Specifies that any insert triggers defined on the destination table execute during the bulk-import operation. If triggers are defined for INSERT operations on the target table, they are fired for every completed batch.

    FIRE_TRIGGERS is a argument use with BULK INSERT T-SQL statement.

    And if you are trying to use bulk insert with SqlBulkCopyclass (.Net Framework/Core) you have to use SqlBulkCopyOptions Enum (docs).

    You can use the SqlBulkCopyOptions enumeration when you construct a SqlBulkCopy instance to change how the WriteToServer methods for that instance behave.

    Here is a sample,

    var options = SqlBulkCopyOptions.CheckConstraints | SqlBulkCopyOptions.FireTriggers | SqlBulkCopyOptions.KeepIdentity;
    var bulkCopy = new SqlBulkCopy(connectionString, options);
    

    OK. Now triggers will run with bulk insert, But why for only one record. Read what Microsoft said about FIRE_TRIGGER argument again.

    If triggers are defined for INSERT operations on the target table, they are fired for every completed batch.

    That means, your trigger will run for whole batch at once. But your batch contains more than one row. Therefore your trigger algorithm (The thing you supposed to do to a single record) will work for one record, not for all the records.

    Now you know why it doesn't work for all, so the solution is improve your trigger to work with multiple rows. Which means iterate throw all rows comes with INSERTED temporary table and execute your algorithm for all records. You can use CURSOR or a simple WHILE LOOP. Its up to you.

    You can find examples here.

提交回复
热议问题