SQL结合使用WITH子句和Cursor

时间:2016-12-09 14:32:06

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

如何在一个查询中使用声明参数 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 子句后,我无法找到打开光标的方法。

任何人都可以帮助我吗?

4 个答案:

答案 0 :(得分:4)

嗯,除了代码的逻辑(对我来说 - 根本不需要光标),你应该把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

答案 1 :(得分:0)

我同意@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

答案 2 :(得分:0)

不要重复上面的代码片段,但要注意WITH子句结果集必须直接在其结尾处理。

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

即克。


    --> 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';

答案 3 :(得分:0)

最后我使用了像#TOP10这样的临时标签。我在查询之后下垂了。一旦我摆脱<!DOCTYPE html> <html ng-app="app"> <head> <link data-require="angular-material@0.11.0" data-semver="0.11.0" rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/angular_material/0.11.0/angular-material.min.css" /> <script data-require="jquery@*" data-semver="2.1.4" src="http://code.jquery.com/jquery-2.1.4.min.js"></script> <script data-require="angular.js@*" data-semver="1.4.5" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script> <script data-require="angular-material@0.11.0" data-semver="0.11.0" src="https://ajax.googleapis.com/ajax/libs/angular_material/0.11.0/angular-material.min.js"></script> <script data-require="angular-animate@1.4.1" data-semver="1.4.1" src="https://code.angularjs.org/1.4.1/angular-animate.js"></script> <script data-require="angular-aria@1.4.1" data-semver="1.4.1" src="https://code.angularjs.org/1.4.1/angular-aria.js"></script> <script src="script.js"></script> </head> <body ng-controller="AppCtrl as ctrl"> <div layout="row"> <md-select ng-model="ctrl.userState"> <md-option> <em>None</em> </md-option> <md-option value="india">india</md-option> <md-option value="bangladesh">bangladesh</md-option> <md-option value="bhutan">bhutan</md-option> <md-option value="nepal">nepal</md-option> </md-select> </div> <div layout="row"> return value: {{ctrl.userState}} </div> </body> </html>部分,我就不再有参数问题了。

非常感谢你。