【问题标题】:Invalid cursor state游标状态无效
【发布时间】:2011-02-17 04:26:05
【问题描述】:

我们在名为 OSPP 的表上设置了触发器,用于将特定数据保存到表中以供以后使用。 一次向表中添加多行时,我在 SAP 中收到以下错误。

光标状态无效

我们有 SQL Server 2005 SP3(但我在 SP1 和 SP2 上进行了干净的 2005 安装)

一个触发器:

CREATE TRIGGER [dbo].[tr_OSPP_Insert]
   ON  [dbo].[OSPP]
   FOR INSERT
AS 
BEGIN
    Declare @ItemCode varchar(255)
    Declare @CardCode varchar(255)
    Declare @Price decimal(18,2)
    Declare @ListNum bigint 
    Declare @ID bigint
    Declare @Remote char(1)


    DECLARE db_cursor CURSOR FOR 
    SELECT ItemCode, CardCode, Price, ListNum
    FROM INSERTED

    OPEN db_cursor  
    FETCH NEXT
    FROM db_cursor  INTO @ItemCode, @CardCode, @Price, @ListNum
    WHILE @@FETCH_STATUS = 0
    BEGIN

    SELECT @Remote = isnull(U_Remote, 'N') FROM OITM WHERE ItemCode = @ItemCode

        IF ltrim(rtrim(upper(@Remote))) = 'Y'
        BEGIN

        SELECT @ID = U_ID FROM [dbo].[@BDS_MAINTENANCE]
        UPDATE [dbo].[@BDS_MAINTENANCE] set U_ID = U_ID + 1

        INSERT INTO [dbo].[@BDS_REMOTESPECIALPRICELIST]
        (   
            Code,
            [Name],
            U_ID,
            U_ItemCode,
            U_CardCode,
            U_Price,
            U_ListNum,
            U_TransactionType,
            U_Uploaded
        ) VALUES (
            @ID,
            '_' + cast(@ID as VARCHAR(50)),
            @ID,
            @ItemCode,
            @CardCode,
            @Price,
            @ListNum,
            1,
            0
        )


    FETCH NEXT
    FROM db_cursor INTO @ItemCode, @CardCode, @Price, @ListNum
    END

    CLOSE db_cursor  
    DEALLOCATE db_cursor


END

END

我们也试过了:

CREATE TRIGGER [dbo].[tr_OSPP_Insert]
   ON  [dbo].[OSPP]
   FOR INSERT
AS 
BEGIN

    SELECT * INTO [@TEMPTABLE222] FROM INSERTED 

END

但仍然得到同样的错误。

你们有什么问题吗?

提前致谢!

【问题讨论】:

  • 那些以@ 开头并用括号括起来的表名是什么?另外,您的光标是否是由于循环另一个光标(其他地方)而被触发的?
  • @marc_s:我认为,在某些专业水平上,使用光标触发触发器并不少见。我认为人们可以被说服离开它而不用我们不寒而栗。 :)
  • @Andriy M:光是游标就够糟糕了——触发器中的游标是魔鬼的杰作。
  • @marc_s:冷嘲热讽也不好。 :) 感谢您删除该评论!
  • @Andriy M :这些是用户定义的表。您在 SAP 中为自定义数据设置它们。

标签: sql-server sql-server-2005 sap


【解决方案1】:

我数了三个开始,三个结束。但它是代表游标循环的第二对 - 所以我会将您的 Close/Deallocate 移动到第二个 End 之后,而不是之前。例如:

    FETCH NEXT
    FROM db_cursor INTO @ItemCode, @CardCode, @Price, @ListNum
    END

    CLOSE db_cursor  
    DEALLOCATE db_cursor
END

可能需要:

    END
    FETCH NEXT
    FROM db_cursor INTO @ItemCode, @CardCode, @Price, @ListNum

END
CLOSE db_cursor  
DEALLOCATE db_cursor

(我也将 fetch 移出了下一级,因为否则您只能在 IF 条件内向前移动光标)


还有一种风格的评论(无法抗拒)。通常认为在触发器正文中 SET NOCOUNT ON 是一种很好的做法,以避免发送大量额外的 n 行受影响的消息。

【讨论】:

  • 稍后我会看看这个。感谢您的帮助!
猜你喜欢
  • 2012-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多