2017-08-18 5 views
0

Ich möchte Daten aus SQL Server in eine neue Excel-Datei mit Powershell extrahieren. Für kleine Datensätze funktioniert mein Code, aber einige Tabellen haben mehr als 100.000 Zeilen und das wird ewig dauern. Der Grund, warum ich das Dienstprogramm in SQl-Server nicht verwende, ist, weil ich mehrere Tabellen extrahieren möchte. Gibt es eine Möglichkeit, mein Skript zu optimieren, um große Tabellen zu exportieren? Oder gibt es einen anderen Weg, dies zu tun?SQL extrahieren Daten nach Excel mit Powershell

ich das folgende Skript

## ---------- Working with SQL Server ---------- ## 

## - Get SQL Server Table data: 
$SQLServer = 'server'; 
$Database = 'database'; 
$SqlQuery = @' Select top 10 * from database.dbo.table '@; 

## - Connect to SQL Server using non-SMO class 'System.Data': 
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection; 
$SqlConnection.ConnectionString = ` 
"Server = $SQLServer; Database = $Database; Integrated Security = True"; 

$SqlCmd = New-Object System.Data.SqlClient.SqlCommand; 
$SqlCmd.CommandText = $SqlQuery; 
$SqlCmd.Connection = $SqlConnection; 

## - Extract and build the SQL data object '$DataSetTable': 
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter; 
$SqlAdapter.SelectCommand = $SqlCmd; 
$DataSet = New-Object System.Data.DataSet; 
$SqlAdapter.Fill($DataSet); 
$DataSetTable = $DataSet.Tables["Table"]; 


## ---------- Working with Excel ---------- ## 

## - Create an Excel Application instance: 
$xlsObj = New-Object -ComObject Excel.Application; 

## - Create new Workbook and Sheet (Visible = 1/0 not visible) 
$xlsObj.Visible = 0; 
$xlsWb = $xlsobj.Workbooks.Add(); 
$xlsSh = $xlsWb.Worksheets.item(1); 

## - Build the Excel column heading: 
[Array] $getColumnNames = $DataSetTable.Columns | Select ColumnName; 

## - Build column header: 
[Int] $RowHeader = 1; 
foreach ($ColH in $getColumnNames) 
{ 
$xlsSh.Cells.item(1, $RowHeader).font.bold = $true; 
$xlsSh.Cells.item(1, $RowHeader) = $ColH.ColumnName; 
$RowHeader++; 
}; 

## - Adding the data start in row 2 column 1: 
[Int] $rowData = 2; 
[Int] $colData = 1; 

foreach ($rec in $DataSetTable.Rows) 
{ 
foreach ($Coln in $getColumnNames) 
{ 
## - Next line convert cell to be text only: 
$xlsSh.Cells.NumberFormat = "@"; 

## - Populating columns: 
$xlsSh.Cells.Item($rowData, $colData) = ` 
$rec.$($Coln.ColumnName).ToString(); 
$ColData++; 
}; 
$rowData++; $ColData = 1; 
}; 

## - Adjusting columns in the Excel sheet: 
$xlsRng = $xlsSH.usedRange; 
$xlsRng.EntireColumn.AutoFit(); 

## ---------- Saving file and Terminating Excel Application ---------- ## 

## - Saving Excel file - if the file exist do delete then save 
$xlsFile = ` 
"C:\path\file.xls"; 

if (Test-Path $xlsFile) 
{ 
Remove-Item $xlsFile 
$xlsObj.ActiveWorkbook.SaveAs($xlsFile); 
} 
else 
{ 
$xlsObj.ActiveWorkbook.SaveAs($xlsFile); 
}; 

## Quit Excel and Terminate Excel Application process: 
$xlsObj.Quit(); (Get-Process Excel*) | foreach ($_) { $_.kill() }; 

## - End of Script - ## 
+0

Versuchen Sie einen Bereich im Speicher zu konstruieren und legen Sie es in das Excel-Objekt auf einmal, schreiben Zelle für Zelle ist sehr langsam. Mein Kommentar ist ein Ratschlag, vielleicht müssen Sie andere Dinge tunen, aber schreiben Sie nicht Zelle für Zelle. Hier ist ein hilfreicher Link, Code ist in .net, aber Sie könnten für Powershell anpassen [Write Array zu Excel] (https://stackoverflow.com/questions/536636/write-array-to-excel-range) –

+0

Meinst du? diesen Teil ersetzen? '## - Bestücken Spalten: $ xlsSh.Cells.Item ($ rowData, $ colData) =' ' $ rec $ ($ Coln.ColumnName) .ToString();. $ ColData ++; }; $ rowData ++; $ ColData = 1; }; ' – MBurger

Antwort

0

Es gibt einige einfache Magie dies viel einfacher machen mit, und das ist Kopieren/Einfügen. Sie können Ihre Datentabelle in eine tabulatorbegrenzte CSV-Datei konvertieren, in die Zwischenablage kopieren und in Excel einfügen. Ich werde deinen SQL-Teil ignorieren, da du das anscheinend gut in der Hand hast.

## ---------- Working with Excel ---------- ## 

## - Create an Excel Application instance: 
$xlsObj = New-Object -ComObject Excel.Application; 

## - Create new Workbook and Sheet (Visible = 1/0 not visible) 
$xlsObj.Visible = 0; 
$xlsWb = $xlsobj.Workbooks.Add(); 
$xlsSh = $xlsWb.Worksheets.item(1); 

## - Copy entire table to the clipboard as tab delimited CSV 
$DataSetTable | ConvertTo-Csv -NoType -Del "`t" | Clip 

## - Paste table to Excel 
$xlsObj.ActiveCell.PasteSpecial() | Out-Null 

## - Set columns to auto-fit width 
$xlsObj.ActiveSheet.UsedRange.Columns|%{$_.AutoFit()|Out-Null} 
Verwandte Themen