首页 > 解决方案 > BCP 根据 powershell 的输出更新数据库表

问题描述

我有 4 个具有相同 csv 标头的文件,如下所示

Column1,Column2,Column3,Column4 


但我只需要Column2,Column3,Column4使用BCP. 我正在使用 PowerShell 选择我想要的列并使用导入所需的数据,BCP但我的 powershell 执行没有错误,并且我的数据库表中没有更新数据。我可以知道如何设置将BCP输出从 Powershell 导入数据库表。这是我的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}

标签: sqlpowershellbcp

解决方案


首先,您不能使用bcp. 它用于批量加载数据。也就是说,它将插入新行或将现有数据导出到平面文件中。更改现有行(通常称为更新)超出了bcp. 如果这就是你需要的,你需要使用另一个工具。Sqlcmd工作正常,并且 PowershellInvoke-Sqlcmd可以运行任意 TSQL 语句。

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

导出过滤后的 CSV 很容易,只要记住使用-NoTypeInformationswitch,以免你得到#TYPE Selected.System.Management.Automation.PSCustomObject第一行数据。假设bcp论点很好(为什么-F2?还有 Unix 换行符?)。

去除双引号需要对文件进行另一次编辑。脚本专家有一个解决方案

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>'switch 传递您需要的任何内容或更改bcp的参数。

Erland 有一个关于批量操作的有用页面。另请参阅 Redgate 的建议


推荐阅读