2016-12-09 2 views
0

Wie ist es möglich erklärt Parameter, ein WITH-Klausel und ein Cursor in einer AbfrageSQL kombinieren WITH-Klausel und Cursor

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 [email protected] 

fetch next from GUID_Cursor into @Sub 

end 
close GUID_Cursor 
deallocate GUID_Cursor 

select * from @TOP10 

Ich kann nicht finden, nur ein Weg, tu öffnen Sie den Cursor zu verwenden, nach der Verwendung der WITH Klausel.

Kann mir jemand helfen?

+0

Ein CTE ist nur eine Sub-Abfrage. Schreibe es als solches neu und das sollte helfen. – dfundako

+0

sollte nicht die "mit" -Klausel nach "declare cursor for" sein? – McNets

Antwort

4

Nun, abgesehen von der Logik des Codes (für mich - es gibt keine Notwendigkeit der Cursor hier überhaupt), sollten Sie nur CTE Erklärung näher an die Stelle bewegen, wo Sie es verwenden.

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 
0

ich mit @AndyKorneyev zustimmen, aber im Interesse des Experiments:

;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 [email protected] 

Aber wirklich, alle könnten Ihren Code mit ersetze

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 
0

Ich will nicht Wiederholen Sie die obigen Snippets, aber beachten Sie, dass WITH Klausel-Ergebnismenge direkt am Ende verarbeitet werden muss.

Im Gegensatz zu Ihrem @tableVar, der Umfang der Ergebnismenge, die von CTE zurückgegeben wird, ist innerhalb kompletten Charge nicht gültig und muss daher von SELECT, INSERT, UPDATE gefolgt werden oder DELETE-Anweisung. (für Details und Beispiele siehe: https://msdn.microsoft.com/en-us/library/ms175972.aspx oder folgen Sie einer der anderen Antworten).

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 

Obwohl ich bin mir nicht ganz sicher, was Sie zielen darauf ab, vielleicht eine kurze beitreten könnten hier den Trick:

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

Am Ende habe ich Temp tabeles wie # TOP10 verwendet. Was ich nach der Abfrage fallen gelassen habe. Sobald ich den with [MyTable] as Teil los war hatte ich keine Probleme mehr mit den Parametern.

Vielen Dank viel.