![](/img/trans.png)
[英]Iterate through rows and insert data in temp table - SQL Server 2008
[英]Iterate through rows in SQL Server 2008
考虑表 SAMPLE:
id integer
name nvarchar(10)
有一个名为myproc
的存储过程。 它只需要一个参数(即 id)
给定一个名称作为参数,找到name = @nameparameter
的所有行并将所有这些 id 传递给myproc
例如:
sample->
1 mark
2 mark
3 stu
41 mark
当mark
通过时, 1,2 and 41
将分别传递给myproc
。
即应该发生以下情况:
execute myproc 1
execute myproc 2
execute myproc 41
我无法触摸myproc
也无法查看其内容。 我只需要将值传递给它。
如果您必须迭代(*),请使用设计用于执行此操作的构造 - cursor 。 备受诟病,但如果它最清楚地表达了你的意图,我说使用它:
DECLARE @ID int
DECLARE IDs CURSOR LOCAL FOR select ID from SAMPLE where Name = @NameParameter
OPEN IDs
FETCH NEXT FROM IDs into @ID
WHILE @@FETCH_STATUS = 0
BEGIN
exec myproc @ID
FETCH NEXT FROM IDs into @ID
END
CLOSE IDs
DEALLOCATE IDs
(*)这个答案最近收到了一些赞成票,但我觉得我应该在这里也加入我的原始评论,并添加一些一般性建议:
在 SQL 中,您通常应该寻求基于集合的解决方案。 整个语言都围绕基于集合的解决方案,并且(反过来)优化器旨在使基于集合的解决方案运行良好。 进而,我们可用于调整优化器的工具也是面向集合的——例如将索引应用于表。
在某些情况下,迭代是最好的方法。 这些是相距甚远的,并且可能类似于杰克逊的优化规则 - 不要这样做 - 并且(仅限专家)不要这样做。
您最好首先尝试根据要影响的所有行的集合来制定您想要的内容 - 要实现的总体变化是什么? - 然后尝试制定一个封装该目标的查询。 只有当这样做产生的查询没有充分执行(或者有一些其他组件除了单独处理每一行之外无法做任何事情)时,您才应该考虑迭代。
我只是声明临时表 @sample 并插入所有具有 name='rahul' 的行,并使用状态列检查该行是否已迭代。并使用 while 循环我遍历临时表 @sample 的所有行具有 name='rahul' 的所有 id
use dumme
Declare @Name nvarchar(50)
set @Name='Rahul'
DECLARE @sample table (
ID int,
Status varchar(500)
)
insert into @sample (ID,status) select ID,0 from sample where sample=@name
while ((select count(Id) from @sample where status=0 )>0)
begin
select top 1 Id from @sample where status=0 order by Id
update @sample set status=1 where Id=(select top 1 Id from @sample where status=0 order by Id)
end
Declare @retStr varchar(100)
select @retStr = COALESCE(@retStr, '') + sample.ID + ', '
from sample
WHERE sample.Name = @nameparameter
select @retStr = ltrim(rtrim(substring(@retStr , 1, len(@retStr )- 1)))
Return ISNULL(@retStr ,'')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.