【问题标题】:SQL combine WITH clause and CursorSQL结合WITH子句和游标
【发布时间】:2016-12-09 14:32:05
【问题描述】:

如何在一个查询中使用声明参数WITH子句游标

declare @TOP10 table (Cat Nvarchar(max),SubGUID uniqueidentifier)
declare @Sub uniqueidentifier
declare GUID_Cursor cursor FOR
(select SubGUID from dbo.Sub with(nolock) where year=2016)
;
with [MyTable] as
(
Select SubGUID, color from dbo.Cars with(nolock) where color ='blue'
)


open GUID_Cursor
fetch next from GUID_Cursor into @Sub
while @@FETCH_STATUS=0
begin
insert into @TOP10 (Cat,SubGUID)

select color,SubGUID from [MyTable]
where SubGUID=@Sub

fetch next from GUID_Cursor into @Sub

end
close GUID_Cursor
deallocate GUID_Cursor

select * from @TOP10

我只是找不到在使用 WITH 子句后打开光标的方法。

谁能帮帮我?

【问题讨论】:

  • CTE 只是一个子查询。这样重写它应该会有所帮助。
  • 不应该是declare cursor for之后的with子句?

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


【解决方案1】:

嗯,除了代码的逻辑(对我来说,这里根本不需要光标),你应该把 CTE 声明移到更靠近你使用它的地方。

;with [MyTable] as
(
    Select SubGUID, color from dbo.Cars with(nolock) where color ='blue'
)
insert into @TOP10 (Cat,SubGUID)    
select color,SubGUID from [MyTable]
where SubGUID=@Sub

但实际上,您的所有代码都可以替换为:

declare @TOP10 table (Cat Nvarchar(max),SubGUID uniqueidentifier)

insert into @TOP10 (Cat,SubGUID)
select color,SubGUID 
from dbo.Cars with(nolock) 
where 
    color ='blue'
    and SubGUID in (select SubGUID from dbo.Sub with(nolock) where year=2016)

select * from @TOP10

【讨论】:

    【解决方案2】:

    我同意@AndyKorneyev,但为了实验:

    declare @crTest CURSOR,
            @name VARCHAR(1000),
            @type VARCHAR(1000)
    
    set @crTest = CURSOR FAST_FORWARD FOR
        WITH cteObjs AS (
            SELECT TOP 10 NAME, type
            FROM sys.objects o
            )
        select name, type
        from cteObjs
    
    
    OPEN @crTest
    
    FETCH NEXT FROM @crTest
    INTO @name, @type
    
    WHILE @@FETCH_STATUS = 0
    BEGIN
        PRINT @name
        PRINT @type
    
        FETCH NEXT FROM @crTest
        INTO @name, @type
    END
    
    CLOSE @crTest
    DEALLOCATE @crTest
    

    【讨论】:

      【解决方案3】:

      不想重复上面的 sn-ps 但要注意WITH 子句结果集必须在其末尾直接处理。

      与您的@tableVar 不同,cte 返回的结果集的范围在整个批处理中无效,因此必须后跟 SELECT、INSERT、UPDATE 或 DELETE 语句。 (有关详细信息和示例,请参阅:https://msdn.microsoft.com/en-us/library/ms175972.aspx 或关注其他答案之一)。

      e。 g.

      
          --> declare var: 
          declare @tableVar table (colOne int, colTwo nvarchar(30)
          );
      
          --> use cte: 
          with preOne as(select carId, color from pcUser with (nolock)
          )
          --> directly followed by insert:
          insert into @tableVar(userId, logInName)
            select colOne, colTwo from @tableVar;
      
          --> use var in cursor or anywhere else in the batch
      
      

      虽然我不确定您的目标是什么,但也许短连接可以解决问题:

      select a.[SubGUID]
      from [dbo].[Sub] as a with (nolock) 
          inner join [dbo].[Cars] as b with (nolock) on a.[SubGUID] = b.[SubGUID]
      where a.[year] = 2016 and b.[color] = 'blue';
      

      【讨论】:

        【解决方案4】:

        最后我使用了 #TOP10 这样的临时表。我在查询后放弃了。一旦我摆脱了with [MyTable] as 部分,我的参数就没有问题了。

        非常感谢大家。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-10-03
          • 1970-01-01
          • 1970-01-01
          • 2011-04-10
          • 2011-08-18
          • 2012-05-27
          • 2021-10-25
          相关资源
          最近更新 更多