Mit PowerShell können Sie das Problem sauber lösen, indem Sie Invoke-Sqlcmd in Export-Csv leiten.
#Requires -Module SqlServer
Invoke-Sqlcmd -Query "SELECT * FROM DimDate;" `
-Database AdventureWorksDW2012 `
-Server localhost |
Export-Csv -NoTypeInformation `
-Path "DimDate.csv" `
-Encoding UTF8
SQL Server 2016 enthält das SqlServer- Modul, das das Invoke-SqlcmdCmdlet enthält , das Sie auch dann haben, wenn Sie nur SSMS 2016 installieren. Zuvor enthielt SQL Server 2012 das alte SQLPS- Modul , das das aktuelle Verzeichnis in SQLSERVER:\den Stand des Moduls ändern würde zuerst verwendet (unter anderen Fehlern), daher müssen Sie die #Requiresobige Zeile ändern in:
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
Um das Beispiel für SQL Server 2008 und 2008 R2 anzupassen, entfernen Sie die #RequiresZeile vollständig und verwenden Sie das Dienstprogramm sqlps.exe anstelle des Standard-PowerShell-Hosts.
Invoke-Sqlcmd ist das PowerShell-Äquivalent von sqlcmd.exe. Anstelle von Text werden System.Data.DataRow- Objekte ausgegeben .
Der -QueryParameter funktioniert wie der -QParameter von sqlcmd.exe. Übergeben Sie eine SQL-Abfrage, die die Daten beschreibt, die Sie exportieren möchten.
Der -DatabaseParameter funktioniert wie der -dParameter von sqlcmd.exe. Übergeben Sie ihm den Namen der Datenbank, die die zu exportierenden Daten enthält.
Der -ServerParameter funktioniert wie der -SParameter von sqlcmd.exe. Übergeben Sie ihm den Namen des Servers, der die zu exportierenden Daten enthält.
Export-CSV ist ein PowerShell-Cmdlet, das generische Objekte in CSV serialisiert. Es wird mit PowerShell geliefert.
Der -NoTypeInformationParameter unterdrückt zusätzliche Ausgaben, die nicht Teil des CSV-Formats sind. Standardmäßig schreibt das Cmdlet einen Header mit Typinformationen. Es informiert Sie über den Typ des Objekts, wenn Sie es später mit deserialisieren Import-Csv, verwirrt jedoch Tools, die eine Standard-CSV erwarten.
Der -PathParameter funktioniert wie der -oParameter von sqlcmd.exe. Ein vollständiger Pfad für diesen Wert ist am sichersten, wenn Sie das alte SQLPS- Modul nicht mehr verwenden können.
Der -EncodingParameter funktioniert wie die Parameter -foder -uvon sqlcmd.exe. Standardmäßig gibt Export-Csv nur ASCII-Zeichen aus und ersetzt alle anderen durch Fragezeichen. Verwenden Sie stattdessen UTF8, um alle Zeichen beizubehalten und mit den meisten anderen Tools kompatibel zu bleiben.
Der Hauptvorteil dieser Lösung gegenüber sqlcmd.exe oder bcp.exe besteht darin, dass Sie den Befehl nicht hacken müssen, um eine gültige CSV auszugeben. Das Cmdlet Export-Csv erledigt alles für Sie.
Der Hauptnachteil besteht darin, dass Invoke-Sqlcmddie gesamte Ergebnismenge gelesen wird, bevor sie entlang der Pipeline geleitet wird. Stellen Sie sicher, dass Sie über genügend Speicher für die gesamte Ergebnismenge verfügen, die Sie exportieren möchten.
Es funktioniert möglicherweise nicht reibungslos für Milliarden von Zeilen. Wenn das ein Problem ist, können Sie die anderen Tools versuchen oder eine eigene effiziente Version rollen von Invoke-Sqlcmdmit System.Data.SqlClient.SqlDataReader Klasse.