วิธีการส่งออกข้อมูลเป็นรูปแบบ CSV จาก SQL Server โดยใช้ sqlcmd


142

ฉันสามารถถ่ายโอนข้อมูลลงในไฟล์ข้อความได้อย่างง่ายดายเช่น:

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

อย่างไรก็ตามฉันได้ดูไฟล์วิธีใช้แล้วSQLCMDแต่ยังไม่เห็นตัวเลือกสำหรับ CSV โดยเฉพาะ

มีวิธีการถ่ายโอนข้อมูลจากตารางลงในไฟล์ข้อความ CSV โดยใช้SQLCMDหรือไม่?


ต้องเป็นผ่าน sqlcmd หรือคุณสามารถใช้โปรแกรมอื่นเช่น codeproject.com/KB/aspnet/ImportExportCSV.aspx
Bernhard Hofmann

ไม่จำเป็นต้องเป็น แต่ฉันต้องการทราบให้แน่ชัดว่า sqlcmd สามารถทำได้จริงหรือไม่ก่อนที่จะดำน้ำในยูทิลิตี้การส่งออกอื่น ๆ สิ่งหนึ่งที่ต้องพูดถึงก็คือต้องเป็นสคริปต์
Ray

มีเครื่องมือ addin SSMS 2008 ที่สร้างเอาต์พุต CSV จากตารางของคุณซึ่งสามารถปรับแต่งตามตำแหน่งและเรียงลำดับตามส่วน store.nmally.com/software/sql-server-management-studio-addons/…

คำตอบ:


142

คุณสามารถเรียกใช้สิ่งนี้:

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 ตัวอักษร (ต้องกว้างเท่ากับแถวที่ยาวที่สุดมิฉะนั้นจะตัดไปที่บรรทัดถัดไป)

24
ข้อแม้ในการทำเช่นนี้คือข้อมูลของคุณต้องไม่มีเครื่องหมายจุลภาค
Sarel Botha

1
@SarelBotha คุณสามารถแก้ไขปัญหา'""' + col1 + '""' AS col1นั้นด้วยเครื่องหมายคำพูดคู่ (สองเท่า) หรือเพียงแค่เรียกขั้นตอนการจัดเก็บ
MisterIsaak

2
@JIsaak จากนั้นตรวจสอบให้แน่ใจว่าข้อมูลของคุณไม่มีเครื่องหมายอัญประกาศคู่หรืออย่าลืมแทนที่เครื่องหมายคำพูดคู่ของคุณด้วยเครื่องหมายคำพูดคู่สองคำ
Sarel Botha

1
มีใครช่วยชี้แจงสิ่งที่ต้องทำเพื่ออนุญาตให้มีเครื่องหมายจุลภาคภายในข้อมูลได้ไหม เราต้องล้อมทุกคอลัมน์ด้วย "" "+ ___ +" "" "หรือไม่?
Ahmed

2
คำตอบนี้ล้าสมัยแล้ว สคริปต์ PowerShell มีความยืดหยุ่นมากขึ้นและสามารถเรียกใช้ใน SQL Server เป็น Job Agent
Clinton Ward

79

ด้วย 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 ประกอบด้วยโมดูลSqlServerซึ่งมีInvoke-Sqlcmdcmdlet ซึ่งคุณจะมีแม้ว่าคุณจะเพิ่งติดตั้ง SSMS 2016 ก่อนหน้านั้น SQL Server 2012 รวมโมดูลSQLPSเก่าซึ่งจะเปลี่ยนไดเร็กทอรีปัจจุบันเป็นSQLSERVER:\เมื่อโมดูลเป็น ใช้ครั้งแรก (ท่ามกลางข้อบกพร่องอื่น ๆ ) ดังนั้นคุณจะต้องเปลี่ยน#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บรรทัดทั้งหมดและใช้ยูทิลิตี้ sqlps.exeแทนโฮสต์ PowerShell มาตรฐาน

Invoke-Sqlcmdเทียบเท่า PowerShell ของ sqlcmd.exe แทนที่จะเป็นข้อความจะส่งออกอ็อบเจ็กต์System.Data.DataRow

-Queryพารามิเตอร์การทำงานเช่น-Qพารามิเตอร์ของ sqlcmd.exe ส่งแบบสอบถาม SQL ที่อธิบายข้อมูลที่คุณต้องการส่งออก

-Databaseพารามิเตอร์การทำงานเช่น-dพารามิเตอร์ของ sqlcmd.exe ส่งชื่อของฐานข้อมูลที่มีข้อมูลที่จะส่งออก

-Serverพารามิเตอร์การทำงานเช่น-Sพารามิเตอร์ของ sqlcmd.exe ส่งชื่อของเซิร์ฟเวอร์ที่มีข้อมูลที่จะส่งออก

Export-CSVคือ PowerShell cmdlet ที่จัดลำดับออบเจ็กต์ทั่วไปเป็น CSV มาพร้อมกับ PowerShell

-NoTypeInformationพารามิเตอร์ยับยั้งเอาท์พุทพิเศษที่ไม่ได้เป็นส่วนหนึ่งของรูปแบบรูปแบบ CSV ตามค่าเริ่มต้น cmdlet จะเขียนส่วนหัวด้วยข้อมูลประเภท ช่วยให้คุณทราบประเภทของออบเจ็กต์เมื่อคุณยกเลิกการกำหนดค่าในภายหลังด้วยImport-Csvแต่ทำให้สับสนกับเครื่องมือที่คาดว่าจะได้รับ CSV มาตรฐาน

-Pathพารามิเตอร์การทำงานเช่น-oพารามิเตอร์ของ sqlcmd.exe เส้นทางแบบเต็มสำหรับค่านี้จะปลอดภัยที่สุดหากคุณติดอยู่โดยใช้โมดูลSQLPS แบบเก่า

-Encodingพารามิเตอร์ทำงานเหมือน-fหรือ-uพารามิเตอร์ของ sqlcmd.exe โดยค่าเริ่มต้น Export-Csv จะแสดงเฉพาะอักขระ ASCII และแทนที่เครื่องหมายคำถามอื่น ๆ ทั้งหมด ใช้ UTF8 แทนเพื่อรักษาอักขระทั้งหมดและเข้ากันได้กับเครื่องมืออื่น ๆ ส่วนใหญ่

ข้อได้เปรียบหลักของโซลูชันนี้สำหรับ sqlcmd.exe หรือ bcp.exe คือคุณไม่ต้องแฮ็กคำสั่งเพื่อส่งออก CSV ที่ถูกต้อง cmdlet Export-Csv จะจัดการทุกอย่างให้คุณ

ข้อเสียเปรียบหลักคือInvoke-Sqlcmdอ่านชุดผลลัพธ์ทั้งหมดก่อนที่จะส่งต่อไปตามท่อ ตรวจสอบให้แน่ใจว่าคุณมีหน่วยความจำเพียงพอสำหรับชุดผลลัพธ์ทั้งหมดที่คุณต้องการส่งออก

อาจทำงานได้ไม่ราบรื่นสำหรับหลายพันล้านแถว หากเป็นปัญหาคุณสามารถลองใช้เครื่องมืออื่น ๆ หรือInvoke-Sqlcmdใช้ คลาสSystem.Data.SqlClient.SqlDataReader ที่มีประสิทธิภาพของคุณเอง


5
คำตอบอื่น ๆ ดูดโดยสุจริตนี่เป็นวิธีเดียวที่จะทำอย่างถูกต้อง ฉันหวังว่ามันจะชัดเจนกว่านี้
Shagglez

1
ใน SQL 2008 R2 ฉันต้องเรียกใช้เครื่องมือ "sqlps.exe" เพื่อใช้ Invoke-Sqlcmd เห็นได้ชัดว่าฉันต้องการ SQL 2012 เพื่อใช้ Import-Module? ทำงานภายใน "sqlps.exe" - ดูรายละเอียดในหัวข้อนี้
Mister_Tom

1
@Mister_Tom จุดดี. โมดูล SQLPS ถูกนำมาใช้กับ SQL 2012 ตอนนี้คำตอบจะอธิบายถึงวิธีการปรับตัวอย่างสำหรับรุ่นเก่า
Iain Samuel McLean Elder

1
@JasonMatney PowerShell เป็นอินเทอร์เฟซการดูแลระบบใหม่สำหรับระบบ Windows แต่มีการเผยแพร่คำแนะนำของ SQL Server จำนวนมากก่อนที่จะกลายเป็นมาตรฐาน กระจายข่าว! :-)
Iain Samuel McLean Elder

1
คำตอบนี้ให้ข้อมูลที่เป็นประโยชน์และวิธีทางเลือกอื่นที่มีประสิทธิภาพและยืดหยุ่นในการจัดการปัญหา แต่ก็ไม่สามารถตอบคำถามเดิมได้อย่างสมบูรณ์ตามที่ถูกถามโดยเฉพาะ ฉันเป็นแฟนพาวเวอร์เชลล์เหมือนกัน แต่อย่าปล่อยให้การเผยแพร่ศาสนากลายเป็นฮิสทีเรีย SQLCMD จะไม่หายไปในเร็ว ๆ นี้
บาร์บีคิว

71
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ด้วย ทำให้/?ผลลัพธ์ของตัวเลือกอับอาย


19
@sims "set nocount on" ในส่วนเริ่มต้นของข้อความค้นหา / inputfile
d -_- b

7
ฉันจะลบการขีดเส้นใต้ส่วนหัวได้อย่างไร
ntombela

@gugulethun: คุณสามารถทำการรวมในแบบสอบถามของคุณเพื่อใส่ชื่อคอลัมน์ในบรรทัดแรก
Nordes

2
มันใช้งานได้เหมือนมีเสน่ห์ แต่ถ้าคอลัมน์ของคุณมีตัวคั่นฉันจะได้ไฟล์ csv ที่เสียหาย ...
Peter

เพิ่มความคิดเห็นนี้ในคำตอบที่ยอมรับเช่นกัน แต่ ... คุณสามารถแก้ไขปัญหา'""' + col1 + '""' AS col1นั้นได้ด้วยเครื่องหมายคำพูดคู่ (สองเท่า) หรือเพียงแค่เรียกขั้นตอนการจัดเก็บ
MisterIsaak

60

นี่ไม่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 , ...

1
ServerName = YourcomputerName \ SQLServerName จากนั้นจะดำเนินการข้อผิดพลาดเป็นอย่างอื่น
Hammad Khan

1
ในกรณีที่คุณต้องการที่จะเห็นเอกสารเต็มรูปแบบสำหรับ bcp.exe: technet.microsoft.com/en-us/library/ms162802.aspx
โรเบิร์ตสเตน

5
คุณจะทำอย่างไรถ้าคุณต้องการส่งออกชื่อคอลัมน์เป็นส่วนหัวด้วย? มีวิธีแก้ปัญหาทั่วไปที่ตรงไปตรงมาโดยใช้ bcp หรือไม่?
Iain Samuel McLean เอ็ลเดอร์

@johndacosta ขอบคุณมาก. คุณจะพิมพ์ส่วนหัวของคอลัมน์ด้วยอย่างไร ฉันไม่เห็นการเปลี่ยนไปใช้ที่ใดก็ได้ง่ายๆ ขอบคุณ!
Rachael

1
bcpไม่รวมส่วนหัว (ชื่อคอลัมน์) แต่เร็วกว่าประมาณ 10 เท่าsqlcmd(จากประสบการณ์ของฉัน) สำหรับข้อมูลขนาดใหญ่จริงๆคุณสามารถใช้bcpเพื่อรับข้อมูลและใช้sqlcmd(เลือก 0 อันดับสูงสุด * จาก ... ) เพื่อรับส่วนหัวจากนั้นรวมเข้าด้วยกัน
YJZ

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

สิ่งนี้จะแสดงผลลัพธ์เริ่มต้น (รวมถึง ----, ---- ตัวคั่นระหว่างส่วนหัวและข้อมูล) ลงในไฟล์ temp จากนั้นลบบรรทัดนั้นโดยกรองออกผ่าน findstr โปรดทราบว่ามันไม่สมบูรณ์แบบเนื่องจากมีการกรองออก-,-- จะไม่ทำงานหากมีเพียงคอลัมน์เดียวในเอาต์พุตและจะกรองบรรทัดที่ถูกต้องซึ่งมีสตริงนั้น


1
ใช้ตัวกรองต่อไปนี้แทน: findstr / r / v ^ \ - [, \ -] * $> output.csv ด้วยเหตุผลบางประการ simle ^ [, \ -] * $ ตรงกับทุกบรรทัด
Vladimir Korolev

3
ใส่ regex ด้วย ^ ไว้ในเครื่องหมายคำพูดคู่เสมอมิฉะนั้นคุณจะได้ผลลัพธ์แปลก ๆ เพราะ ^ เป็นอักขระหลีกสำหรับ cmd.exe regexes ทั้งสองข้างต้นทำงานไม่ถูกต้องเท่าที่ฉันสามารถบอกได้ แต่สิ่งนี้ทำได้: findstr / r / v "^ - [-,] * -. $" (ก่อนหน้า $ ดูเหมือนจะจำเป็นเมื่อทดสอบกับ echo แต่อาจไม่ใช่สำหรับเอาต์พุต sqlcmd)
JimG

นอกจากนี้ยังมีปัญหากับวันที่ที่มีช่องว่าง 2 ช่องระหว่างวันที่และเวลาแทนที่จะเป็นวันเดียว เมื่อคุณพยายามเปิด CSV ใน Excel จะแสดงเป็น 00: 00.0 วิธีง่ายๆในการแก้ไขปัญหานี้คือการค้นหาและแทนที่ "" ด้วย "" ทั้งหมดในตำแหน่งโดยใช้ SED คำสั่งที่จะเพิ่มลงในสคริปต์ของคุณคือ SED -i "s / / / g" output.csv เพิ่มเติมเกี่ยวกับ SED gnuwin32.sourceforge.net/packages/sed.htm
PollusB

นี่คือคำตอบที่ถูกต้องทำงานได้ดีกับการเพิ่มของ @ JimG ฉันใช้เครื่องหมายอัฒภาคสำหรับตัวคั่นและไฟล์ sql สำหรับอินพุตไฟล์มีส่วนที่ไม่นับและ ansi_warning off และสวิตช์ -W สำหรับการลบพื้นที่
robotik

1

คำตอบนี้สร้างจากโซลูชันจาก @ iain-elder ซึ่งทำงานได้ดียกเว้นกรณีฐานข้อมูลขนาดใหญ่ (ตามที่ระบุไว้ในโซลูชันของเขา) ตารางทั้งหมดต้องพอดีกับหน่วยความจำของระบบของคุณและสำหรับฉันนี่ไม่ใช่ตัวเลือก ฉันสงสัยว่าทางออกที่ดีที่สุดจะใช้System.Data.SqlClient.SqlDataReaderและ Serializer CSV ที่กำหนดเอง ( ดูตัวอย่างที่นี่ ) หรือภาษาอื่นที่มีไดรเวอร์ MS SQL และการทำให้เป็นอนุกรม CSV ในจิตวิญญาณของคำถามเดิมซึ่งอาจกำลังมองหาวิธีแก้ปัญหาที่ไม่มีการพึ่งพารหัส PowerShell ด้านล่างใช้ได้กับฉัน มันช้ามากและไม่มีประสิทธิภาพโดยเฉพาะอย่างยิ่งในการสร้างอินสแตนซ์อาร์เรย์ข้อมูล $ และการเรียก Export-Csv ในโหมดผนวกสำหรับทุก ๆ $ chunk_size บรรทัด

$chunk_size = 10000
$command = New-Object System.Data.SqlClient.SqlCommand
$command.CommandText = "SELECT * FROM <TABLENAME>"
$command.Connection = $connection
$connection.open()
$reader = $command.ExecuteReader()

$read = $TRUE
while($read){
    $counter=0
    $DataTable = New-Object System.Data.DataTable
    $first=$TRUE;
    try {
        while($read = $reader.Read()){

            $count = $reader.FieldCount
            if ($first){
                for($i=0; $i -lt $count; $i++){
                    $col = New-Object System.Data.DataColumn $reader.GetName($i)
                    $DataTable.Columns.Add($col)
                }
                $first=$FALSE;
            }

            # Better way to do this?
            $data=@()
            $emptyObj = New-Object System.Object
            for($i=1; $i -le $count; $i++){
                $data +=  $emptyObj
            }

            $reader.GetValues($data) | out-null
            $DataRow = $DataTable.NewRow()
            $DataRow.ItemArray = $data
            $DataTable.Rows.Add($DataRow)
            $counter += 1
            if ($counter -eq $chunk_size){
                break
            }
        }
        $DataTable | Export-Csv "output.csv" -NoTypeInformation -Append
    }catch{
        $ErrorMessage = $_.Exception.Message
        Write-Output $ErrorMessage
        $read=$FALSE
        $connection.Close()
        exit
    }
}
$connection.close()


1

มักจะsqlcmdมาพร้อมกับbcpยูทิลิตี้ (เป็นส่วนหนึ่งของmssql-tools) ซึ่งจะส่งออกเป็น CSV โดยค่าเริ่มต้น

การใช้งาน:

bcp {dbtable | query} {in | out | queryout | format} datafile

ตัวอย่างเช่น:

bcp.exe MyTable out data.csv

ในการถ่ายโอนตารางทั้งหมดเป็นไฟล์ CSV ที่เกี่ยวข้องนี่คือสคริปต์Bash :

#!/usr/bin/env bash
# Script to dump all tables from SQL Server into CSV files via bcp.
# @file: bcp-dump.sh
server="sql.example.com" # Change this.
user="USER" # Change this.
pass="PASS" # Change this.
dbname="DBNAME" # Change this.
creds="-S '$server' -U '$user' -P '$pass' -d '$dbname'"
sqlcmd $creds -Q 'SELECT * FROM sysobjects sobjects' > objects.lst
sqlcmd $creds -Q 'SELECT * FROM information_schema.routines' > routines.lst
sqlcmd $creds -Q 'sp_tables' | tail -n +3 | head -n -2 > sp_tables.lst
sqlcmd $creds -Q 'SELECT name FROM sysobjects sobjects WHERE xtype = "U"' | tail -n +3 | head -n -2 > tables.lst

for table in $(<tables.lst); do
  sqlcmd $creds -Q "exec sp_columns $table" > $table.desc && \
  bcp $table out $table.csv -S $server -U $user -P $pass -d $dbname -c
done

0

คำตอบข้างบนเกือบจะแก้ไขได้สำหรับฉัน แต่มันสร้าง CSV ที่แยกวิเคราะห์ไม่ถูกต้อง

นี่คือเวอร์ชันของฉัน:

sqlcmd -S myurl.com -d MyAzureDB -E -s, -W -i mytsql.sql | findstr /V /C:"-" /B > parsed_correctly.csv

มีคนบอกว่าsqlcmdล้าสมัยไปแล้วสำหรับทางเลือก PowerShell บางอย่างก็ลืมไปว่าไม่ได้sqlcmdมีไว้สำหรับ Windows เท่านั้น ฉันใช้ Linux (และเมื่อใช้ Windows ฉันก็หลีกเลี่ยง PS อยู่ดี)

พูดทั้งหมดนั้นฉันคิดว่าbcpง่ายกว่า


0

เนื่องจากทำตาม 2 เหตุผลคุณควรเรียกใช้โซลูชันของฉันใน CMD:

  1. อาจมีเครื่องหมายคำพูดคู่ในแบบสอบถาม
  2. ชื่อผู้ใช้และรหัสผ่านเข้าสู่ระบบบางครั้งจำเป็นในการสืบค้นอินสแตนซ์ SQL Server ระยะไกล

    sqlcmd -U [your_User]  -P[your_password] -S [your_remote_Server] -d [your_databasename]  -i "query.txt" -o "output.csv" -s"," -w 700
    

-2

คุณสามารถทำได้ด้วยวิธีแฮ็ก ระมัดระวังในการใช้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!")

ที่มา: การส่งออกการเขียน SQL เพื่อ CSV ด้วย VBScript


1
คำอธิบายสำหรับการโหวตลงคะแนนจะดี คำตอบของฉันถูกต้อง: คุณไม่สามารถทำได้ด้วย sqlcmd ฉันยังเสนอทางเลือกอื่นในการทำงานให้สำเร็จ
Sarel Botha

4
การโหวตลดลงเป็นเพราะคุณสามารถทำสิ่งที่ OP ขอด้วย sqlcmd ได้อย่างชัดเจน
Brian Driscoll

2
@BrianDriscoll เขาไม่ได้บอกว่าหนึ่งไม่สามารถทำมันได้ด้วยsqlcmdเราเป็นเพียงการระบุความจริงที่ว่าsqlcmdจะไม่ถูกต้องหลบหนีจุลภาคจึงเป็นแทบจะไม่สามารถใช้งานได้สำหรับการใด ๆที่ร้ายแรงเอาท์พุท CSV
Sebastian

ฉันพูดแบบนั้น แต่เบื่อกับการโหวตต่ำดังนั้นฉันจึงแก้ไขคำตอบของฉัน ฉันจะทำให้การแก้ไขของฉันเป็นจริงมากขึ้น
Sarel Botha
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.