Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Tsql 如何将CTE用作环路?_Tsql_Loops_Cursor_Common Table Expression_Recursive Query - Fatal编程技术网

Tsql 如何将CTE用作环路?

Tsql 如何将CTE用作环路?,tsql,loops,cursor,common-table-expression,recursive-query,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)

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

如果可以使用函数而不是过程,则无需使用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\u存储的函数必须是表值函数(而不是标量)。在上面的示例中,函数返回的一列是
nvarchar
named
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
的更多信息: