2014-01-27 29 views
1

我正在開發一個ASP.NET應用程序,用於分析用戶上傳的Excel文件。這些文件包含有關客戶的各種數據(一行=一個客戶),關鍵字段爲CustomerCode。基本上數據以DataTable對象的形式出現。SQL Server - 規避大型IN(...)子句(> 40000項)的最佳實踐

在某些時候,我需要從SQL獲取有關指定客戶的信息,並將其與用戶上傳的信息進行比較。我做了以下方法:'Customer1','Customer2',...'CustomerN'

  1. CustomerCode列做一個逗​​號分隔的客戶名單。
  2. 將此字符串傳遞給SQL查詢IN (...)子句並執行它。

這是工作好,直到我試圖傳遞〜裏面IN (...)第40000項時跑進The query processor ran out of internal resources and could not produce a query plan例外。

瑣碎的方式似乎:

  1. 在查詢模板替換IN (...)= 'SomeCustomerCode'
  2. 對每個CustomerCode執行此查詢40000次。
  3. DataTable.Merge 40000次。

有沒有更好的方法來解決這個問題?

注意:我不能做IN (SELECT CustomerCode FROM ... WHERE SomeConditions),因爲數據來自Excel文件,因此無法從數據庫查詢。

+2

您是否可以不創建臨時表並將其添加到主表中? – Andrew

+0

是的,也想過這個。但是在這種情況下,我需要插入40000行,或者通過另一個大的INSERT查詢(它不會失敗嗎?)或執行40000次INSERT。 – Taosique

+0

從40000個輸入生成最終表格所產生的*結果*有多可用?此外,SQL Server具有可以讀取Excel文件的OLE DB提供程序,如果將文件放置在數據庫服務器可以讀取它們的某個位置是可行的,那麼「從Excel文件中不能從DB查詢」。是不正確的。 –

回答

1

"Table valued parameters"值得研究,它允許你通過(通常是通過C#端的DataTable)多行 - 缺點是你需要正式聲明並命名SQL服務器上的數據形狀。

或者,您可以使用SqlBulkCopy將行放入暫存表中,然後僅將JOIN添加到該表中。如果你有並行調用者,你需要在行上使用某種類型的會話標識符來區分併發使用(以及:不要忘記隨後刪除會話的數據)。

0

你不應該一次處理太多的記錄,因爲你提到的錯誤,它是如此大的一批,它需要太多的時間來運行,你不能並行做任何事情。您不應該一次只處理一條記錄,因爲那樣SQL Server通信的開銷就會太大。在中間選擇一些東西,例如。 10000次記錄。您甚至可以並行處理,您可以在處理先前的10000批處理時在後臺開始運行下一個10000的SQL。