帮助我使用powershell和bcp将CSV加载到SQL Server中 [英] Help me use powershell and bcp to load CSV into SQL Server

查看:160
本文介绍了帮助我使用powershell和bcp将CSV加载到SQL Server中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用bcp从其他人从另一个表导出的CSV加载一个表,但是遇到了一些问题.我最初遇到的两个问题是:一个导出字段是一个int,需要以varchar字段结尾,而另一个字段则需要用静态字符串填充.好吧,第一个没什么大不了的,Chad的回答使我想到了@{n='Col3';e={'ABC'}}语法.但是我在围绕正确获取数据的几个问题上步履蹒跚.

I'm using bcp to load a table from a CSV exported from another table by someone else far far away, and have run into some issues. My original two problems: one exported field is an int that needs to end up in a varchar field, and another field needs to be populated with a static string. Well, the first is no big deal, and Chad's answer led me to the @{n='Col3';e={'ABC'}} syntax. But i'm stumbling around several issues getting the data loaded correctly.

  1. 有时,一个值可能没有空格,有时可能没有空格.如何在bcp格式文件中为此指定分隔符?我问,因为大概我需要用引号将它们括起来.

  1. Sometimes a value might have no spaces, sometimes it might. How do i specify delimiters for that in a bcp format file? I ask because presumably i need to surround these with quotes.

a.我应该在带引号的中间CSV文件中包装值吗?

a. Should i be wrapping values in the intermediate CSV file with quotes?

在我的测试代码中,它将列标题和换行符与第一行的实际值Col1一起推入Col1中.

In my test code, it's shoving the column headers and a linefeed into Col1 with the actual value of Col1 for the first row.

在我实际的未经消毒的代码中,尽管第二行已插入,但第一行却显示String data, right truncation.

In my actual, unsanitized code, i'm getting String data, right truncation on the first row, though the second row is inserted okay.

无论如何,我从其他地方获取的初始CSV数据看起来像这样(注意:没有标题行)

Anyhow, the initial CSV data that i get from elsewhere looks like this (note: no header row)

"ABC123",123456,"APPLE"
"XYZ789",456789,"ORANGE"

目标SQL表是这样的

Col1 varchar(50) (Primary Key)
Col2 varchar(50)
Col3 varchar(50)
Col4 varchar(50)

我需要将 ABC123 装入Col1 123456 装入Col2 Export1 装入Col3将APPLE 放入Col4. Export1 是静态字符串.我正在Powershell 1.0中做到这一点.

I need to load ABC123 into Col1, 123456 into Col2, Export1 into Col3, and APPLE into Col4. Export1 is the static string. I'm doing this in Powershell 1.0.

乍得的import-csv | export-csv看起来很有希望,但是它不喜欢缺少标头,并且PS 1.0不支持-Header选项.

Chad's import-csv | export-csv looks promising, but it doesn't like missing headers, and PS 1.0 doesn't support the -Header option.

上面编辑的描述以反映我如何徘徊到这一点.四列表和三列CSV显然是简化的.一个真实的列是一个城市,因此它可以包含简单的字符串或需要引用的字符串.此时,我的Powershell 1.0代码如下.

Edited description above to reflect how i've wandered to this point. The four-column table and three-column CSV are obviously simplifications. One real column is a city, so it could contain simple strings or those that require quoting. My Powershell 1.0 code at this point is as follows.

$SQLSERVER="svr"
$SQLTABLE="test"
$SQLUSER="u"
$SQLPASS="p"

$TESTFILE = "testdata.csv"
$TESTFILEHDR = "testdata-wHeaders.csv"
$TESTFILEFIX = "testdata-fixed.csv"
$OrigHeaders = "`"Col1`",`"Col2`",`"Col3`"`n"

function Create-BcpFormat($fileName)
{
@"
<?xml version='1.0'?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <RECORD>
  <FIELD ID='1' xsi:type='CharTerm' TERMINATOR=',"' COLLATION='SQL_AltDiction_CP850_CI_AS'/>
  <FIELD ID='2' xsi:type='CharTerm' TERMINATOR='",' COLLATION='SQL_AltDiction_CP850_CI_AS'/>
  <FIELD ID='3' xsi:type='CharTerm' TERMINATOR=',' COLLATION='SQL_AltDiction_CP850_CI_AS'/>
  <FIELD ID='4' xsi:type='CharTerm' TERMINATOR='\r\n' COLLATION='SQL_AltDiction_CP850_CI_AS'/>
 </RECORD>
 <ROW>
  <COLUMN SOURCE="1" NAME="Col1" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="2" NAME="Col2" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="3" NAME="Col3" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="4" NAME="Col4" xsi:type="SQLVARYCHAR"/>
 </ROW>
</BCPFORMAT>
"@ | Set-Content $filename
}

## GHI456 is already in the table, clean out previous attempts
"`nclean test table:"
osql @("-S","$SQLSERVER","-U","$SQLUSER","-P","$SQLPASS","-Q",
    """delete from $SQLTABLE where col1 <> 'GHI456' or col1 is null""")

## Prepend
$body = [string]::join([environment]::NewLine, (gc $TESTFILE))
$OrigHeaders + $body > $TESTFILEHDR

"`nTESTFILEHDR:"
type $TESTFILEHDR

$accts = Import-csv $TESTFILEHDR | select 'Col1', 'Col2', @{n='Col3';e={'ABC'}}, @{n='Col4';e={$_.Col3}}
$accts
$accts | Export-Csv $TESTFILEFIX -NoTypeInfo

"`nTESTFILEFIX:"
type $TESTFILEFIX

$BCPFMTFILE = "bcp.fmt"
$BCPERRFILE = "bcp.err"
Create-BcpFormat $BCPFMTFILE
bcp @("$SQLTABLE","in","$TESTFILEFIX","-S","$SQLSERVER","-U","$SQLUSER","-P","$SQLPASS","-f",$BCPFMTFILE,"-e",$BCPERRFILE)
Remove-Item $BCPFMTFILE

"`ntest table:"
osql @("-S","$SQLSERVER","-U","$SQLUSER","-P","$SQLPASS","-Q",
    """select left(Col1,20) 'Col1', left(Col2,8) 'Col2', left(Col3,8) 'Col3', left(Col4,8) 'Col4' from $SQLTABLE""")

"`nBCPERRFILE:"
type $BCPERRFILE

推荐答案

为什么不在PowerShell中以编程方式使用ADO.NET的SqlBulkCopy? 您将拥有完全的控制权:逐行读取,转换数据并根据需要填充DataTable,然后分批调用WriteToServer. 请参阅 http://msdn.microsoft.com/en -us/library/system.data.sqlclient.sqlbulkcopy.aspx

Why don't you use ADO.NET's SqlBulkCopy programmatically in PowerShell? You will have full control: read line by line, convert data and populate a DataTable as you wish and invoke WriteToServer in batches. See http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy.aspx

这篇关于帮助我使用powershell和bcp将CSV加载到SQL Server中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆