简体   繁体   English

遍历 SQL Server 2008 中的行

[英]Iterate through rows in SQL Server 2008

Consider the table SAMPLE:考虑表 SAMPLE:

id       integer
name     nvarchar(10)

There is a stored proc called myproc .有一个名为myproc的存储过程。 It takes only one paramater ( which is id)它只需要一个参数(即 id)

Given a name as parameter, find all rows with the name = @nameparameter and pass all those ids to myproc给定一个名称作为参数,找到name = @nameparameter的所有行并将所有这些 id 传递给myproc

eg:例如:

sample->
1   mark
2   mark
3   stu
41  mark

When mark is passed, 1,2 and 41 are to be passed to myproc individually.mark通过时, 1,2 and 41将分别传递给myproc

ie the following should happen:即应该发生以下情况:

execute myproc 1
execute myproc 2
execute myproc 41

I can't touch myproc nor see its content.我无法触摸myproc也无法查看其内容。 I just have to pass the values to it.我只需要将值传递给它。

If you must iterate(*), use the construct designed to do it - the cursor .如果您必须迭代(*),请使用设计用于执行此操作的构造 - cursor Much maligned, but if it most clearly expresses your intentions, I say use it:备受诟病,但如果它最清楚地表达了你的意图,我说使用它:

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

(*) This answer has received a few upvotes recently, but I feel I ought to incorporate my original comment here also, and add some general advice: (*)这个答案最近收到了一些赞成票,但我觉得我应该在这里也加入我的原始评论,并添加一些一般性建议:

In SQL, you should generally seek a set-based solution.在 SQL 中,您通常应该寻求基于集合的解决方案。 The entire language is oriented around set-based solutions, and (in turn) the optimizer is oriented around making set-based solutions work well.整个语言都围绕基于集合的解决方案,并且(反过来)优化器旨在使基于集合的解决方案运行良好。 In further turn, the tools that we have available for tuning the optimizer is also set-oriented - eg applying indexes to tables.进而,我们可用于调整优化器的工具也是面向集合的——例如将索引应用于表。

There are a few situations where iteration is the best approach.某些情况下,迭代是最好的方法。 These are few are far between, and may be likened to Jackson's rules on optimization - don't do it - and (for experts only) don't do it yet .这些是相距甚远的,并且可能类似于杰克逊的优化规则 - 不要这样做 - 并且(仅限专家)要这样做。

You're far better served to first try to formulate what you want in terms of the set of all rows to be affected - what is the overall change to be achieved?您最好首先尝试根据要影响的所有行的集合来制定您想要的内容 - 要实现的总体变化是什么? - and then try to formulate a query that encapsulates that goal. - 然后尝试制定一个封装该目标的查询。 Only if the query produced by doing so is not performing adequately (or there's some other component that is unable to do anything other than deal with each row individually) should you consider iteration.只有当这样做产生的查询没有充分执行(或者有一些其他组件除了单独处理每一行之外无法做任何事情)时,您才应该考虑迭代。

I just declare the temporary table @sample and insert the all rows which have the name='rahul' and also take the status column to check that the row is iterated.and using while loop i iterate through the all rows of temporary table @sample which have all the ids of name='rahul'我只是声明临时表 @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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM