2015-04-14 77 views
0

值以下select語句slects的更新結果基於測試ID測試ID的循環儘管SQL

select testID from tblTests 

我的代碼的打擊名單。我想循環通過上面的代碼,以便我可以一次循環一個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

更改'where tbltests.testid ='to'where tbltests.testid IN(select testID from tblTests)''。歡呼!不需要循環! –

+2

如果你必須循環,那麼你將需要創建一個基於你的SELECT語句的CURSOR和循環使用光標 – Mike

+0

我沒有添加所有的conde – user3636426

回答

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. 

查看更多about the NOLOCK hint

查看更多about Sargable statements