使用带有CTE的光标

Pav*_*mar 14 sql sql-server common-table-expression

我需要一个光标用于下面的查询,所以我可以循环来获取/更新/插入一些其他数据.有人可以帮我这个吗?

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)
Run Code Online (Sandbox Code Playgroud)

我尝试了很多方法,但没有发现任何有用的方法.

我正在使用

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
Run Code Online (Sandbox Code Playgroud)

我仍然遇到错误

Dam*_*ver 26

只需将它放在公用表表达式之前:

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) 
Run Code Online (Sandbox Code Playgroud)

(但是,插入关于游标的常见注意事项几乎总是错误的工具.如果你能找到一种方法以基于集合的方式完成整个操作,它通常更可取,并且可能表现更好(或者至少更多)适合性能调整))

  • 游标变量可以以`@`开头,在这种情况下,它们会在超出范围时自动关闭和释放. (6认同)
  • (将声明更改为`DECLARE @boris CURSOR; SET @boris = CURSOR FOR ...`为此 (6认同)
  • @Bridge - 抱歉,习惯的力量.我可以*永远*似乎没有为游标找到一个合适的名字 - 它们要么是通过阅读琐碎的选择语句来理解,或者b)如此复杂以理解你将破坏`sysname`的限制在试图描述它们.所以他们在我的代码中往往被命名为`boris` (3认同)
  • 敢问我为什么叫你的光标`boris`?:-) (2认同)

Mar*_*ith 12

可以@在游标名称中使用,但您使用的语法是错误的.

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
Run Code Online (Sandbox Code Playgroud)

当声明为局部@变量时,当变量超出范围时,光标将自动关闭并释放.

  • +100 - “当声明为本地@变量时,当变量超出范围时,游标将自动关闭并释放。” - 即使作为一名长期的 MS SQL 开发人员,对我来说还是个新手 - 谢谢! (3认同)