2015-01-07 73 views
2

我經常看到專家用戶建議嘗試在數據庫級別避免循環(參考文獻here)。我有一小段代碼,我不能看到其他方式來實現任務而不使用循環。這項任務非常簡單,但有沒有辦法避免循環?有沒有辦法避免SQL Server 2008 R2中的這個循環?

DECLARE @id INT = 1 
DECLARE @auxId INT 

WHILE @id IS NOT NULL 
BEGIN 
    SET @auxId = @id 
    SELECT @id = id_next_version FROM task WHERE id_task = @id 
END 

SELECT @aux 

解釋代碼:

我哪裏有任務,有一些行的其他任務的更新一臺,所以我有哪裏是下一個版本的ID列。我想要的是找到最後一個任務版本的id

編輯:

表結構

CREATE TABLE task 
(
    id_task INT IDENTITY(1,1) NOT NULL, 
    task NVARCHAR(50) NULL, 
    id_next_version INT NULL 
) 

回答

4

您遍歷圖 - 可能是一個樹形結構實際上。你可以用遞歸CTE來做到這一點:

with cte as (
    select id_task, id_next_version, 1 as lev 
    from task 
    where id_task = @id 
    union all 
    select t.id_task, t.id_next_version, cte.lev + 1 
    from task t join 
     cte 
     on t.id_task = cte.id_next_version 
    ) 
select top 1 * 
from cte 
order by lev desc; 

我不確定這比你的循環更優雅。它應該是一個更快的iota,因爲你只傳入一個查詢。

Here是一個說明代碼的SQL小提琴。

+0

我只是運行你的代碼,但沒有返回任何東西。任何提示? – smartdan

+0

@DanielGonzalez。 。 。它既適用於SQL小提琴,也適用於本地SQL Server實例中的示例數據。 –

+0

根據我的經驗,這可能比iota更快。這實質上是將循環移入循環連接。該循環的機體更緊密。 – usr

相關問題