3

Есть ли способ конвертировать этот курсор в цикл/рекурсивный CTE? Я читал некоторые статьи о CTE, но они были об иерархиях, и они заставляли мою голову вращаться.Как использовать CTE как цикл?

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 

ответ

0

Если вы можете использовать функцию вместо процедуры, то нет необходимости использовать CTE. Вы можете использовать функцию непосредственно в ЗЕЬЕСТЕ или сделать что-то еще, как этот

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 

Или, если вы абсолютно хотите использовать CTE, то вы можете использовать этот код

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 

В этом случае dbo.test_stored_function должен быть табличная функция (не скаляр). В приведенных выше примерах один из возвращающихся столбцов функции - nvarchar с именем name, но он может быть вам понадобятся.

Если вам абсолютно необходимо использовать процедуру, я могу предложить попробовать динамический SQL-запрос. Вы можете подготовить одну строку с несколькими запросами внутри (с помощью конкатенации в другой SQL-запрос, где результат содержит данные для параметров процедуры) и выполнить его с функцией sp_executesql как в этом примере

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

Вы можете прочитать больше о функции sp_executesql здесь: https://msdn.microsoft.com/pl-pl/library/ms188001%28v=sql.110%29.aspx?f=255&MSPPError=-2147217396

Смежные вопросы