2012-01-03 111 views
1

我們需要定期導入CSV,看起來像這樣:是唯一導入數據 - C#/ SQL Server的解決方案

Name,SpecID,TestResult1,TestResult2,TestResult3 
Alex,ASD123,3.23,452.2,232 
Craig,DFG444,453.56,345.3,23 

得到的數據存儲是這樣的:

SPECIMENTABLE (name,specid,SPECIMENTABLEID) 
Alex,ASD123,1 
Craig,DFG444,2 

RESULTTABLE (testresult,result,SPECIMENTABLEID) 
    TestResult1,3.23,1 
    TestResult2,452.2,1 
    TestResult3,232,1 
    TestResult1, 453.56,2 
    etc 

即時傾銷這樣的數據:

public void DumpQuickLabDump() 
    { 
     // T-SQL Connection 
     string connection = "Data Source=gaia;Initial Catalog=SalesDWH;Integrated Security=True"; 


     // Get the data into the DataTable 
     //dtData = GetData(...); 

     // Create an object of SqlBulkCopy 
     SqlBulkCopy objSBC = new SqlBulkCopy(connection); 
     // Specify the destination table 
     objSBC.BulkCopyTimeout = 0; 
     objSBC.BatchSize = 10000; 
     objSBC.DestinationTableName = "SpecimenTable"; 
     // Write the data to the SQL Server 

     objSBC.WriteToServer(QuickLabDump); 
    } 
    public void DumpTestResults() 
    { 
     // T-SQL Connection 
     string connection = "Data Source=gaia;Initial Catalog=SalesDWH;Integrated Security=True"; 


     // Get the data into the DataTable 
     //dtData = GetData(...); 

     // Create an object of SqlBulkCopy 
     SqlBulkCopy objSBC = new SqlBulkCopy(connection); 
     // Specify the destination table 
     objSBC.BulkCopyTimeout = 0; 
     objSBC.BatchSize = 10000; 
     objSBC.DestinationTableName = "ResultTable"; 
     // Write the data to the SQL Server 

     objSBC.WriteToServer(TestResults); 
    } 

有時客戶端會向我提交上傳的CSV文件,然後幾天後,他們會導入另一個CSV文件,但它會有一定比例的相同記錄。

我該如何避免重複數據? (請注意,從一個CSV文件中的數據庫中填充了兩個表格)

解決方案可以是.NET或sql。

太感謝你了

+0

你熟悉三角洲是什麼本聲明?也聽起來像你可能需要改變你的查詢添加SQL來檢查IfExist或NotExist取決於你的邏輯,以確定是否更新行或行,我會建議一個日期或時間戳上的關鍵字段的Delta,因爲你怎麼知道即使日期是當前日期,也是正確的如果數據回滾或意外更改,該怎麼辦? – MethodMan 2012-01-03 22:32:19

+0

@DJKRAZE我可能只是在字段組合上做 – 2012-01-03 22:35:40

+0

@DJKRAZE不,我不知道delta是什麼 – 2012-01-03 22:36:17

回答

4

你不能直接使用SqlBulkCopy做你想要的。但是,您可以將行批量複製到工作表中,然後使用MERGE語句來更新或插入。

但是,這確實需要您的源信息具有足夠的信息來唯一標識每一行。

讓我們假設例如代替SpecimenTableobjSBC.DestinationTableName它被設置爲StagingSpecimenTable。 StagingSpecimenTable是一個SpecimenTable結構的副本。然後批量複製後,您可以執行使用一個SqlCommand

MERGE SpecimenTable AS target 
USING (SELECT name,specid FROM StagingSpecimenTable) 
    AS source (StagingSpecimenTable) 
ON (target.specid = source.specid) 
WHEN MATCHED 
    THEN UPDATE SET target.mame= source.name 
WHEN NOT MATCHED 
    THEN INSERT (name, specid) 
    VALUES (source.name, source.specid) 

然後你不得不刪除或截斷StagingSpecimenTable以及類似的操作ResultTable

+0

+1:SQLBulkCopy專爲「盡力而爲」設計,以儘可能快速。因此,解決方案是批量複製到保留表中,然後運行SQL,將它們(適當時)拖到主表中。 – MatBailie 2012-01-03 23:45:15

+0

@conrad你能告訴我我將如何使用合併來做到這一點 – 2012-01-04 17:10:18

+1

@我確信我已經更新了我的答案 – 2012-01-04 17:33:03

1

您需要Data deduplication機制,以檢測哪些記錄是以前進口的,這樣做,你需要有一個邏輯,能夠找到重複數據刪除的記錄。

你的邏輯是什麼?例如,您可以將SpecID設置爲主要的重複數據刪除規則,這意味着如果您的SpecID與數據庫中的數據相同,則不要導入它,否則將其導入。

或者您可以爲您的規則組合字段,如「名稱+ SpecID」或甚至所有要收集的字段。在這種情況下,我建議使用助手字段,您可以在其中存儲MD5(或任何其他散列機制)以存儲將所有字段組合到重複數據刪除規則中的散列值,然後在插入之前需要爲新值生成散列並檢查它是否已經存在通過查詢您的助手字段存在於您的表格中。

這可能有點混淆,但邏輯非常簡單。請讓我知道如果您需要更多的幫助:-)