Powershell / SQL Server / Import-CSV

时间:2015-10-15 10:35:10

标签: sql-server powershell csv

使用另一个脚本进行工作,我试图从只包含一列数据的CSV中读取。然后在查询SQL数据库时为每个项找到相应的ID。然后将结果(ID1,CSVID1)放入excel文件中(我的这部分工作正常)。

现在我遇到了关于如何在foreach循环中填充数据集的问题。

$excelAssets = Import-Csv .\test.csv -Header assetId | Foreach-Object {
    $assetId = $_.assetId
    # SQL Query Variables
    $query = "SELECT AssetId AS AssetID, BrandId AS BrandID FROM [AssetLibrary_BrandAsset] WHERE AssetId = $assetId"

    $connection = New-SqlConnection -Server $dataSource -Database $dataBase

    #Execute the SQL commands and place the results in dataset
    if ($connection.State -eq 'Open')
    {   
        $swLap = Start-Elapsed $sw "Executing SQL Query"
        Write-Verbose "$query";
        $dataSet += Invoke-SQLQuery -connection $connection -query $query -ExecutionTimeout '0'
        $i++
        $connection.Close();
        End-Elapsed $sw $swLap    
    } ELSE {
        Write-Error "$($(Format-Elapsed $swLap)) SQL Connection Not Open - Exiting...";
        exit;
    }
}

现在$dataSet +=不起作用,我已经多次搜索,试图找到这个问题的答案。任何帮助表示赞赏。

使用$dataSet

$dataTable = new-object "System.Data.DataTable" "Results"
$dataTable = $dataSet.Tables[0]

$rowDT = $dataTable.Rows.Count;
$colDT = $dataTable.Columns.Count;
Write-Host -NoNewLine "$(Format-Elapsed $sw.Elapsed) Rows: ";
Write-Host -NoNewLine "$($rowDT+1)" -ForegroundColor "Green";
Write-Host -NoNewLine " Columns: "
Write-Host -NoNewLine "$($colDT+1)" -ForegroundColor "Green";
Write-Host -NoNewLine " Cells: "
Write-Host "$( ($colDT+1)*($rowDT+1) )" -ForegroundColor "Green";


#Create a 2D Array of the DataTable
# http://stackoverflow.com/questions/13184191/fastest-way-to-drop-a-dataset-into-a-worksheet
$tableArray = New-Object 'object[,]' $rowDT, $colDT;
$swLap = Start-Elapsed $sw "DataTable transformation"
# i = row and j = column
for ($i=0;$i -lt $rowDT; $i++) 
{
    #Write-Progress -Activity "Transforming DataTable" -status "Row $i" -percentComplete ($i / $rowDT*100)
    for ($j=0;$j -lt $colDT; $j++) 
    {
        $tableArray[$i,$j] = $dataTable.Rows[$i].Item($j).ToString();
    }    
}

End-Elapsed $sw $swLap 

$rowOffset = 1; $colOffset = 1;# 1,1 = "A1"

# Write out the header column names
for ($j=0;$j -lt $colDT; $j++) 
{
    $ActiveWorksheet.cells.item($rowOffset, $j+1) = $dataTable.Columns[$j].ColumnName;
}
$headerRange = $ActiveWorksheet.Range($ActiveWorksheet.cells.item($rowOffset, $colOffset), $ActiveWorksheet.cells.item($rowOffset, $colDT+$colOffset-1)); 
$headerRange.Font.Bold = $false
$headerRange.Interior.Color = $headingColour
$headerRange.Font.Name = $headingFont
$headerRange.Font.Color = $headingFontColour

$rowOffset++;

# Extract the data to Excel
$tableRange = $ActiveWorksheet.Range($ActiveWorksheet.cells.item($rowOffset, $colOffset), $ActiveWorksheet.cells.item($rowDT+$rowOffset-1, $colDT+$colOffset-1));
$tableRange.Cells.Value2 = $tableArray;

# Resize the columns in Excel
$swLap = Start-Elapsed $sw "Resize Excel Worksheet"
$wholeRange = $ActiveWorksheet.UsedRange
$wholeRange.EntireColumn.AutoFit() | Out-Null
End-Elapsed $sw $swLap 

# Save Excel workbook
$ActiveWorkbook.SaveAs("$OutputFile") 
$ActiveWorkbook.Close() 

1 个答案:

答案 0 :(得分:1)

第一次分配到ActiveRecord::RecordInvalid (Validation failed: Phone can't be blank): 后,它的类型可能是不是数组,这意味着$dataSet运算符的行为与你期待。

您可以在开始分配之前将+=初始化为空数组:

$dataSet

或者您可以在分配期间投射它:

Import-Csv .\test.csv -Header assetId | Foreach-Object -Begin {$dataSet = @()} -Process {
    # rest of script in here
} -End {return $dataSet}

最后,另一种解决方案是确保将[array]$dataSet += Invoke-SQLQuery -connection $connection -query $query -ExecutionTimeout '0' 的输出视为数组,然后再将其分配给Invoke-SQLQuery

$dataSet

适合您的编码风格。