2011-09-29 48 views
1

後更新與數等差數列列我有一個PresentationSlide表:高效的方式刪除操作

PresentationSlide 
    PresentationSlideId 
    PresentationId 
    Content 
    Order 

和示例行:

+---------------------+----------------+---------+-------+ 
| PresentationSlideId | PresentationId | Content | Order | 
+--------+------------+----------------+---------+-------+ 
|     123 |    3 | "bla" |  1 | 
|     23 |    3 | "bla2" |  2 | 
|     22 |    3 | "bla3" |  3 | 
|     100 |    3 | "bla4" |  4 | 
|     150 |    3 | "bla5" |  5 | 
+---------------------+----------------+---------+-------+  

我想保持數等差數列(1 ,2,3,4,...)在Order列後DELETE操作。

例如,如果我刪除第三行(PresentationSlideId = 22),以列的值將是:(1,2,4,5)我想更新Order這樣:

PresentationSlideId = 100: update order from 4 to 3 
PresentationSlideId = 150: update order from 5 to 4 

如何是最有效的方式做這樣的更新?有什麼辦法只使用一個UPDATE陳述?我可以使用遊標和循環來做到這一點,但效果並不理想。

回答

2

1)令是一列一個很可憐的名字,因爲它是一個SQL關鍵字

2)這將是好了很多,如果你能在訂單與空白應對(也可能切換到使用浮點數,所以你可以插入小數值),因爲在你當前的模型中,每一次插入,更新或刪除都可能影響整個表格。這並不好。在選擇期間使用ROW_NUMBER()計算訂單通常會更好。

3)

create table #PresentationSlide (
    PresentationSlideID int not null, 
    PresentationId int not null, 
    Content varchar(10) not null, 
    [Order] int not null 
) 
insert into #PresentationSlide (PresentationSlideId , PresentationId , Content , [Order]) 
select 123,3,'bla',1 union all 
select 23,3,'bla2',2 union all 
select 22,3,'bla3',3 union all 
select 100,3,'bla4',4 union all 
select 150,3,'bla5',5 


delete from #PresentationSlide where PresentationSlideId = 22 

;With Reorder as (select PresentationSlideId,ROW_NUMBER() OVER (ORDER BY [Order]) as NewOrder from #PresentationSlide) 
update ps set [Order] = NewOrder 
from #PresentationSlide ps inner join Reorder r on ps.PresentationSlideId = r.PresentationSlideId 

select * from #PresentationSlide order by [Order] 

drop table #PresentationSlide 
+0

廣告2:我不知道,如果使用float和分數值是不錯的主意。據我所知,float具有有限的精度,因此在固定行之後多次插入行後,'Order'派系值將開始相同。剩下的就好了。 –

+0

@Lacasus - 整數也具有有限的精度。如果花車讓你感覺不舒服,可以考慮將初始'Order'值賦值爲10的倍數。不管怎樣,這個想法是允許使用可用間隙執行一些插入和更新,並且不必執行重新編號操作*每*次(您可能仍需執行重新編號,但可降低操作的*平均成本) –

+0

小備註:您的代碼僅適用於一個演示文稿,我添加了「WHERE PresentationId = @PresentationId」表達式,其中@PresentationId是已刪除行的PresentationId,現在它可以工作(但只有當所有已刪除的行共享相同的PresentationId時)。 –

2
;with C as 
(
    select [Order],  
     row_number() over(order by [Order]) as rn 
    from PresentationSlide 
) 
update C set 
    [Order] = rn