【问题标题】:Using a cursor with a CTE使用带有 CTE 的游标
【发布时间】:2013-01-30 10:12:21
【问题描述】:

我需要一个用于以下查询的游标,以便循环获取/更新/插入一些其他数据。有人可以帮我吗?

DECLARE @FROMDATE DATETIME
DECLARE @TODATE DATETIME
SELECT @FROMDATE = Getdate()
SELECT @TODATE = Getdate() + 7

;WITH DATEINFO(DATES)
     AS (SELECT @FROMDATE
         UNION ALL
         SELECT DATES + 1
         FROM   DATEINFO
         WHERE  DATES < @TODATE)
SELECT *
FROM   DATEINFO
OPTION (MAXRECURSION 0)

我尝试了很多方法,但没有找到任何有效的方法。

我正在使用

declare @adate datetime
DECLARE @FROMDATE DATETIME 
DECLARE @TODATE DATETIME 
select @FROMDATE=getdate()
select @TODATE =getdate()+7

declare @weekdates cursor for
WITH DATEINFO(DATES) AS (SELECT @FROMDATE UNION ALL SELECT DATES + 1 FROM DATEINFO WHERE DATES < @TODATE) 
SELECT * FROM DATEINFO OPTION (MAXRECURSION 0)

open @weekdates
fetch next from @weekdates into @adate
while @@fetch_status=0
begin
print 'success'
fetch next from @weekdates into @adate
end
close @weekdates
deallocate @weekdates

我仍然遇到错误

【问题讨论】:

    标签: sql sql-server common-table-expression


    【解决方案1】:

    只要放在公用表表达式之前即可:

    DECLARE @FROMDATE DATETIME 
    DECLARE @TODATE DATETIME 
    select @FROMDATE=getdate()
    select @TODATE =getdate()+7
    
    declare boris cursor for
    
    WITH DATEINFO(DATES)
         AS (SELECT @FROMDATE
             UNION ALL
             SELECT DATES + 1
             FROM   DATEINFO
             WHERE  DATES < @TODATE)
    SELECT *
    FROM   DATEINFO
    OPTION (MAXRECURSION 0) 
    

    (但是,请插入通常的注意事项,即游标几乎总是错误的工作工具。如果您能找到一种方法以基于集合的方式完成整个操作,那么它通常是可取的,并且可能会执行得更好(或在至少更适合性能调整))

    【讨论】:

    • 我敢问你为什么叫你的光标boris? :-)
    • @Bridge - 抱歉,习惯的力量。我永远似乎无法为游标想出一个体面的名称 - 它们要么是 a) 通过阅读琐碎的 select 语句而容易理解,或者 b) 理解起来如此复杂以至于你会破坏sysname 试图描述它们的限制。所以他们在我的代码中往往被命名为boris
    • @user1776417 它抛出了什么错误?您是否完全复制和粘贴?你记得去掉分号吗?完成后记得关闭并取消分配boris
    • 游标变量可以以@ 开头,在这种情况下,它们会在超出范围时自动关闭和释放。
    • (为此将声明更改为DECLARE @boris CURSOR;SET @boris = CURSOR FOR ...
    【解决方案2】:

    在游标名称中使用@ 很好,但您使用的语法是错误的。

    DECLARE @adate DATETIME
    DECLARE @FROMDATE DATETIME
    DECLARE @TODATE DATETIME
    
    SELECT @FROMDATE = getdate()
    
    SELECT @TODATE = getdate() + 7
    
    DECLARE @weekdates CURSOR;
    
    SET @weekdates = CURSOR FOR
    WITH DATEINFO(DATES)
         AS (SELECT @FROMDATE
             UNION ALL
             SELECT DATES + 1
             FROM   DATEINFO
             WHERE  DATES < @TODATE)
    SELECT *
    FROM   DATEINFO
    OPTION (MAXRECURSION 0) 
    
    OPEN @weekdates
    
    FETCH next FROM @weekdates INTO @adate
    
    WHILE @@fetch_status = 0
      BEGIN
          PRINT 'success'
    
          FETCH next FROM @weekdates INTO @adate
      END
    

    当声明为本地 @ 变量时,游标会在变量超出范围时自动关闭并释放。

    【讨论】:

    • +100 - “当声明为局部 @ 变量时,游标会在变量超出范围时自动关闭并释放。” - 即使是长期的 MS SQL 开发人员,对我来说也是新手 - 谢谢!
    • 'declared as a local @'解释真的很有用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 2011-11-01
    • 1970-01-01
    • 2012-01-31
    • 1970-01-01
    • 1970-01-01
    • 2018-12-03
    相关资源
    最近更新 更多