Fire trigger for every inserted row using SqlBulkCopy

前端 未结 4 1070
清歌不尽
清歌不尽 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:04

    I Have try this and it will work for.

    I hope its help you..

    CREATE TRIGGER Triggername ON TableName After INSERT AS SET NOCOUNT ON;

    insert into TargetTable (Fields) SELECT (i.field1,i.field2,i.field3,....,i.fieldn) FROM inserted i GO

    0 讨论(0)
  • 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.

    0 讨论(0)
  • 2021-01-19 04:21

    Triggers never fire per-row. They fire for all rows of the corresponding DML statement. Rewrite your trigger so that it can cope with the INSERTED table containing many rows. This is best-practice and required practice anyway.

    it is firing trigger for only first row inserted out of 50k rows

    You must be misinterpreting the situation, maybe because you were unaware that triggers can contain multiple rows in the virtual tables.

    0 讨论(0)
  • 2021-01-19 04:24

    The SqlBulkCopy object's batch size is the full set of rows, by default.

    Here's what MSDN says about the BatchSize property values: "Zero (the default) indicates that each WriteToServer operation is a single batch."

    In this case, the trigger will fire once, but the Inserted table will have entries for all of the affected records.

    0 讨论(0)
提交回复
热议问题