【问题标题】:FETCH NEXT FROM WHILE @@FETCH_STATUS = 0 BEGIN taking too longFETCH NEXT FROM WHILE @@FETCH_STATUS = 0 BEGIN 耗时太长
【发布时间】:2019-08-09 17:16:43
【问题描述】:

存储过程需要2分钟才能返回结果 我实现了查询检查所有记录并获取所有记录。

OPEN cFolders
FETCH NEXT FROM cFolders INTO @FId
WHILE (@@FETCH_STATUS = 0)
BEGIN
  IF @FolderPath IS NOT NULL
    SET @FolderPath = @FolderPath + '/' +
      (SELECT [FileManager_Folders].FolderName
         FROM [FileManager_Folders]  
         WHERE [FileManager_Folders].Id = @FId)
  ELSE
    SET @FolderPath =
      CASE
        WHEN @FId <> @SharedFolderId AND @ObjectTypeId = 1 THEN
          (SELECT dbo.Projects.ProjectName
             FROM dbo.Projects
             WHERE dbo.Projects.Id =
               (SELECT [FileManager_Folders].ObjectId
                  FROM [FileManager_Folders]
                  WHERE [FileManager_Folders].Id = @FId))
        WHEN @FId <> @SharedFolderId AND @ObjectTypeId = 9 THEN
          (SELECT dbo.Asset_Properties.Name
             FROM dbo.Asset_Properties
             WHERE dbo.Asset_Properties.Id =
               (SELECT [FileManager_Folders].ObjectId 
                  FROM [FileManager_Folders]
                  WHERE [FileManager_Folders].Id = @FId))
        ELSE
          (SELECT [FileManager_Folders].FolderName     
             FROM [FileManager_Folders]
             WHERE [FileManager_Folders].Id = @FId)
        END

   FETCH NEXT FROM cFolders INTO @FId
END
CLOSE cFolders
DEALLOCATE cFolders
RETURN ISNULL(@FolderPath,'')
END

我只想要前 100 个结果。不知道该怎么办...

【问题讨论】:

  • 欢迎来到 SO!什么数据库服务器/版本?
  • 所以您向我们展示了一个耗时太长的游标操作 - 而没有向我们展示 游标执行的查询。您对问题所在也很模糊。我们不介意读者,并且没有可以打开的神奇“快速查询”选项。
  • 欢迎来到 Stack Overflow!如前所述,我们需要您做一些事情来让我们更好地了解您的问题以及其他可用的解决方案。详情请见How to Askminimal reproducible example
  • 如果没有别的,你可以在循环中添加一个计数器,例如declare @FoldersProcessed as Int = 0;,增加循环中的计数(set @FoldersProcessed += 1;)并在达到目标值时退出。由于每次通过循环都会覆盖 @FolderPath 的值,因此不清楚为什么要费心找出其中的前 99 个。
  • 请编辑您的问题(使用问题底部的edit 链接),而不是将您的回复作为答案发布给 cmets。您可以使用 cmets 后的 add a comment 链接回复 cmets。如果要将评论定向到特定用户,请以 at 符号(“@”)开头评论,然后是用户名,例如“@HABO - 为什么是鸭子?”

标签: sql-server tsql cursor sql-server-2016


【解决方案1】:

因此,您向我们展示了一个耗时过长的游标操作 - 而没有向我们展示游标执行的查询。您对问题所在也很模糊。我们不介意读者,并且没有可以打开的神奇“快速查询”选项。 – Damien_The_Unbeliever

    DECLARE @ObjectTypeId BIGINT 
    SET @ObjectTypeId = (SELECT ObjectTypeId FROM [FileManager_Folders] WHERE Id = 
    @FolderId)

    DECLARE @FolderPath NVARCHAR(3000)
    DECLARE @SharedFolderId BIGINT
    SET @SharedFolderId = (SELECT Id FROM [FileManager_Folders] WHERE ObjectId = -1 AND 
    ParentId IS NULL)
    DECLARE @FId AS NVARCHAR(200)
    DECLARE cFolders CURSOR FOR
    WITH Folders (FolderId, ParentId, FolderName) AS
    (
     SELECT
     F.Id, F.ParentId, F.FolderName
    FROM dbo.[FileManager_Folders] F
    WHERE F.Id = @FolderId
   UNION ALL
   SELECT
     F.Id, F.ParentId, F.FolderName
    FROM dbo.[FileManager_Folders] F
     INNER JOIN Folders P ON P.ParentId = F.Id
     )SELECT FolderId FROM Folders ORDER BY ParentId ASC

    OPEN cFolders
   FETCH NEXT FROM cFolders INTO @FId
    WHILE (@@FETCH_STATUS = 0)
    BEGIN
    IF @FolderPath IS NOT NULL   SET  @FolderPath = @FolderPath + '/' + (SELECT 
    [FileManager_Folders].FolderName FROM [FileManager_Folders]  WHERE 
    [FileManager_Folders].Id = @FId)
    ELSE  SET @FolderPath = CASE WHEN @FId <> @SharedFolderId AND @ObjectTypeId = 1  THEN  
     (SELECT dbo.Projects.ProjectName FROM dbo.Projects WHERE dbo.Projects.Id = 
                            (SELECT [FileManager_Folders].ObjectId FROM 
    [FileManager_Folders]  WHERE [FileManager_Folders].Id = @FId))
                        WHEN @FId <> @SharedFolderId AND @ObjectTypeId = 9  THEN  (SELECT 
    dbo.Asset_Properties.Name FROM dbo.Asset_Properties WHERE dbo.Asset_Properties.Id = 
                            (SELECT [FileManager_Folders].ObjectId FROM 
   [FileManager_Folders]  WHERE [FileManager_Folders].Id = @FId))
                            ELSE (SELECT [FileManager_Folders].FolderName FROM 
    [FileManager_Folders]  WHERE [FileManager_Folders].Id = @FId)
                            END

    FETCH NEXT FROM cFolders INTO @FId
    END
CLOSE cFolders
DEALLOCATE cFolders

RETURN ISNULL(@FolderPath,'')

END



【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-01
    • 2021-08-07
    • 2018-02-27
    • 2013-05-28
    相关资源
    最近更新 更多