Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/wordpress/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Stored procedures 在存储过程中使用光标_Stored Procedures_Sql Server 2016 - Fatal编程技术网

Stored procedures 在存储过程中使用光标

Stored procedures 在存储过程中使用光标,stored-procedures,sql-server-2016,Stored Procedures,Sql Server 2016,在MS SQL 2016存储过程中,我有以下极慢的代码(我认为它陷入了一个永无止境的循环): 此过程只是一个维护过程,不会经常运行,但运行时最好只需几秒钟。其目的是在一个表中规范化ADMIN_API_Master_Members_List表中每个逗号分隔值的一条记录,并将其与程序代码、成员ID和DBID一起放入ADMIN_API_PMID_PROGRAM_CODE_HOLDING_表中 主表中只有大约150条记录,逗号分隔的字符串可能有5个值。我接受其他解决方案 提前感谢无限循环的原因可能是循环

在MS SQL 2016存储过程中,我有以下极慢的代码(我认为它陷入了一个永无止境的循环):

此过程只是一个维护过程,不会经常运行,但运行时最好只需几秒钟。其目的是在一个表中规范化ADMIN_API_Master_Members_List表中每个逗号分隔值的一条记录,并将其与程序代码、成员ID和DBID一起放入ADMIN_API_PMID_PROGRAM_CODE_HOLDING_表中

主表中只有大约150条记录,逗号分隔的字符串可能有5个值。我接受其他解决方案


提前感谢

无限循环的原因可能是循环中没有“Fetch next” 请尝试以下方法:

  @DBID Integer
  AS
  BEGIN

  DECLARE TagCursor CURSOR FOR SELECT MemberID
  FROM           ADMIN_API_Master_Members_List
  WHERE DBID= @DBID AND Len(Pending) > 0 

  DECLARE @ProgramCode VARCHAR(10)
  DECLARE @Values VARCHAR(MAX)
  DECLARE @tag nvarchar(10) 

    OPEN TagCursor
        FETCH NEXT FROM TagCursor INTO @tag   

        WHILE (@@FETCH_STATUS = 0)
        BEGIN

       SELECT @ProgramCode = Program_Code, @Values= Pending FROM  ADMIN_API_Master_Members_List WHERE MemberID= @tag 

       DELETE FROM ADMIN_API_PMID_PROGRAM_CODE_HOLDING_TABLE
       WHERE  (MemberID =@tag)

       INSERT INTO ADMIN_API_PMID_PROGRAM_CODE_HOLDING_TABLE ( ProgramCode, MemberID, DBID, PMID) 
       SELECT    @ProgramCode, @tag, @DBID ,  Value FROM STRING_SPLIT(@Values, ',')  
      FETCH NEXT FROM TagCursor INTO @tag    
       END

        CLOSE TagCursor
        DEALLOCATE TagCursor 
  END

无限循环的原因可能是循环中没有“fetchnext” 请尝试以下方法:

  @DBID Integer
  AS
  BEGIN

  DECLARE TagCursor CURSOR FOR SELECT MemberID
  FROM           ADMIN_API_Master_Members_List
  WHERE DBID= @DBID AND Len(Pending) > 0 

  DECLARE @ProgramCode VARCHAR(10)
  DECLARE @Values VARCHAR(MAX)
  DECLARE @tag nvarchar(10) 

    OPEN TagCursor
        FETCH NEXT FROM TagCursor INTO @tag   

        WHILE (@@FETCH_STATUS = 0)
        BEGIN

       SELECT @ProgramCode = Program_Code, @Values= Pending FROM  ADMIN_API_Master_Members_List WHERE MemberID= @tag 

       DELETE FROM ADMIN_API_PMID_PROGRAM_CODE_HOLDING_TABLE
       WHERE  (MemberID =@tag)

       INSERT INTO ADMIN_API_PMID_PROGRAM_CODE_HOLDING_TABLE ( ProgramCode, MemberID, DBID, PMID) 
       SELECT    @ProgramCode, @tag, @DBID ,  Value FROM STRING_SPLIT(@Values, ',')  
      FETCH NEXT FROM TagCursor INTO @tag    
       END

        CLOSE TagCursor
        DEALLOCATE TagCursor 
  END

我还没有对此进行测试,但正如我在评论中提到的,使用
光标
是个坏主意;由于SQL Server擅长基于集合的方法而不是迭代任务(后者是
游标),因此它们天生就很慢

我怀疑这可以实现您想要的答案,并且避免了
光标

CREATE PROC YourProc @DBID integer
AS
BEGIN

    DECLARE @Deleted table (ProgramCode varchar(10),
                            [Value] varchar(MAX),
                            Tag nvarchar(10));


    DELETE HT
    OUTPUT deleted.Program_Code,
           deleted.Pending,
           deleted.MemberID
    INTO @Deleted (ProgramCode,
                   [Value],
                   Tag)
    FROM ADMIN_API_PMID_PROGRAM_CODE_HOLDING_TABLE AS HT
         JOIN ADMIN_API_Master_Members_List AS MML ON HT.MemberID = MML.MemberID
    WHERE MML.[DBID] = @DBID
      --AND LEN(Pending) > 0; --Changed this to below to be SARGable, as only a string with the value '' will have a length of 0.
      AND Pending != '';

    INSERT INTO ADMIN_API_PMID_PROGRAM_CODE_HOLDING_TABLE (ProgramCode,
                                                           MemberID,
                                                           DBID,
                                                           PMID)
    SELECT D.ProgramCode,
           D.Tag,
           @DBID,
           SS.Value
    FROM @Deleted AS D
         CROSS APPLY STRING_SPLIT(D.[Value], ',') AS SS;

END;

我还没有对此进行测试,但正如我在评论中提到的,使用
光标
是个坏主意;由于SQL Server擅长基于集合的方法而不是迭代任务(后者是
游标),因此它们天生就很慢

我怀疑这可以实现您想要的答案,并且避免了
光标

CREATE PROC YourProc @DBID integer
AS
BEGIN

    DECLARE @Deleted table (ProgramCode varchar(10),
                            [Value] varchar(MAX),
                            Tag nvarchar(10));


    DELETE HT
    OUTPUT deleted.Program_Code,
           deleted.Pending,
           deleted.MemberID
    INTO @Deleted (ProgramCode,
                   [Value],
                   Tag)
    FROM ADMIN_API_PMID_PROGRAM_CODE_HOLDING_TABLE AS HT
         JOIN ADMIN_API_Master_Members_List AS MML ON HT.MemberID = MML.MemberID
    WHERE MML.[DBID] = @DBID
      --AND LEN(Pending) > 0; --Changed this to below to be SARGable, as only a string with the value '' will have a length of 0.
      AND Pending != '';

    INSERT INTO ADMIN_API_PMID_PROGRAM_CODE_HOLDING_TABLE (ProgramCode,
                                                           MemberID,
                                                           DBID,
                                                           PMID)
    SELECT D.ProgramCode,
           D.Tag,
           @DBID,
           SS.Value
    FROM @Deleted AS D
         CROSS APPLY STRING_SPLIT(D.[Value], ',') AS SS;

END;

为什么首先要使用光标?游标天生就是慢的。为什么不使用基于集合的方法?为什么首先使用光标?游标天生就是慢的。为什么不使用基于集合的方法呢?太棒了——效果很好。我已经起床太多小时了,从来没有看到错过了什么。谢谢这个网站上的人great@user1314159我仍然建议不要使用
光标
。它们并不是SQL Server所擅长的。太棒了——工作起来很有魅力。我已经起床太多小时了,从来没有看到错过了什么。谢谢这个网站上的人great@user1314159我仍然建议不要使用
光标
。它们不是SQL Server擅长的。好的,我能理解-谢谢,两个答案都有目的。好的,我能理解-谢谢,两个答案都有目的