通过使用PowerShell将表列与SQL匹配来加载CSV

时间:2017-08-22 08:42:30

标签: sql-server powershell csv

我的要求是将系统生成的CSV文件加载到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 table查询:

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
);

以下是我在PowerShell中使用Out-datatable.ps1write-datatable.ps1

的尝试
. 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数据。

1 个答案:

答案 0 :(得分:2)

使用格式良好的CSV文件,您不需要手动指定-Header行,PowerShell会自动计算出来。但是,您的文件具有重复的列名称(PowerShell区分大小写,因此Namename重复),您将收到如下错误:

The member "Name" is already present

要解决此问题,您需要首先重命名其中一列以使其唯一(然后删除代码的-Header部分),或者您可以使用{{1使用您希望每列属性名称手动指定完整标题行的属性。您可以使用字符串数组来执行此操作,例如:

-Header

通过执行此操作,您还无需执行代码的$my_import = Import-CSV –useCulture -Header 'Employee_id','First_Name','Last_Name','Shift','Day','Night' $csvfile | Out-datatable 部分来重命名列名称,因为它们将正确设置为开头。