153

次のようなテキスト ファイルにデータを簡単にダンプできます。

sqlcmd -S myServer -d myDB -E -Q "select col1, col2, col3 from SomeTable" 
     -o "MyData.txt"

ただし、ヘルプ ファイルをSQLCMD見ましたが、CSV 専用のオプションは見当たりませんでした。

を使用してテーブルから CSV テキスト ファイルにデータをダンプする方法はありますSQLCMDか?

4

12 に答える 12

154

次のようなものを実行できます。

sqlcmd -S MyServer -d myDB -E -Q "select col1, col2, col3 from SomeTable" 
       -o "MyData.csv" -h-1 -s"," -w 700
  • -h-1結果から列名ヘッダーを削除します
  • -s","列区切り記号を , に設定します
  • -w 700行幅を 700 文字に設定します (これは、最も長い行と同じ幅にする必要があります。そうしないと、次の行に折り返されます)
于 2009-01-08T19:08:34.753 に答える
94

PowerShell を使用すると、Invoke-Sqlcmd を Export-Csv にパイプすることで、問題をうまく解決できます。

#Requires -Module SqlServer
Invoke-Sqlcmd -Query "SELECT * FROM DimDate;" `
              -Database AdventureWorksDW2012 `
              -Server localhost |
Export-Csv -NoTypeInformation `
           -Path "DimDate.csv" `
           -Encoding UTF8

SQL Server 2016 には、SSMS 2016 をインストールしただけでも使用できるコマンドレットを含むSqlServerモジュールが含まれています。それ以前は、SQL Server 2012 には古いSQLPSモジュールが含まれていました。これにより、現在のディレクトリがモジュールがインストールされた時点に変更されます。 (他のバグの中でも)最初に使用されたため、上記の行を次のように変更する必要があります。Invoke-SqlcmdSQLSERVER:\#Requires

Push-Location $PWD
Import-Module -Name SQLPS
# dummy query to catch initial surprise directory change
Invoke-Sqlcmd -Query "SELECT 1" `
              -Database  AdventureWorksDW2012 `
              -Server localhost |Out-Null
Pop-Location
# actual Invoke-Sqlcmd |Export-Csv pipeline

この例を SQL Server 2008 および 2008 R2 に適合させるには、#Requires行全体を削除し、標準の PowerShell ホストの代わりにsqlps.exe ユーティリティを使用します。

Invoke-Sqlcmdは、sqlcmd.exe に相当する PowerShell です。テキストの代わりにSystem.Data.DataRowオブジェクトを出力します。

このパラメーターは、sqlcmd.exe-Queryのパラメーターと同様に機能します。-Qエクスポートするデータを記述する SQL クエリを渡します。

このパラメーターは、sqlcmd.exe-Databaseのパラメーターと同様に機能します。-dエクスポートするデータを含むデータベースの名前を渡します。

このパラメーターは、sqlcmd.exe-Serverのパラメーターと同様に機能します。-Sエクスポートするデータを含むサーバーの名前を渡します。

Export-CSVは、汎用オブジェクトを CSV にシリアル化する PowerShell コマンドレットです。PowerShell に同梱されています。

この-NoTypeInformationパラメーターは、CSV 形式の一部ではない余分な出力を抑制します。既定では、コマンドレットは型情報を含むヘッダーを書き込みます。後で で逆シリアル化するときにオブジェクトのタイプを知ることができますが、Import-Csv標準の CSV を期待するツールを混乱させます。

このパラメーターは、sqlcmd.exe-Pathのパラメーターと同様に機能します。古いSQLPSモジュール-oを使用している場合は、この値のフル パスが最も安全です。

パラメータは、sqlcmd.exeのまたはパラメータの-Encodingように機能します。デフォルトでは、Export-Csv は ASCII 文字のみを出力し、その他すべてを疑問符に置き換えます。代わりに UTF8 を使用して、すべての文字を保持し、他のほとんどのツールとの互換性を維持してください。-f-u

sqlcmd.exe または bcp.exe に対するこのソリューションの主な利点は、有効な CSV を出力するためにコマンドをハックする必要がないことです。Export-Csv コマンドレットがすべてを処理します。

主な欠点はInvoke-Sqlcmd、パイプラインに沿って渡す前に結果セット全体を読み取ることです。エクスポートする結果セット全体に十分なメモリがあることを確認してください。

数十億行の場合、スムーズに機能しない場合があります。それが問題である場合は、他のツールを試すか、System.Data.SqlClient.SqlDataReaderクラスをInvoke-Sqlcmd使用し て独自の効率的なバージョンを作成することができます。

于 2014-06-01T02:21:34.883 に答える
76
sqlcmd -S myServer -d myDB -E -o "MyData.txt" ^
    -Q "select bar from foo" ^
    -W -w 999 -s","

最後の行には、CSV 固有のオプションが含まれています。

  • -W   個々のフィールドから末尾のスペースを削除する
  • -s","   列区切り記号をコンマ (,) に設定します
  • -w 999   行幅を 999 文字に設定します

scottm の答えは私が使用するものに非常に近い-Wですが、CSV を他の場所で使用するときに空白を削除する必要はありません。

MSDN sqlcmd リファレンスも参照してください。それは/?オプションの出力を恥ずかしく思います。

于 2010-03-11T16:42:29.987 に答える
63

これbcpは意図されたものではありませんか?

bcp "select col1, col2, col3 from database.schema.SomeTable" queryout  "c:\MyData.txt"  -c -t"," -r"\n" -S ServerName -T

これをコマンド ラインから実行して、構文を確認します。

bcp /?

例えば:

usage: bcp {dbtable | query} {in | out | queryout | format} datafile
  [-m maxerrors]            [-f formatfile]          [-e errfile]
  [-F firstrow]             [-L lastrow]             [-b batchsize]
  [-n native type]          [-c character type]      [-w wide character type]
  [-N keep non-text native] [-V file format version] [-q quoted identifier]
  [-C code page specifier]  [-t field terminator]    [-r row terminator]
  [-i inputfile]            [-o outfile]             [-a packetsize]
  [-S server name]          [-U username]            [-P password]
  [-T trusted connection]   [-v version]             [-R regional enable]
  [-k keep null values]     [-E keep identity values]
  [-h "load hints"]         [-x generate xml format file]
  [-d database name]

bcp列ヘッダーを出力できないことに注意してください。

参照先: bcp ユーティリティドキュメント ページ。

上記のページの例:

bcp.exe MyTable out "D:\data.csv" -T -c -C 65001 -t , ...
于 2011-03-25T05:19:20.720 に答える
12

これを行おうとしているが、列ヘッダーも持っている人へのメモ。これは、バッチファイルを使用した解決策です。

sqlcmd -S servername -U username -P password -d database -Q "set nocount on; set ansi_warnings off; sql query here;" -o output.tmp -s "," -W
type output.tmp | findstr /V \-\,\- > output.csv
del output.tmp

これにより、初期結果 (ヘッダーとデータの間の ----,---- セパレーターを含む) が一時ファイルに出力され、findstr でフィルター処理してその行が削除されます。フィルターで除外しているため、完全ではないことに注意してください-,-。出力に列が 1 つしかない場合は機能しません。また、その文字列を含む正当な行もフィルターで除外されます。

于 2011-08-31T16:04:43.597 に答える
1

BCP の代替オプション:

exec master..xp_cmdshell 'BCP "sp_who" QUERYOUT C:\av\sp_who.txt -S MC0XENTC -T -c '
于 2016-11-16T05:04:45.910 に答える
-1

ハックな方法でそれを行うことができます。sqlcmdハックの使用には注意してください。データに二重引用符またはコンマが含まれていると、問題が発生します。

簡単なスクリプトを使用して、適切に実行できます。

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Data Exporter                                                 '
'                                                               '
' Description: Allows the output of data to CSV file from a SQL '
'       statement to either Oracle, SQL Server, or MySQL        '
' Author: C. Peter Chen, http://dev-notes.com                   '
' Version Tracker:                                              '
'       1.0   20080414 Original version                         '
'   1.1   20080807 Added email functionality                '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
option explicit
dim dbType, dbHost, dbName, dbUser, dbPass, outputFile, email, subj, body, smtp, smtpPort, sqlstr

'''''''''''''''''
' Configuration '
'''''''''''''''''
dbType = "oracle"                 ' Valid values: "oracle", "sqlserver", "mysql"
dbHost = "dbhost"                 ' Hostname of the database server
dbName = "dbname"                 ' Name of the database/SID
dbUser = "username"               ' Name of the user
dbPass = "password"               ' Password of the above-named user
outputFile = "c:\output.csv"      ' Path and file name of the output CSV file
email = "email@me.here"           ' Enter email here should you wish to email the CSV file (as attachment); if no email, leave it as empty string ""
  subj = "Email Subject"          ' The subject of your email; required only if you send the CSV over email
  body = "Put a message here!"    ' The body of your email; required only if you send the CSV over email
  smtp = "mail.server.com"        ' Name of your SMTP server; required only if you send the CSV over email
  smtpPort = 25                   ' SMTP port used by your server, usually 25; required only if you send the CSV over email
sqlStr = "select user from dual"  ' SQL statement you wish to execute
'''''''''''''''''''''
' End Configuration '
'''''''''''''''''''''



dim fso, conn

'Create filesystem object 
set fso = CreateObject("Scripting.FileSystemObject")

'Database connection info
set Conn = CreateObject("ADODB.connection")
Conn.ConnectionTimeout = 30
Conn.CommandTimeout = 30
if dbType = "oracle" then
    conn.open("Provider=MSDAORA.1;User ID=" & dbUser & ";Password=" & dbPass & ";Data Source=" & dbName & ";Persist Security Info=False")
elseif dbType = "sqlserver" then
    conn.open("Driver={SQL Server};Server=" & dbHost & ";Database=" & dbName & ";Uid=" & dbUser & ";Pwd=" & dbPass & ";")
elseif dbType = "mysql" then
    conn.open("DRIVER={MySQL ODBC 3.51 Driver}; SERVER=" & dbHost & ";PORT=3306;DATABASE=" & dbName & "; UID=" & dbUser & "; PASSWORD=" & dbPass & "; OPTION=3")
end if

' Subprocedure to generate data.  Two parameters:
'   1. fPath=where to create the file
'   2. sqlstr=the database query
sub MakeDataFile(fPath, sqlstr)
    dim a, showList, intcount
    set a = fso.createtextfile(fPath)

    set showList = conn.execute(sqlstr)
    for intcount = 0 to showList.fields.count -1
        if intcount <> showList.fields.count-1 then
            a.write """" & showList.fields(intcount).name & ""","
        else
            a.write """" & showList.fields(intcount).name & """"
        end if
    next
    a.writeline ""

    do while not showList.eof
        for intcount = 0 to showList.fields.count - 1
            if intcount <> showList.fields.count - 1 then
                a.write """" & showList.fields(intcount).value & ""","
            else
                a.write """" & showList.fields(intcount).value & """"
            end if
        next
        a.writeline ""
        showList.movenext
    loop
    showList.close
    set showList = nothing

    set a = nothing
end sub

' Call the subprocedure
call MakeDataFile(outputFile,sqlstr)

' Close
set fso = nothing
conn.close
set conn = nothing

if email <> "" then
    dim objMessage
    Set objMessage = CreateObject("CDO.Message")
    objMessage.Subject = "Test Email from vbs"
    objMessage.From = email
    objMessage.To = email
    objMessage.TextBody = "Please see attached file."
    objMessage.AddAttachment outputFile

    objMessage.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
    objMessage.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserver") = smtp
    objMessage.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = smtpPort

objMessage.Configuration.Fields.Update

    objMessage.Send
end if

'You're all done!!  Enjoy the file created.
msgbox("Data Writer Done!")

出典: VBScript を使用して SQL 出力を CSV に書き込む

于 2009-01-08T18:50:56.833 に答える