2017-08-22 22 views
1

我的要求是將系統生成的CSV文件加載到SQL表中。下面我提供了CSV文件,表格查詢和我的代碼。使用PowerShell將表列匹配到SQL加載CSV

以下是CSV文件abc.csvxyz.csv哪一列每次都像列表中的第二個文件一樣變化,正如您可以看到最後兩列進行混洗。

 
id,Name,name,Shift,Day,Night 
1,ert,sdf,08/21/2017 Day,2,- 
2,wer,asdf,08/21/2017 Day,-,1 
3,rty,adsf,08/21/2017 Day,1,- 
4,yui,adsf,08/21/2017 Day,-,- 
5,qwe,asdf,08/21/2017 Day,-,- 
6,ret,asdf,08/21/2017 Day,-,- 
7,chh,asdf,08/21/2017 Day,-,- 
8,sdf,cxvv,08/21/2017 Day,1,- 
 
id,Name,name,Shift,Night,Day 
1,ert,sdf,08/21/2017 Day,-,2 
2,wer,asdf,08/21/2017 Day,1,- 
3,rty,adsf,08/21/2017 Day,-,1 
4,yui,adsf,08/21/2017 Day,-,- 
5,qwe,asdf,08/21/2017 Day,-,- 
6,ret,asdf,08/21/2017 Day,-,- 
7,chh,asdf,08/21/2017 Day,-,- 
8,sdf,cxvv,08/21/2017 Day,-,1 

下面是創建表查詢的SQL加載此數據:

CREATE DATABASE MES; 
USE MES; 
CREATE TABLE MESdata 
(
    Id    int NOT NULL IDENTITY(1,1) PRIMARY KEY, 
    Employee_id  int NOT NULL, 
    First_Name  varchar(20) NOT NULL, 
    Last_Name  varchar(20) NOT NULL, 
    Shift   varchar(20) NOT NULL, 
    Day    int NULL, 
    Night   int NULL 
); 

以下爲使用Out-datatable.ps1write-datatable.ps1我在PowerShell中嘗試:

. C:\ReadCSV\Out-datatable.ps1; 
. C:\ReadCSV\write-datatable.ps1; 

if (Test-Path Variable:\my_import) { 
    Remove-Variable my_import 
} 

$csvfile = 'C:\ReadCSV\abc.csv' 
$header  = Get-Content 'C:\ReadCSV\abc.csv' | select -First 1 
$sqlTable = 'MESdata' 
$DataSource = 'HOST\INSTANCE' 
$DataBase = 'MES' 
$my_import = Import-Csv -UseCulture -Header $header $csvfile | 
       select @{Label="Employee_id";Expression={$_."id"}}, 
        @{Label="First_Name";Expression={$_."Name"}}, 
        @{Label="Last_Name";Expression={$_."name"}}, 
        @{Label="Shift";Expression={$_."Shift"}}, 
        @{Label="Day";Expression={$_."Day"}}, 
        @{Label="Night";Expression={$_."Night"}} | 
       Out-DataTable  
Write-DataTable -ServerInstance $DataSource -Database $DataBase -TableName $sqlTable -Data $my_import 
#$ConnectionString ='Data Source={0}; Database={1}; Trusted_Connection=True;' -f $DataSource,$DataBase 
#$bulkCopy = New-Object Data.SqlClient.SqlBulkCopy($ConnectionString) 
#$bulkCopy.DestinationTableName = $sqlTable 
#$bulkCopy.WriteToServer($my_import) 

我第一個錯誤:

 
Exception calling "WriteToServer" with "1" argument(s): "Column 'Employee_id' 
does not allow DBNull.Value." 
At C:\ReadCSV\stackoverflow.ps1:25 char:1 
+ $bulkCopy.WriteToServer($my_import) 
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    + CategoryInfo   : NotSpecified: (:) [], MethodInvocationException 
    + FullyQualifiedErrorId : InvalidOperationException 

我該怎麼辦?我是否需要更改表格字段的數據類型,但我不想那樣。但是,如果我將所有不爲null替換爲null,那麼該腳本將執行而不會出錯,但會包含所有NULL數據。

+0

你不需要這樣做'-Header $ header',我懷疑它導致你的問題。 –

+2

這就是說我認爲你會遇到一個問題,因爲PowerShell不區分大小寫,所以有兩列名爲「Name」。 –

回答

2

如果格式良好的CSV文件不需要手動指定-Header行,PowerShell會自動計算出結果。但是你的文件有一個重複的列名(PowerShell是區分大小寫,因此Namename副本),你會得到這樣的錯誤:

The member "Name" is already present 

若要解決此你要麼需要重命名這些列中的一個首先使它們唯一(然後刪除代碼的-Header部分),或者也可以使用-Header屬性手動指定完整標題行,使用您希望爲每列指定的任何屬性名稱。你這樣做使用字符串e.g數組:

$my_import = Import-CSV –useCulture -Header 'Employee_id','First_Name','Last_Name','Shift','Day','Night' $csvfile | Out-datatable 

這樣做,你也再不用做你的代碼的Select部分重命名的列名,因爲他們將要設置正確的開始。

+1

重命名重複標題可以說是更好的選擇,因爲它不需要關於列順序的知識。 –

+0

@AnsgarWiechers我改變了我的腳本,正如你所提到的關於標題,但我的主要問題是我的輸入CSV文件每次隨着列位置獲取更改,如我在xyz.csv中所示,所以我想正確的數據進入正確的表字段,這就是爲什麼我使用'選擇',但現在我得到他從數據中給出值類型字符串 源無法轉換爲指定目標列的類型int。「此錯誤數據不會去sql表。請幫助我與代碼 – Paddy

+0

@Paddy'Import-Csv'會自動執行此操作,前提是您的CSV文件具有標題行並且沒有重複的列名稱。 –