내가 SQL에 1백60기가바이트 CSV 파일을로드하려고하고 내가 Github에서 가져온 PowerShell 스크립트를 사용하고 내가오류 : 입력 배열이 테이블 PowerShell을 열 수보다 긴
IException calling "Add" with "1" argument(s): "Input array is longer than the number of columns in this table."
At C:\b.ps1:54 char:26
+ [void]$datatable.Rows.Add <<<< ($line.Split($delimiter))
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
그래서이 오류를 얻을 작은 3 줄 csv와 동일한 코드를 검사하고 모든 열이 일치하고 첫 번째 행에 헤더가 있고 왜이 오류가 발생하는지 확실하지 않은 여분의 구분 기호가 없습니다.
코드는 160 기가 바이트의 입력 파일로 작업
<# 8-faster-runspaces.ps1 #>
# Set CSV attributes
$csv = "M:\d\s.txt"
$delimiter = "`t"
# Set connstring
$connstring = "Data Source=.;Integrated Security=true;Initial Catalog=PresentationOptimized;PACKET SIZE=32767;"
# Set batchsize to 2000
$batchsize = 2000
# Create the datatable
$datatable = New-Object System.Data.DataTable
# Add generic columns
$columns = (Get-Content $csv -First 1).Split($delimiter)
foreach ($column in $columns) {
[void]$datatable.Columns.Add()
}
# Setup runspace pool and the scriptblock that runs inside each runspace
$pool = [RunspaceFactory]::CreateRunspacePool(1,5)
$pool.ApartmentState = "MTA"
$pool.Open()
$runspaces = @()
# Setup scriptblock. This is the workhorse. Think of it as a function.
$scriptblock = {
Param (
[string]$connstring,
[object]$dtbatch,
[int]$batchsize
)
$bulkcopy = New-Object Data.SqlClient.SqlBulkCopy($connstring,"TableLock")
$bulkcopy.DestinationTableName = "abc"
$bulkcopy.BatchSize = $batchsize
$bulkcopy.WriteToServer($dtbatch)
$bulkcopy.Close()
$dtbatch.Clear()
$bulkcopy.Dispose()
$dtbatch.Dispose()
}
# Start timer
$time = [System.Diagnostics.Stopwatch]::StartNew()
# Open the text file from disk and process.
$reader = New-Object System.IO.StreamReader($csv)
Write-Output "Starting insert.."
while ((($line = $reader.ReadLine()) -ne $null))
{
[void]$datatable.Rows.Add($line.Split($delimiter))
if ($datatable.rows.count % $batchsize -eq 0)
{
$runspace = [PowerShell]::Create()
[void]$runspace.AddScript($scriptblock)
[void]$runspace.AddArgument($connstring)
[void]$runspace.AddArgument($datatable) # <-- Send datatable
[void]$runspace.AddArgument($batchsize)
$runspace.RunspacePool = $pool
$runspaces += [PSCustomObject]@{ Pipe = $runspace; Status = $runspace.BeginInvoke() }
# Overwrite object with a shell of itself
$datatable = $datatable.Clone() # <-- Create new datatable object
}
}
# Close the file
$reader.Close()
# Wait for runspaces to complete
while ($runspaces.Status.IsCompleted -notcontains $true) {}
# End timer
$secs = $time.Elapsed.TotalSeconds
# Cleanup runspaces
foreach ($runspace in $runspaces) {
[void]$runspace.Pipe.EndInvoke($runspace.Status) # EndInvoke method retrieves the results of the asynchronous call
$runspace.Pipe.Dispose()
}
# Cleanup runspace pool
$pool.Close()
$pool.Dispose()
# Cleanup SQL Connections
[System.Data.SqlClient.SqlConnection]::ClearAllPools()
# Done! Format output then display
$totalrows = 1000000
$rs = "{0:N0}" -f [int]($totalrows/$secs)
$rm = "{0:N0}" -f [int]($totalrows/$secs * 60)
$mill = "{0:N0}" -f $totalrows
Write-Output "$mill rows imported in $([math]::round($secs,2)) seconds ($rs rows/sec and $rm rows/min)"
이 경우 일반적으로이 오류는 일부 줄에 예기치 않은 포함 된 구분 기호 ... 탭이 있음을 나타냅니다. 조금 더러운 입력 데이터 일뿐입니다. 행을 읽은 다음 탭을 빈 문자열로 바꾸고 원래의 크기와 축소 된 크기를 비교하여 열이있는 행보다 많은 행을 볼 수 있습니다. 네 개의 열이있는 경우 행이 세 자로 줄어들 것으로 예상됩니다. –
@Laughing Vergil 답장을 보내 주셔서 감사합니다. 쉼표로 구분 된 파일에 대해 동일한 결과를 얻었으므로 같은 오류가 발생합니다. – Zack
일부 데이터의 줄 종결자가 문제가 발생할 수 있습니다 - Windows 스타일의 텍스트 파일 중간에 UNIX 스타일의 줄 바꿈이있는 경우 하나의 데이터 검색 작업에서 두 행으로 끝납니다. 삽입 된 줄 바꿈 또는 CR/LF 쌍은 처리를 망칠 수도 있습니다. –