如何使用CTE作为循环?

时间:2016-06-23 21:23:27

标签: tsql loops cursor common-table-expression recursive-query

有没有办法将此游标转换为循环/递归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

1 个答案:

答案 0 :(得分:0)

如果您可以使用函数而不是程序,则无需使用CTE。您可以直接在select子句中使用函数或执行其他类似的操作

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的{​​{1}},但它可以是您需要的。

如果你必须使用一个程序,那么我可以建议尝试使用动态sql查询。您可以在内部准备一个包含多个查询的字符串(在其他sql查询中使用连接,其中结果包含过程参数的数据),并使用函数name执行它,如本示例所示

sp_executesql

您可以在此处详细了解功能declare @sql nvarchar(max) = N'execute dbo.some_procedure val1; execute dbo.some_procedure val2;'; execute sp_executesql @sql; https://msdn.microsoft.com/pl-pl/library/ms188001%28v=sql.110%29.aspx?f=255&MSPPError=-2147217396