简体   繁体   English

PowerShell - Invoke-Sqlcmd 结果到 Export-Csv 设置批处理行限制

[英]PowerShell - Invoke-Sqlcmd results to Export-Csv set batch row limit

I'm exporting about 1,000,000 rows via an Invoke-Sqlcmd script and it exports into a csv around 180MB.我正在通过Invoke-Sqlcmd脚本导出大约 1,000,000 行,并将其导出到大约 180MB 的 csv 中。

What I would like to do is be able to export it instead into 10 100,000 row files.我想做的是能够将它导出到 10 100,000 行文件中。 How do I go about doing this as it doesn't seem to be a feature in Export-Csv or Invoke-Sqlcmd that I can find.我如何 go 关于这样做,因为它似乎不是我可以找到的Export-CsvInvoke-Sqlcmd中的功能。

Current code:当前代码:

$dataSubset = "mydata"
$localFile = ("{0}.csv" -f $dataSubset)
$localPath = "my\path"
$serverInstance = "myserver.domain.com"
$database = "mydatabase"

$Query = @"
my crazy ass query
"@
$Results = Invoke-Sqlcmd -QueryTimeout 0 -ServerInstance $ServerInstance -Database $database -Query $Query
$Results | Export-csv $localPath/$localFile -NoTypeInformation

Instead of having a single mydata.csv I want to have mydata_1.csv , mydata_2.csv , etc.我不想拥有一个mydata.csv我想要mydata_1.csvmydata_2.csv等。

Use the Select-Object cmdlet (whose built-in alias is select ), it has -Skip and -First parameters:使用Select-Object cmdlet(其内置别名为select ),它具有-Skip-First参数:

for ($i=0; $i -lt 10; $i++) {
    $localFile = ("{0}_{1}.csv" -f $dataSubset, $i)
    $Results | Select -Skip ($i * 100000) -First 100000 | Export-Csv $localPath/$localFile -NoTypeInformation
}

Unfortunately, as of PowerShell 7.0, there is no batching (chunking) mechanism in PowerShell.不幸的是,从 PowerShell 7.0 开始,PowerShell 中没有批处理(分块)机制。

  • This GitHub issue suggests adding a -ReadCount parameter to Select-Object to enable batching.此 GitHub 问题建议将-ReadCount参数添加到Select-Object以启用批处理。

For now, you'll have to implement your own:现在,您必须实现自己的:

# ... 

$batchSize = 10000
$fileNdx = 0

# The list to hold a batch.
$batch = [Collections.Generic.List[object]]::new($batchSize)

# The script block for exporting a single batch to a CSV.
# Exports to .../mydata_1.csv, .../mydata_2.csv, ... 
$sb = { 
        ++$fileNdx; 
        $batch | Export-Csv -NoTypeInformation "$localPath/mydata_$fileNdx.csv" 
      }

Invoke-Sqlcmd -QueryTimeout 0 -ServerInstance $ServerInstance -Database $database -Query $Query |
  ForEach-Object -Process {
    $batch.Add($_) # add object to current batch
    if ($batch.Count -eq $batchSize) { # batch is complete
      . $sb # export
      $batch.Clear() # start new batch
    }
  } -End { 
    if ($batch.Count) { # final, incomplete batch
      . $sb # export
    }
  }

Note that you should generally avoid $Results = Invoke-Sqlcmd... with large queries, because it invariably collects the entire result set in memory as a whole - instead, use the pipeline , with its object-by-object processing, as shown above.请注意,您通常应避免使用大型查询$Results = Invoke-Sqlcmd... ,因为它总是将 memory 中的整个结果集作为一个整体收集 - 相反,请使用pipeline及其逐个对象处理,如图所示以上。
That said, if you have enough memory, capturing all input at once can situationally improve performance.也就是说,如果您有足够的 memory,一次捕获所有输入可以根据情况提高性能。

I dont think that powershell is the way to do this.我不认为 powershell 是这样做的方法。 Cant you export directy from the SQL Server via cmd integration?您不能通过 cmd 集成直接从 SQL 服务器导出吗?

Anyway, concerning your question, another Alterantive is:无论如何,关于你的问题,另一个选择是:

$length = $Results.length


$items = 10;
$stepwitch = [Math]::Ceiling($length / $items)

for($i=1;$i -le $items; $i++) {
$firstItem = ($i - 1) * $stepwitch 
$lastItem = ($i * $stepwitch) - 1
if ($lastItem -gt $length) {$lastItem = $length}
echo ("FI: " + $firstItem + " LI:"  + $lastItem)
$localFile = ("{($i)}.csv" -f $dataSubset)
$Results[$firstItem..$lastItem] | Export-csv $localPath/$localFile -NoTypeInformation
}

(not tested, but at the end similiar to Mark Arends solution) (未经测试,但最后类似于 Mark Arends 解决方案)

Another alterantive would maybe to use the .net method system.array.copy https://docs.microsoft.com/de-de/dotnet/api/system.array.copy?view=netcore-3.1另一种选择可能是使用 .net 方法 system.array.copy https://docs.microsoft.com/de-de/dotnet/api/system.array.copy?view=netcore-3.1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM