PowerShellとBCPを使用してCSVをSQL Serverにロードするのを手伝ってください
-
29-09-2019 - |
質問
私はBCPを使用して、遠く離れた他の誰かによって別のテーブルからエクスポートされたCSVからテーブルをロードし、いくつかの問題に遭遇しました。私の元の2つの問題:1つのエクスポートされたフィールドは、Varcharフィールドで終わる必要があるINTであり、別のフィールドに静的文字列を入力する必要があります。まあ、最初は大したことではなく、チャドの答えは私を @{n='Col3';e={'ABC'}}
構文。しかし、私はデータを正しくロードするいくつかの問題につまずいています。
値にスペースがない場合もあれば、場合によってはそうかもしれません。 BCP形式ファイルでそのデリミターを指定するにはどうすればよいですか?おそらくこれらを引用符で囲む必要があるからです。
a。中間CSVファイルに引用符を付けて値をラッピングする必要がありますか?
私のテストコードでは、最初の行のCOL1の実際の値を使用して、列ヘッダーとCOL1にラインフィードを押し込んでいます。
私の実際の、無化されていないコードでは、私は取得しています
String data, right truncation
最初の行では、2番目の行が挿入されていますが、大丈夫です。
とにかく、私が他の場所から得た最初のCSVデータはこのように見えます(注:ヘッダーの行はありません)
"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
, 、 と りんご の中へ Col4
. Export1 静的文字列です。 PowerShell 1.0でこれを行っています。
編集:ChadのImport-CSV | Export -CSVは有望に見えますが、ヘッダーが欠落しているのは好きではなく、PS 1.0は-Headerオプションをサポートしていません。
編集:上記の説明を編集して、私がこの時点にさまよった方法を反映しています。 4列のテーブルと3列のCSVは、明らかに単純化されています。 1つの実際の列は都市であるため、単純な文字列または引用が必要な文字列が含まれている可能性があります。この時点でのPowerShell 1.0コードは次のとおりです。
$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を使用してみませんか?完全な制御:行ごとに読み取り、データを変換し、希望どおりにデータテーブルを入力し、バッチでwritetoserverを呼び出します。見る http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlbulkcopy.aspx
他のヒント
列を追加するためにこのようなことをすることができます
import -csv。 forum.csv -header "col1"、 "col2"、 "col4" | col1、col2、 @{n = 'col3'; e = {'export1'}}、col4 | Export-csv ./forum2.csv -notypeinfo