' CURSOR_NAME'不存在

时间:2016-09-19 06:49:56

标签: sql sql-server cursor

为了审计目的,我编写了以下触发器。当我尝试更新Sales.SalesOrderHeader表中的记录时,我收到以下错误:

  

Msg 16916,Level 16,State 1,Procedure tr_AuditUpdate,Line 11 A   光标名称为' c_Audit2'不存在。

这是触发器:

 USE [AdventureWorks2008R2]
    GO
    /****** Object:  Trigger [Sales].[tr_AuditUpdate]    Script Date: 9/19/2016 9:27:36 AM ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    ALTER trigger [Sales].[tr_AuditUpdate]
    on [Sales].[SalesOrderHeader]
    for Update
    AS
    SET NOCOUNT ON
    BEGIN
    DECLARE @EntityCode1 int
    DECLARE @OldStatus1 nvarchar(100)
    DECLARE @NewStatus1 nvarchar(100)

    if @@ROWCOUNT>0
        DECLARE c_Audit2 CURSOR LOCAL FOR
        Select  d.SalesOrderID,d.Status,i.Status
        From    deleted AS d
        join inserted AS i
        on i.SalesOrderID=d.SalesOrderID
    Open c_Audit2


    Fetch Next From c_Audit2
    INTO @EntityCode1, @OldStatus1, @NewStatus1

    While @@FETCH_STATUS=0
    BEGIN
      execute sp_Audit @AuditedTable='Sales.SalesOrderHeader',
                       @EntityCode=@EntityCode1,
                       @OldStatus=@OldStatus1,
                       @NewStatus1=@NewStatus1,
                       @AuditUpdate='+',
                       @AuditInsert='-',
                       @AuditDelete='-'

      Fetch Next From c_Audit2
      INTO @EntityCode1, @OldStatus1, @NewStatus1
    END

    CLOSE c_Audit2
    DEALLOCATE c_Audit2
    END

这是更新声明

update Sales.SalesOrderHeader
set Status=4
where SalesOrderID=43659

1 个答案:

答案 0 :(得分:1)

只有在@@ ROWCOUNT> 0时才会创建光标,就像你在触发器的开头写的一样。删除它,如果它会正常工作。

if @@ROWCOUNT>0
    DECLARE c_Audit2 CURSOR LOCAL FOR
    Select  d.SalesOrderID,d.Status,i.Status
    From    deleted AS d
    join inserted AS i
    on i.SalesOrderID=d.SalesOrderID
open c_Audit2 -- fails when @@rowcount=0

因为如果不总是创建游标。

然后你的下一个陈述是

open c_Audit2

如果“@@ ROWCOUNT> 0”返回false

,则会失败

删除此代码: if @@ ROWCOUNT> 0 ,您的触发器将有效。