2010-07-12 99 views
1

我需要將一些CSV文件導入到SQL中相應的表中。我試圖編寫一個存儲過程,將導入任何這些CSV文件,使用一些參數來設置文件名,目的地名稱等東西。具有驗證功能的CSV導入

到目前爲止很簡單。問題出在這個DB的結構上。每個數據表都有許多(通常是5)列,它們是一組設置格式,然後是所需的許多數據列。然後有一組數據驗證表,其中包含這5列可以包含的特定值組。所以問題是,當我從CSV導入時,我需要驗證導入的每一行都符合這些驗證表中的條件,實質上驗證表中有一行中的數據與5導入數據中的列。

如果沒有,那麼它需要向日志中寫入錯誤並且不導入它,如果是的話就應該導入它。

這裏是我的意思的例子:

數據表(其中導入的數據會)

|datatype|country|currency| datacolumn1 | datacolumn| 
|1  | 2  | GBP | 10000  | 400  | 
|3  | 4  | USD | 10000  | 400  | 

驗證表

|datatype|country|currency| 
|1  |2  |GBP  | 
|2  |3  |USD  | 

所以第一行是有效的,它在前3列的驗證表中具有匹配記錄,但是se cond不是,應該被拒絕。

增加的問題是每個表可以引用不同的驗證表(儘管許多引用同一個表),所以必須檢查的列經常在數量和名稱上有所不同。

我的第一個問題是如何在從CSV導入時逐行檢查,有沒有辦法在不導入臨時表的情況下執行此操作? 之後,檢查列匹配的最好方法是什麼,儘管事實上列的名稱和列數根據正在導入的表而變化,但檢查列是否匹配。

+2

快速,簡短的回答:使用SQL Server Integration Services(SSIS) – 2010-07-12 14:45:20

+0

您是否真的需要進行逐行驗證?這將是一個痛苦緩慢的過程,如果你碰巧有大量的行 – 2010-07-12 14:45:38

+0

@philip不幸的是,這是不可能的,它需要從另一套存儲過程調用 – 2010-07-12 14:46:23

回答

2

您可以通過導入CSV的內容到一些臨時表這一點 -

SELECT * into newtable FROM 
OPENROWSET ('MSDASQL', 'Driver={Microsoft Text Driver (*.txt; *.csv)};DefaultDir={Directory Path of the CSV File};', 
'SELECT * from yourfile.csv'); 

一旦你有了一些SQL表數據,您可以使用一個內連接來驗證數據和縮小到有效的行。

SELECT A.*,B.* FROM newtable A 
INNER JOIN validation_table B ON A.Datatype = B.Datatype 
INNER JOIN validation_table C ON A.Country = C.Country 
INNER JOIN validation_table D ON A.Currency = D.Currency 

這應該根據您的驗證規則爲您提供有效的行。

+0

不要忘記,無效行的數量大於零,你必須殺死整個事情。 – 2010-07-12 15:08:59

+0

我會添加,一旦你有一個臨時表中的所有記錄,然後執行驗證檢查並將壞記錄從表中移出到異常表(帶有添加異常原因的ans)。這將使處理更容易,因爲您已經清除了任何不良數據,如果somone詢問爲什麼記錄XYZ不在prod數據庫中,您將能夠查找並查看原因。 – HLGEM 2012-10-23 20:10:56

1

SSIS將允許您在加載數據時檢查,過濾和處理數據。我不知道有任何其他的原生SQL工具可以做到這一點。如果沒有SSIS(或第三方工具),您必須先將文件中的所有數據加載到某種「暫存」表(#temp或專用永久性表)中,然後從那裏開始工作。

@Pavan Reddy的OPENROWSET解決方案應該可以工作。我已經使用了視圖,我首先確定了源文件中的行,在目標表上構建了一個「映射」視圖,然後將BULK INSERTED插入到視圖中(還允許您在「跳過的列」上使用默認值玩遊戲) 。

(僅舉,你可以從一個存儲過程中推出的SSIS包,使用xp_cmdshell的調用DTEXEC這是複雜的,需要的參數一臺主機,但它可以做到的。)