2013-05-10 156 views
-2

我在這裏有一個查詢來更新每個代表最近的庫存清單類型的表。但是,我得到它的唯一方法是使用遊標,這真的會影響性能。以下是我正在使用的表格聲明和查詢。我還能做些什麼來更快地達到預期效果?如何提高查詢性能?

表:

create table #inv (
Rep_LName nvarchar (50), 
Rep_FName nvarchar (50), 
Rep_ID nvarchar (50), 
Rep_Email nvarchar (100), 
Rep_Status nvarchar (50), 
Rep_BU nvarchar (50), 
Sales_Force nvarchar (50), 
Territory nvarchar (50), 
Sample_Eligibility nvarchar (50), 
DM_Name nvarchar (100), 
Phys_Inv_Date datetime, 
Last_Reconciled datetime, 
Inv_Type nvarchar(50), 
Days_Since_Last_inv int) 

查詢:

declare Inventory_type cursor 
for select rep_ID, inventory_type 
from inv_header 
where rep_id in (select rep_id from #inv) 
order by call_date desc 
declare @rep_ID nvarchar(50) 
declare @inventory_type nvarchar(50) 
declare @ls_Sql as nvarchar(max) 
declare @param as nvarchar(max) 
select @ls_Sql='' 
select @param='' 
-- open cursor 
open Inventory_type 

fetch next from Inventory_type 
into @rep_ID, @inventory_type 
while (@@fetch_status = 0) 
begin 
    --use parameterized dynamic sql 
    SET @param='@rep_ID nvarchar(50),@inventory_type nvarchar(50)' 
    SET @ls_Sql='update #inv set Inv_Type = @inventory_type 
WHERE rep_id = @rep_id AND Inv_Type IS NULL' 

    --pass parameter to dynamic query 
    exec sp_executesql @ls_Sql,@param,@rep_ID,@Inventory_type 

    fetch next from Inventory_type 
    into @rep_ID, @Inventory_type 
end 

close Inventory_type 
deallocate Inventory_type 
+2

當然你可以做到這一點作爲UPDATE語句? – Simon 2013-05-10 13:19:26

+2

RBAR警報! (通過激動的行排列)......... – granadaCoder 2013-05-10 13:21:25

+1

這裏是一個學習的例子.....它展示了一個RBAR解決方案,然後將它重構爲一個基於集合的解決方案。 http://granadacoder.wordpress.com/2008/07/24/cursors-setbased-and-scalar-udf/ – granadaCoder 2013-05-10 13:23:00

回答

4

不要使用遊標;他們破壞查詢性能。是的,他們出於某種原因出現在產品中,但他們是最後一招的工具,幾乎總是可以通過基於集合的方法完成工作。一個簡單的更新語句在這裏可以很好地工作。

update i 
set i.Inv_Type = h.inventory_type 
from #inv i 
inner join inv_header h on i.rep_id = h.rep_id 
    and h.Call_date = 
    (select Max(Call_Date) 
    from inv_header i2 
    where i2.rep_id = i.rep_id) 
where i.inv_type is null 
+0

我的第一個想法。 – 2013-05-10 13:27:10

+3

這將不會得到最新呼叫日期inventory_type – 2013-05-10 13:32:53

+0

@CharlesBretana優秀點;編輯。 – 2013-05-10 13:33:59

0

了我的頭頂部,不知道你的數據庫中,這樣的事情應該工作:

UPDATE #inv set Inv_Type = (SELECT inventory_type FROM inv_header 
    WHERE #inv.Rep_ID = inv_header.rep_id) 
    WHERE Inv_Type IS NULL 

你可以也可以將它作爲連接來使用,可能會更有效,具體取決於您擁有的行數。

應該讓你至少開始....

0

我認爲他想擁有最新的贖回日的inv_type ..

update inv 
set inv.Inv_Type = ih.inventory_type 
from (
    select rep_ID, max(call_date) max_call_date 
    from inv_header 
    where rep_id in (select rep_id from #inv) 
    group by rep_ID) a 
inner join inv_header ih 
    on ih.rep_ID = a.rep_ID 
    and ih.call_date = a.max_call_date 
inner join #inv inv 
    on inv.rep_ID = ih.rep_id 
    and inv.Inv_Type is null 
1

試試這個:

update i set 
    Inv_Type = h.inventory_type 
    From #inv i join inv_header h 
    on h.rep_id = i.Rep_ID 
     And h.Call_date = 
      (Select Max(Call_Date) 
      From inv_header 
      Where rep_id = i.rep_id) 
    where i.Inv_Type Is Null