循环遍历SQL中的值

时间:2015-04-14 09:58:18

标签: sql sql-server-2008

下面的select语句将测试id的列表

select testID from tblTests 

我有基于测试ID更新结果的代码。我想循环上面的代码,以便我可以一次循环一个ID。我如何循环上述语句中的所有测试ID?

--get decision from tbloptions
declare @decision nvarchar
declare @newQuestionNo char(10)
declare @suffix char(1)
declare @scenarioID int
declare @scenarioNo int
declare @testsummaryid int
declare @points int

select 
    @decision = tbloptions.decision,
    @newQuestionNo = rtrim(tbloptions.GoToQuestion),
    @points = coalesce(tbloptions.points,0),
    @suffix = tbloptions.GoToSuffix,
    @scenarioID = tbloptions.scenarioID,
    @testsummaryid = testsummaryid 
from 
    tbloptions with(nolock)
    join tbltests on tbloptions.scenarioID = tbltests.scenarioID
        and tbloptions.questionNo = tbltests.questionNo
where 
    tbltests.testid = 


if @newQuestionNo in ('Pass','Neutral','Fail')
begin
--end scenario session
    update tblTestSummaries
    set 
        end_date = getdate(),
        points = @points,
        completed = 1,
        timetaken = dbo.TimeTaken(
            (select 
                start_date 
            from tbltestsummaries
            where testsummaryid = @testsummaryid),
            getdate()),
        result = case 
            when @points > 2 then 'P'
            when @points = 2 then 'I'
            when @points < 2 then 'F'
        end, 
        testSessionID = @testSessionID
    where testsummaryid = @testsummaryid
end

1 个答案:

答案 0 :(得分:0)

SQL Server已经过优化,可以执行基于集合的操作。当您尝试应用迭代逻辑时,会降低性能。如果您来自编码背景(或ISAM数据库背景),那么在基于集合的关系数据库方式中思考起初可能会非常棘手。如果您发现自己在寻找迭代解决方案或者认为需要使用光标,那么您可能需要退后一步,问问自己是否真的以最有效的方式做到了这一点。

以下查询应该执行您正在查找的内容,并仍然允许SQL Server优化查询。请注意查询中的注释。

UPDATE  TS
SET     end_date = getdate(),
        points = coalesce(O.points,0),
        completed = 1,
        timetaken = dbo.TimeTaken(start_date, getdate()),
        result = case 
            when coalesce(O.points,0) > 2 then 'P'
            when coalesce(O.points,0) = 2 then 'I'
            when coalesce(O.points,0) < 2 then 'F'
        end, 
        testSessionID = @testSessionID -- I did not see this variable anywhere else in your code and am assuming it's defined elsewhere.
FROM    tbloptions O --with(nolock)  Be Careful using this.  Read about "dirty reads" below.
JOIN    tbltests T on O.scenarioID = T.scenarioID and O.questionNo = T.questionNo
JOIN    tblTestSummaries TS ON TS.testSummaryID = T.testSummaryID
WHERE   rtrim(tbloptions.GoToQuestion) IN ('Pass', 'Neutral', 'Fail') -- Note that this is not Sargable and may not perform well. Consider changing the varchar field to a FK to remove the need to trim the text.

详细了解the NOLOCK hint

详细了解Sargable statements