BCP 更新数据库 table 基于 powershell 的输出

BCP update database table base on output from powershell

我有 4 个文件具有相同的 csv header 如下

Column1,Column2,Column3,Column4 


但我只需要来自 Column2,Column3,Column4 的数据,以便使用 BCP 将数据导入 SQL 数据库。我正在使用 PowerShell select 我想要的列并使用 BCP 导入所需的数据但是我的 powershell 执行没有错误并且我的数据库 table 中没有更新数据。我可以知道如何设置 BCP 以将 Powershell 的输出导入数据库 table。这是我的 powershell 脚本

$filePath = Get-ChildItem -Path 'D:\test\*' -Include $filename
$desiredColumn = 'Column2','Column3','Column4'

foreach($file in $filePath)
{
  write-host $file
 $test = import-csv $file | select $desiredColumn
 write-host $test
 $action = bcp <myDatabaseTableName> in $test -T -c -t";" -r"\n" -F2 -S <MyDatabase>
}



这些是 powershell 脚本的输出

D:\test\sample1.csv
@{column2=111;column3=222;column4=333} @{column2=444;column3=555;column4=666}
D:\test\sample2.csv
@{column2=777;column3=888;column4=999} @{column2=aaa;column3=bbb;column4=ccc}

首先,您不能 更新 table 与 bcp。它用于批量加载数据。也就是说,它将 insert 新行或 export 现有数据到平面文件中。更改现有行(通常称为更新)超出了 bcp 的范围。如果那是你需要的,你需要使用另一个工具。 Sqlcmd 工作正常,Powershell 的 Invoke-Sqlcmd 用于 运行 任意 TSQL 语句。

无论如何,BCP utility 的语法非常棘手。据我所知,不能通过将数据作为参数传递给 bcp 来批量加载数据,必须使用源文件。因此,您需要保存过滤后的文件并将其名称传递给 bcp.

导出过滤后的 CSV 非常简单,只需记住使用 -NoTypeInformation 开关,以免第一行数据为 #TYPE Selected.System.Management.Automation.PSCustomObject。假设 bcp 论点很好(为什么 -F2 和 Unix 换行符?)。

去除双引号需要对文件进行另一次编辑。脚本专家 has a solution.

foreach($file in $filePath){
  write-host $file
  $test = import-csv $file | select $desiredColumn
  # Overwrite filtereddata.csv, should one exist, with filtered data
  $test | export-csv -path .\filtereddata.csv -NoTypeInformation
  # Remove doulbe quotes
  (gc filtereddata.csv) | % {$_ -replace '"', ''} | out-file filtereddata.csv -Fo -En ascii
  $action = bcp <myDatabaseTableName> in filtereddata.csv -T -c -t";" -r"\n" -F2 -S <MyDatabase>
}

根据您的语言环境,列分隔符可能是分号、冒号或其他。使用 -Delimiter '<character>' 开关传递您需要的任何内容或更改 bcp 的参数。

Erland a helpful page about bulk operations. Also, see Redgate's advice.

无需先修改文件,这里有一个关于 bcp 如何处理引用数据的答案。

本质上,你需要使用-f选项和create/use一个格式文件来告诉SQL你的自定义字段分隔符(简而言之,它不再是一个单独的逗号(,)而是现在是 (",")... 带有两个双引号的逗号。需要转义 dblquotes 和一个小技巧来处理一行中的第一个双引号。但它就像一个魅力。

此外,需要格式文件忽略列...只需将目标列号设置为零即可。所有这些都无需在加载前修改文件。祝你好运!