2017-04-04 136 views
1

我一直在努力與System.OutOfMemoryException。我已經看到了一些解決方案,但都說你需要更多的RAM。我懷疑它是否由於代碼效率低下。所以讓我分享一下我的問題。
我有10個不同的表,每個表中有5k條記錄,我需要從每個表中選擇一個列並構建一個新表。我能夠插入大約1.5k條記錄,但隨後執行停止,並且「System.OutOfMemoryException」 。 我while循環看起來像是否在存儲過程中使用while循環導致System.OutOfMemoryException?

ALTER PROCEDURE Sp_sample 
As 
    Select col1 
    into 
    #ControlTable 
    from 
    tab1 

while exists(select * from #ControlTable) 
    begin 

      (select count(*) from #ControlTable); 
      select @var1 = (select top 1 col1 from #ControlTable);   
      select @var2 = (select top 1 col2 from table1 where [email protected]); 
      if exists (select a from tablenew where [email protected]) 
      begin    
       update tablenew set col2 = @var2 where col1 = @var1 
      end 
      else 
      begin   
       insert into tablenew values (@var1,@var2) 
      end 
      delete from #ControlTable where col1 = @var1; 
    end 
Begin 

我已經發布的示例代碼,使問題更通用。 任何幫助或建議將不勝感激。

+0

你的意思是'select @ var1 =(從#ControlTable選擇top 1 col1);'? – artm

+1

我覺得你正在壓倒這個任務,很容易用[合併語句](https://technet.microsoft.com/en-us/library/bb522522(v = sql.105).aspx)來完成。另外,有些部分不會像'(從#ControlTable選擇count(*)');' –

+1

同意Jorge--'(從#ControlTable選擇count(*));'將生成一個單獨的*結果集*每次循環迭代。所以,如果你正在談論5000行,你將會生成5000個結果集供客戶端系統處理。 –

回答

3

請嘗試以下while循環和檢查性能:

ALTER PROCEDURE Sp_sample 
As 
Select col1, ROW_NUMBER() OVER(Order By col1) AS RowNo 
into 
#ControlTable 
from 
tab1 

DECLARE @Index INT=1; 
DECLARE @TotalRow INT=0; 

SELECT @TotalRow=COUNT(col1) FROM #ControlTable 

while @Index<[email protected] 
begin    
     select @var1 = var1 from #ControlTable where [email protected];   
     select @var2 = var2 from table1 where [email protected]; 

     if exists (select a from tablenew where [email protected]) 
     begin    
      update tablenew set col2 = @var2 where col1 = @var1 
     end 
     else 
     begin   
      insert into tablenew values (@var1,@var2) 
     end 
     SET @Index = @Index+1; 
end 
Begin 
+0

謝謝@Sandip。它爲我工作。 – Hitsa00

1

你可以使用MERGE插入或更新表。

Select col1, max(col2) AS col2 into #ControlTable from tab1 GROUP BY col1 

MERGE tablenew AS T 
USING #ControlTable AS S 
ON (T.col1 = S.col1) 
WHEN NOT MATCHED BY TARGET 
    THEN INSERT(col1, col2) VALUES(S.col1, S.col2) 
WHEN MATCHED 
    THEN UPDATE SET T.col2 = S.col2