I am trying to batch up rows from a large json doc, and insert them into SQL Server.
The following code works, but inserts 1 row at a time into the SQL Server table. I think this is actually every 1000th row.
add-type -path "C:\Program Files\WindowsPowerShell\Modules\newtonsoft.json\1.0.2.201\libs\newtonsoft.json.dll"
install-module sqlserver -AllowClobber
class EliteCoords {
[double] $x
[double] $y
[double] $z
}
class EliteSystem {
[int] $id
[long] $id64
[string] $name
[EliteCoords] $coords
[string] $date
}
$dt = New-Object system.data.datatable
$dt.Columns.Add("ID",[int])
$dt.Columns.Add("ID64",[long])
$dt.Columns.Add("Name",[string])
$dt.Columns.Add("Coordsx",[decimal])
$dt.Columns.Add("Coordsy",[decimal])
$dt.Columns.Add("Coordsz",[decimal])
$dt.Columns.Add("DiscoveryDate",[string])
$stream = (Get-Item c:\code\systemsWithCoordinates.json).OpenText()
$reader = [Newtonsoft.Json.JsonTextReader]::new($stream)
while ($reader.Read()) {
$cnt = 0
$dt.Clear()
while ($cnt -le 1000) {
$cnt = $cnt + 1
if ($reader.TokenType -eq 'StartObject') {
$row = [Newtonsoft.Json.JsonSerializer]::CreateDefault().Deserialize($reader, [EliteSystem])
$dr = $dt.NewRow()
$dr["ID"] = $row.id
$dr["ID64"] = $row.id64
$dr["Name"] = $row.name
$dr["Coordsx"] = $row.coords.x
$dr["Coordsy"] = $row.coords.y
$dr["Coordsz"] = $row.coords.z
$dr["DiscoveryDate"] = $row.date
$dt.Rows.Add($dr)
}
}
write-sqltabledata -ServerInstance ELITEDANGEROUS -Database EDSM -Schema Staging -Table SystemsWithCoordinates -InputData $dt
}
$stream.Close()
I know that the problem is because the if block is being skipped, for all but the first iteration of the inner while loop, because the token type is changing from StartObject to StartArray.
I tried putting an additional reader loop inside but of course, that reads the whole file.
I also tried just reading the array rather than object, but of course, that fails because of the nested json.
How should I structure the loops, so that I can batch up and process 1000 rows?