如何将 CTE 用作循环?
Posted
技术标签:
【中文标题】如何将 CTE 用作循环?【英文标题】:How to use a CTE as a loop? 【发布时间】:2016-10-26 09:45:38 【问题描述】:有没有办法将此光标转换为循环/递归 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】:如果您可以使用函数而不是过程,则无需使用 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
,名为 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
【讨论】:
以上是关于如何将 CTE 用作循环?的主要内容,如果未能解决你的问题,请参考以下文章
Oracle SQL 中的变量声明、CTE 和 While 循环
在 plpgsql(PostgreSQL 的)中,可以将 CTE 保留到外循环吗?
SQL Server连续日期 - 将多行汇总为连续的开始和结束日期行,而不包含CTE,循环,... s