【问题标题】:Trigger will not fire at all after bulkcopy批量复制后触发器根本不会触发
【发布时间】:2018-01-28 11:52:53
【问题描述】:

我想在使用批量复制将插入的记录插入数据库后更新它们。我想在插入后写一个触发器来为我做更新。如果我一个接一个地插入记录,但在批量复制插入后拒绝工作,触发器工作正常。

我已将触发触发器 (SqlBulkCopyOptions.FireTriggers & SqlBulkCopyOptions.CheckConstraints) 添加到连接中,但它仍然无法正常工作。

这是我写的触发器:

CREATE TRIGGER [dbo].[Trigger_assessment]
ON [dbo].[assessment]
AFTER INSERT 
AS
BEGIN
    SET NoCount ON

    Declare @a as int
    Declare @b as int

    SELECT @b = exam_score, @a = ca 
    FROM inserted

    UPDATE assessment 
    SET final_ca = ca*0.3, final_exam = exam_score * 0.7,
        f_score = ((ca * 0.3) + (exam_score * 0.7)) 
    WHERE exam_score = @b AND ca = @a
END

还有批量复制:

     Dim koneksi_excel As New      System.Data.OleDb.OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0; Data Source='" & path1.Text & " '; Extended Properties=""Excel 12.0 xml;HDR=yes""")

    koneksi_excel.Open()
    Dim query_excel As String = "select * from [Sheet1$]"

    Dim cmd As OleDbCommand = New OleDbCommand(query_excel, koneksi_excel)

    Dim rd As OleDbDataReader

    Dim koneksi As New SqlConnection()

    If mysqlconnectionstring.State = ConnectionState.Closed Then
        mysqlconnectionstring.Open()
    End If
    Using BulkCopy As SqlBulkCopy = New SqlBulkCopy(ConfigurationManager.ConnectionStrings("SchoolDBConnectionString").ConnectionString.ToString, SqlBulkCopyOptions.FireTriggers & SqlBulkCopyOptions.CheckConstraints)

        BulkCopy.DestinationTableName = "dbo.assessment"

        Try

            rd = cmd.ExecuteReader
            BulkCopy.WriteToServer(rd)
            rd.Close()
            mysqlconnectionstring.Close()
            MsgBox("Data import succesful", MsgBoxStyle.Information, "imports")
            path.Text = ""
        Catch ex As Exception
            MsgBox(ex.ToString)
        Finally
            mysqlconnectionstring.Close()
        End Try
    End Using

我需要帮助,谢谢

【问题讨论】:

  • 您的触发器有 MAJOR 缺陷,因为您似乎认为它会每行调用一次 - 那是不是 b> 情况。触发器将每个语句触发一次,因此如果您的INSERT 语句导致此触发器触发插入 25 行,您将触发触发器一次,但随后Inserted 伪表将包含 25 行。您的代码将在这 25 行中选择哪一行? SELECT @b = exam_score, @a = ca FROM inserted - 它是不确定的,您将获得任意行,您将忽略所有其他行。您需要重写触发器以考虑到这一点!

标签: sql-server tsql sql-server-2012 triggers


【解决方案1】:

inserted 虚拟表是一个表,因此可以有多个行。如果您进行批量插入(或更新),此表中将包含多行。您需要考虑到这一点。您可以在此处阅读更多相关信息:Use the inserted and deleted Tables


您更正的触发器是:

CREATE TRIGGER [dbo].[Trigger_assessment]
ON [dbo].[assessment]
after insert
AS
BEGIN
    SET NoCount ON

    update 
        assessment 
    set 
        final_ca=a.ca*0.3,
        final_exam=a.exam_score*0.7,
        f_score=((a.ca*0.3)+(a.exam_score*0.7)) 
    from
        assessment AS a
        inner join inserted as i on
            i.ca=a.ca and
            i.exam_score=a.exam_score;
END

【讨论】:

    猜你喜欢
    • 2018-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-07
    • 2012-11-12
    • 1970-01-01
    • 1970-01-01
    • 2010-11-14
    相关资源
    最近更新 更多