2016-06-23 22 views
3

Gibt es eine Möglichkeit, diesen Cursor in eine Schleife/rekursive CTE zu konvertieren? Ich habe einige Artikel über CTEs gelesen, aber sie haben sich um Hierarchien gekümmert, und sie haben mir den Kopf verdreht.Wie verwende ich einen CTE als Schleife?

create table #things(id int) 
insert into #things (id) 
values(1),(2),(3),(4),(5) 

create table #items (name varchar(8), id int) 
insert into #items 
values ('grodd', 1), ('duck', 2), ('time', 3), ('nix', 4), ('quasar', 7) 


declare @count int = 0 
declare @id int = 0 
declare @name varchar(8) = null 

-- load cursor with ids from table #things 
declare test_cursor cursor for 
select id 
from #things 

-- get id first row and set @id with id 
open test_cursor 
fetch next from test_cursor into @id 

while @@FETCH_STATUS = 0 
begin 
    set @count = (select count(id) from #items where id = @id) 
    if (@count > 0) 
    begin 
     set @name = (select top 1 name from #items where id = @id) 
     exec dbo.test_stored_procedure @name 
    end 
    -- get id from next row and set @id = id 
    fetch next from test_cursor into @id 
end 

close test_cursor 
deallocate test_cursor 

drop table #items 
drop table #things 

Antwort

0

Wenn Sie anstelle der Prozedur eine Funktion verwenden können, ist die Verwendung von CTE nicht erforderlich. Sie können Funktion direkt in select-Klausel verwenden, oder etwas anderes wie dieses

select result.* 
from #items as i 
inner join #things as t on t.id = i.id 
cross apply 
dbo.test_stored_function (i.name) as result 

tun Oder wenn Sie absolut CTE verwenden möchten, dann können Sie diesen Code

with some_array as (
    select i.name 
    from #items as i 
    inner join #things as t on t.id = i.id 
) 
select result.* from some_array as sa 
cross apply 
dbo.test_stored_function (sa.name) as result 

In diesem Fall nutzen die dbo.test_stored_function sein müssen eine Tabellenwertfunktion (kein Skalar). In den obigen Beispielen ist eine der wiederkehrenden Spalten von der Funktion nvarchar mit dem Namen name, aber es kann genau das sein, was Sie brauchen.

Wenn Sie unbedingt eine Prozedur verwenden müssen, kann ich vorschlagen, mit dynamischer SQL-Abfrage zu versuchen. Sie können eine einzelne Zeichenfolge mit mehreren Abfragen innerhalb vorbereiten (eine Verkettung in anderer SQL-Abfrage mit den Ergebnisdaten für Prozedurparameter enthalten) und führen Sie es mit der Funktion sp_executesql wie in diesem Beispiel

declare @sql nvarchar(max) = N'execute dbo.some_procedure val1; execute dbo.some_procedure val2;'; 
execute sp_executesql @sql; 

Sie können mehr über Funktion lesen sp_executesql hier: https://msdn.microsoft.com/pl-pl/library/ms188001%28v=sql.110%29.aspx?f=255&MSPPError=-2147217396

Verwandte Themen