Update-SQL.ps1
function Update-Sql { <# .Synopsis Updates a SQL table .Description Inserts new content into a SQL table, or updates the existing contents of a SQL table .Example Get-Counter | Select-Object -ExpandProperty CounterSamples | Update-Sql -TableName Perfcounters -Force -ConnectionStringOrSetting (Get-SecureSetting SqlAzureConnectionString -ValueOnly) .Example Get-Counter | Select-Object -ExpandProperty CounterSamples | Update-Sql -TableName Perfcounters -Force -ConnectionStringOrSetting (Get-SecureSetting SqlAzureConnectionString -ValueOnly) -Parallel .Link Select-Sql .Link Remove-Sql #> [OutputType([Nullable])] param( # The name of the SQL table [Parameter(Mandatory=$true)] [string]$TableName, # The Input Object [Parameter(Mandatory=$true, ValueFromPipeline=$true)] [PSObject] $InputObject, # A List of Properties to add to the database. If omitted, all properties will be added (except those excluded with -ExcludeProperty) [string[]] $Property, # A List of Properties to exclude from the database. If omitted, all properties (or the properties specified with the -Property parameter) will be added [string[]] $ExcludeProperty, # The rowkey of the input object [Parameter(ValueFromPipelineByPropertyName=$true)] [string] $RowKey, # The property of the input object to use as a row [string] $RowProperty, # The type of key to use for the SQL table. [ValidateSet('Guid', 'Hex', 'SmallHex', 'Sequential', 'Named', 'Parameter')] [string]$KeyType = 'Guid', # A lookup table containing SQL data types [Hashtable[]] $ColumnType, # A lookup table containing the real SQL column names for an object [Hashtable[]] $ColumnAlias, # If set, will force the creation of a table. # If omitted, an error will be thrown if the table does not exist. [Switch] $Force, # The connection string or a setting containing the connection string. [String] $ConnectionStringOrSetting, # If set, will output SQL. Be aware that this will only output insert statements, not update statements [Switch] $OutputSql, # If set, will use SQL server compact edition [Switch] $UseSQLCompact, # The path to SQL Compact. If not provided, SQL compact will be loaded from the GAC [string] $SqlCompactPath, # If set, will use SQL lite [Alias('UseSqlLite')] [switch] $UseSQLite, # The path to SQLite. If not provided, SQLite will be loaded from Program Files [Alias('SqlLitePath')] [string] $SqlitePath, # If set, will use MySql to connect to the database [Switch] $UseMySql, # The path to MySql's .NET connector. If not provided, MySql will be loaded from Program Files [string] $MySqlPath, # The path to a SQL compact or SQL lite database [Alias('DBPath')] [string] $DatabasePath, # If set, will skip table creation column checks [Switch] $DoNotCheckTable, # If set, will keep the connection open. [Switch] $KeepConnected, # Foreign keys in the table. [Hashtable] $ForeignKey = @{}, # The length of a string key. By default, 100 [Uint32] $StringKeyLength = 100, # If set, will run Update-SQL in parallel [Switch] $Parallel, # If set, will hide the progress [Switch] $HideProgress, # If set, will output the original object. [switch] $Passthru ) begin { $sqlParams = @{} + $psboundparameters foreach ($k in @($sqlParams.Keys)) { if ('SqlCompactPath', 'UseSqlCompact', 'SqlitePath', 'UseSqlite', 'UseMySql', 'MySqlPath', 'DatabasePath', 'ConnectionStringOrSetting' -notcontains $k) { $sqlParams.Remove($k) } } $params = @{} + $psboundparameters #region Get Connection String if ($PSBoundParameters.ConnectionStringOrSetting) { if ($ConnectionStringOrSetting -notlike "*;*") { $ConnectionString = Get-SecureSetting -Name $ConnectionStringOrSetting -ValueOnly } else { $ConnectionString = $ConnectionStringOrSetting } $script:CachedConnectionString = $ConnectionString } elseif ($script:CachedConnectionString){ $ConnectionString = $script:CachedConnectionString } else { $ConnectionString = "" } if (-not $ConnectionString -and -not ($UseSQLite -or $UseSQLCompact)) { throw "No Connection String" return } #endregion Get Connection String #region Connect to SQL if (-not $OutputSQL) { if ($script:CachedConnection -and $script:CachedConnection.State -eq 'Open') { $sqlConnection = $script:CachedConnection } elseif ($UseSQLCompact) { if (-not ('Data.SqlServerCE.SqlCeConnection' -as [type])) { if ($SqlCompactPath) { $resolvedCompactPath = $ExecutionContext.SessionState.Path.GetResolvedPSPathFromPSPath($SqlCompactPath) $asm = [reflection.assembly]::LoadFrom($resolvedCompactPath) } else { $asm = [reflection.assembly]::LoadWithPartialName("System.Data.SqlServerCe") } $null = $asm } $resolvedDatabasePath = $ExecutionContext.SessionState.Path.GetResolvedPSPathFromPSPath($DatabasePath) $sqlConnection = New-Object Data.SqlServerCE.SqlCeConnection "Data Source=$resolvedDatabasePath" $sqlConnection.Open() $script:CachedConnection = $sqlConnection } elseif ($UseSqlite) { if (-not ('Data.Sqlite.SqliteConnection' -as [type])) { if ($sqlitePath) { $resolvedLitePath = $ExecutionContext.SessionState.Path.GetResolvedPSPathFromPSPath($sqlitePath) $asm = [reflection.assembly]::LoadFrom($resolvedLitePath) } else { $asm = [Reflection.Assembly]::LoadFrom("$env:ProgramFiles\System.Data.SQLite\2010\bin\System.Data.SQLite.dll") } $null = $asm } $resolvedDbPath = $ExecutionContext.SessionState.Path.GetResolvedPSPathFromPSPath($DatabasePath) $sqlConnection = New-Object Data.Sqlite.SqliteConnection "Data Source=$resolvedDbPath" $sqlConnection.Open() $script:CachedConnection = $sqlConnection } elseif ($useMySql) { if (-not ('MySql.Data.MySqlClient.MySqlConnection' -as [type])) { if (-not $mySqlPath) { $programDir = if (${env:ProgramFiles(x86)}) { ${env:ProgramFiles(x86)} } else { ${env:ProgramFiles} } $mySqlPath = Get-ChildItem "$programDir\MySQL\Connector NET 6.7.4\Assemblies\"| Where-Object { $_.Name -like "*v*" } | Sort-Object { $_.Name.Replace("v", "") -as [Version] } -Descending | Select-object -First 1 | Get-ChildItem -filter "MySql.Data.dll" | Select-Object -ExpandProperty Fullname } $asm = [Reflection.Assembly]::LoadFrom($MySqlPath) $null = $asm } $sqlConnection = New-Object MySql.Data.MySqlClient.MySqlConnection "$ConnectionString" $sqlConnection.Open() } else { $sqlConnection = New-Object Data.SqlClient.SqlConnection "$connectionString" $sqlConnection.Open() $script:CachedConnection = $sqlConnection } } #endregion Connect to SQL $propertyMatches = @{} foreach ($p in $Property) { if ($p) { $propertyMatches.$p = $p } } $excludeMatches = @{} foreach ($p in $excludeMatches) { if ($p) { $excludeMatches.$p = $p } } #region Common Parameters & Procedures $GetPropertyNamesAndTypes = { param($object, [string[]]$PropertyList) $haspstypename = $false foreach ($prop in $object.psobject.properties) { if (-not $prop) { continue } if ($PropertyList -and $prop.Name -notcontains $PropertyList) { continue } if ($propertyMatches.Count -and -not $propertyMatches[$prop]) { continue } if ($ExcludeProperty.Count -and $ExcludeProperty -contains $prop.Name) { continue } # $prop.Name if ($prop.Name -eq 'RowError' -or $prop.Name -eq 'RowState' -or $prop.Name -eq 'Table' -or $prop.Name -eq 'ItemArray'-or $prop.Name -eq 'HasErrors') { continue } if ($prop.Name -eq 'pstypename') { $haspstypename = $true } $sqlType = if ($columnType -and $columnType[$prop.Name]) { $columnType[$prop.Name] } elseif ($prop.Value -ne $null) { if ($prop.Value -is [String]) { if ($UseSQLCompact) { "ntext" } elseif ($UseSQLite) { "text" } elseif ($useMySql) { "longtext" } else { "varchar(max)" } } elseif ($prop.Value -is [bool] -or $prop.Value -is [switch]) { "bit" } elseif ($Prop.Value -is [Double]) { "float" } elseif ($prop.Value -is [Long]) { "bigint" } elseif ($prop.Value -is [DateTime]) { "datetime" } elseif ($prop.Value -is [Byte]) { "tinyint" } elseif ($prop.Value -is [Int16]) { "smallint" } elseif ($prop.Value -is [Int]) { "int" } elseif ($prop.Value -is [char]) { "char(1)" } elseif ($prop.Value -is [BigInt]) { "BIGINT" } else { if ($UseSQLCompact) { "ntext" } elseif ($UseSQLite) { "text" } elseif ($UseMySql) { "longtext" } else { "varchar(max)" } } } else { if ($UseSQLCompact) { "ntext" } elseif ($UseSQLite) { "text" } elseif ($UseMySql) { "longtext" } else { "varchar(max)" } } $columnName = if ($ColumnAlias -and $ColumnAlias[$prop.Name]) { $ColumnAlias[$prop.Name] } else { $prop.Name } New-Object PSObject -Property @{ Name=$columnName Value = if ($sqlType -eq 'bit') { if ($prop.Value) { 1 } else { 0 } } elseif ($sqlType -eq 'datetime') { if ($useMySql) { ($prop.Value -as [datetime]).ToString([Globalization.CultureInfo]::InvariantCulture.DateTimeFormat.SortableDateTimePattern) } else { $prop.Value } } else { ($prop.Value -as [string]).Replace("'", "''") } SqlType = $sqlType } } if ($haspstypename -or ($PropertyList -and $propertyList -notcontains 'pstypename') -or ($object.pstypenames[0] -like "*.PSCustomObject" -or $object.pstypenames[0] -like "*Selected.*")) { } else { New-Object PSObject -Property @{ Name="pstypename" Value = $object.pstypenames -join '|' SqlType = if ($UseSQLCompact) { "ntext" } elseif ($UseSQLite) { "text" } elseif ($useMySql) { "longtext" } else { "varchar(max)" } } } } #endregion Common Parameters & Procedures if (-not $DoNotCheckTable) { $columnsInfo = Get-SqlTable -TableName $TableName @sqlParams if (-not $columnsInfo) { # Table Doesn't Exist Yet, mark it for creation if (-not $Force) { Write-Error "$tableName does not exist" } } $Local:DoNotRetry = $false } $AccumulatedInput = New-Object Collections.ArrayList } process { # If there are no columns, and -Force is not set if (-not $columnsInfo -and -not $force) { return } $params = @{} + $psboundparameters $null = $AccumulatedInput.Add($params) #endregion Attempt SQL Insert } end { $total= $AccumulatedInput.Count $counter =0 $progressId = Get-Random if ($Parallel -and $AccumulatedInput.Count -gt 9) { $first, $rest = @($AccumulatedInput) $first.Remove("Parallel") $first.HideProgress = $true Update-Sql @first foreach ($in in $rest) { $in.Remove("Parallel") $in.Passthru = $true $in.HideProgress = $true } $sb = [ScriptBlock]::Create(" `$m = New-Module -Name Pipeworks { function Update-SQL { $((Get-Command Update-SQL).Definition) } function Select-SQL { $((Get-Command Select-SQL).Definition) } function Get-SQLTable { $((Get-Command Get-SqlTable).Definition) } function Add-SQLTable { $((Get-Command Add-SqlTable).Definition) } function Get-SecureSetting{ $((Get-Command Get-SecureSetting).Definition) } } `$generalParameters = @{} + `$args[0] `$generalParameters.Remove('InputObject') `$inputObjects = foreach (`$a in `$args) { `$a.InputObject } `$inputObjects | Update-SQL @generalParameters ") $total = $AccumulatedInput.Count $counter = 1 Invoke-Parallel -InputObject $rest -Command $sb | ForEach-Object { if ($_ -isnot [Management.Automation.ErrorRecord]) { $counter++ $perc = $counter * 100 / $total if (-not $hideProgress) { Write-Progress -Id $progressId -PercentComplete $perc "Updating $TableName" "$counter of $total" } } else { $_ | Write-Error } } -End { if (-not $hideProgress) { Write-Progress -Id $progressId -Completed "Updating $TableName" "$counter of $total" } } return } foreach ($in in $AccumulatedInput) { $counter++ $perc = $counter * 100 / $total if (-not $HideProgress) { Write-Progress "Updating $TableName" "$counter of $total" -PercentComplete $perc -Id $progressId } foreach ($kv in $in.GetEnumerator()) { Set-Variable -Name $kv.Key -Value $kv.Value } $objectSqlInfo = & $GetPropertyNamesAndTypes $inputObject # There are no columns, create the table if (-not $columnsInfo -and (-not $Local:DoNotRetry) -and -not $DoNotCheckTable) { $extraSqlParams = @{StringKeyLength = $StringKeyLength} if ($ForeignKey -and $ForeignKey.Count) { $extraSqlParams["ForeignKey"] = $ForeignKey } if ($RowProperty) { Add-SqlTable -KeyType $keyType -TableName $TableName -Column ( $objectSqlInfo | Where-Object { $_.Name -ne $RowProperty } | Select-Object -ExpandProperty Name ) -DataType ( $objectSqlInfo | Where-Object { $_.Name -ne $RowProperty } | Select-Object -ExpandProperty SqlType ) @sqlParams -RowKey $RowProperty @extraSqlParams } else { Add-SqlTable -KeyType $keyType -TableName $TableName -Column ( $objectSqlInfo | Where-Object { $_.Name -ne 'RowKey' } | Select-Object -ExpandProperty Name ) -DataType ( $objectSqlInfo | Where-Object { $_.Name -ne 'RowKey' } | Select-Object -ExpandProperty SqlType ) @sqlParams @extraSqlParams } if (-not $DoNotCheckTable) { $columnsInfo = Get-SQLTable -TableName $TableName @sqlParams } } # If there's still no columns info the table could not be created, and we should bounce if (-not $columnsInfo -and -not $DoNotCheckTable) { $Local:DoNotRetry = $true return } $updated = $false # It's quicker, and involves less simultaneous connections, to attempt an insert before attempting an update #region Attempt SQL Insert $row = if ($psBoundParameters.RowKey -and -not $updated) { $psBoundParameters.RowKey } elseif ($psBoundParameters.RowProperty -and $inputObject.$rowProperty) { $inputObject.$rowProperty } elseif ($KeyType -eq 'GUID') { [GUID]::NewGuid() } elseif ($KeyType -eq 'Hex') { "{0:x}" -f (Get-Random) } elseif ($KeyType -eq 'SmallHex') { "{0:x}" -f ([int](Get-Random -Maximum 512kb)) } elseif ($KeyType -eq 'Sequential') { # Seqential keys should be handled by SQL #if ($row -ne $null -and $row -as [Uint32]) { # $row + 1 #} else { #Select-SQL -FromTable $TableName -Property "COUNT(*)" @sqlParams | # Select-Object -ExpandProperty Column1 #} } $insertColumns = @($objectSqlInfo | Where-Object { $_.Name -ne 'RowKey'} | Where-Object { if ($RowProperty) { $_.Name -ne $RowProperty } elseif ($_.Name -ne 'RowKey') { $_ } } | Select-Object -ExpandProperty Name) $insertData = @($objectSqlInfo | Where-Object { $insertColumns -contains $_.Name } | Foreach-Object { $_.Value }) $isUpdate = $false $insertNames = if ($UseMySql) { $insertColumns -join ", " } else { $insertColumns -join "`", `"" } $insertInfo= $insertData -join "', '" if ($params.RowKey ) { $sqlInsert = if ($UseMySql) { "INSERT INTO $TABLEName (RowKey, $insertNames) VALUES ('$Row','$insertInfo')" } else { "INSERT INTO $TABLEName (`"RowKey`", `"$insertNames`") VALUES ('$Row','$insertInfo')" } } else { $rowKeyInfo = if ($KeyType -ne 'Sequential' -and $row) { if ($UseMySql) { if ($RowProperty) { "$rowProperty," } else { "RowKey," } } else { if ($RowProperty) { "`"$rowProperty`"," } else { "`"RowKey`"," } } } if ($keyType -eq 'Sequential') { if ($inputObject.$rowProperty -or $psboundparameters.RowKey) { $isUpdate = $true } } $rowKeyValue = if ($KeyType -ne 'Sequential' -and $row) { "'$Row'," } $sqlInsert = if ($UseMySql) { "INSERT INTO $TABLEName ($rowKeyInfo $insertNames) VALUES ($rowKeyValue '$( $insertInfo)')" } else { "INSERT INTO $TABLEName ($rowKeyInfo `"$insertNames`") VALUES ($rowKeyValue '$( $insertInfo)')" } } if (-not $isUpdate) { Write-Verbose $sqlInsert } $sqlStatement = $sqlInsert $shouldKeepTrying = $true do { try { $sqlStatement = $sqlInsert if ($outputSql) { $sqlStatement } elseif ($isupdate) { throw "It's an update" } elseif ($UseSQLCompact) { $sqlAdapter= New-Object "Data.SqlServerCE.SqlCeDataAdapter" ($sqlStatement, $sqlConnection) $dataSet = New-Object Data.DataSet $rowCount = $sqlAdapter.Fill($dataSet) } elseif ($UseSQLite) { $sqlAdapter= New-Object "Data.SQLite.SQLiteDataAdapter" ($sqlStatement, $sqlConnection) $dataSet = New-Object Data.DataSet $rowCount = $sqlAdapter.Fill($dataSet) $null = $rowCount } elseif ($UseMySql) { $sqlAdapter= New-Object "MySql.Data.MySqlClient.MySqlDataAdapter" ($sqlStatement, $sqlConnection) $sqlAdapter.SelectCommand.CommandTimeout = 0 $dataSet = New-Object Data.DataSet $rowCount = $sqlAdapter.Fill($dataSet) } else { $sqlAdapter= New-Object "Data.SqlClient.SqlDataAdapter" ($sqlStatement, $sqlConnection) $dataSet = New-Object Data.DataSet $rowCount = $sqlAdapter.Fill($dataSet) } $null = $rowCount $shouldKeepTrying = $false } catch { $insertError = $_ $null = $insertError if ($_.Exception.InnerException.Message -like "*invalid column name*" -or $_.Exception.InnerException.Message -like "*no column named*" -or $_.Exception.InnerException.Message -like "*column name is not valid*" -or $_.Exception.InnerException.Message -like "Unknown Column*") { $columnName = if ($_.Exception.InnerException.Message -like "*invalid*") { ($_.Exception.InnerException.Message -split "'")[1] } elseif ($_.Exception.InnerException.Message -like "*no column named*") { ($_.Exception.InnerException.Message -split " ")[-1] } elseif ($_.Exception.InnerException.Message -like "*column name is not valid*") { ($_.Exception.InnerException.Message -split "[ =\]]" -ne '')[-1] } elseif ($_.Exception.InnerException.Message -like "Unknown column*") { ($_.Exception.InnerException.Message -split "'" -ne '')[1] } $columnInfo = & $GetPropertyNamesAndTypes $inputObject -propertyList $columnName $sqlAlter= "ALTER TABLE $TableName ADD $ColumnName $($columnInfo.SqlType)" $sqlStatement = $sqlAlter try { if ($UseSQLCompact) { $sqlAdapter= New-Object "Data.SqlServerCE.SqlCeDataAdapter" ($sqlStatement, $sqlConnection) $sqlAdapter.SelectCommand.CommandTimeout = 0 $dataSet = New-Object Data.DataSet $rowCount = $sqlAdapter.Fill($dataSet) } elseif ($UseSQLite) { $sqlAdapter= New-Object "Data.SQLite.SQLiteDataAdapter" ($sqlStatement, $sqlConnection) $sqlAdapter.SelectCommand.CommandTimeout = 0 $dataSet = New-Object Data.DataSet $rowCount = $sqlAdapter.Fill($dataSet) } elseif ($useMySql) { $sqlAdapter= New-Object "MySql.Data.MySqlClient.MySqlDataAdapter" ($sqlStatement, $sqlConnection) $sqlAdapter.SelectCommand.CommandTimeout = 0 $dataSet = New-Object Data.DataSet $rowCount = $sqlAdapter.Fill($dataSet) } else { $sqlAdapter= New-Object "Data.SqlClient.SqlDataAdapter" ($sqlStatement, $sqlConnection) $sqlAdapter.SelectCommand.CommandTimeout = 0 $dataSet = New-Object Data.DataSet $rowCount = $sqlAdapter.Fill($dataSet) } } catch { $shouldKeepTrying = $false Write-Error $_ Write-Debug $_ } } elseif ($_.Exception.HResult -eq '-2146233087' -or $_.Exception.Hresult -eq '-2146233087' -or $isUpdate) { # It's a duplicate, so update instead of create $sqlUpdate = "UPDATE $TABLEName SET " $sqlUpdate += ( ($objectSqlInfo | Where-Object { $insertColumns -contains $_.Name } | Foreach-Object { if ($UseMySql) { $_.Name + '=' + "'$($($_.Value))'" } else { '[' + $_.Name + ']=' + "'$($($_.Value))'" } }) -join ", ") $sqlupdate+= " WHERE " +$( if ($params.RowKey) { "RowKey='$RowKey'" } elseif ( $InputObject.$RowProperty) { "$RowProperty ='$($inputObject.$RowProperty)'" }) Write-Verbose $SqlUpdate $shouldKeepTrying = $true do { try { $sqlStatement = $sqlUpdate if ($outputSql) { $sqlStatement } elseif ($UseSQLCompact) { $sqlAdapter= New-Object "Data.SqlServerCE.SqlCeDataAdapter" ($sqlStatement, $sqlConnection) $dataSet = New-Object Data.DataSet $rowCount = $sqlAdapter.Fill($dataSet) } elseif ($UseSQLite) { $sqlAdapter= New-Object "Data.SQLite.SQLiteDataAdapter" ($sqlStatement, $sqlConnection) $dataSet = New-Object Data.DataSet $rowCount = $sqlAdapter.Fill($dataSet) } elseif ($UseMySql) { $sqlAdapter= New-Object "MySql.Data.MySqlClient.MySqlDataAdapter" ($sqlStatement, $sqlConnection) $sqlAdapter.SelectCommand.CommandTimeout = 0 $dataSet = New-Object Data.DataSet $rowCount = $sqlAdapter.Fill($dataSet) } else { $sqlAdapter= New-Object "Data.SqlClient.SqlDataAdapter" ($sqlStatement, $sqlConnection) $dataSet = New-Object Data.DataSet $rowCount = $sqlAdapter.Fill($dataSet) } $shouldKeepTrying = $false } catch { if ($_.Exception.InnerException.Message -like "*invalid column name*" -or $_.Exception.InnerException.Message -like "*no column named*" -or $_.Exception.InnerException.Message -like "*column name is not valid*") { $columnName = if ($_.Exception.InnerException.Message -like "*invalid*") { ($_.Exception.InnerException.Message -split "'")[1] } elseif ($_.Exception.InnerException.Message -like "*no column named*") { ($_.Exception.InnerException.Message -split " ")[-1] } elseif ($_.Exception.InnerException.Message -like "*column name is not valid*") { ($_.Exception.InnerException.Message -split "[ =\]]" -ne '')[-1] } $columnInfo = & $GetPropertyNamesAndTypes $inputObject -propertyList $columnName $sqlAlter= "ALTER TABLE $TableName ADD $ColumnName $($columnInfo.SqlType)" $sqlStatement = $sqlAlter try { if ($UseSQLCompact) { $sqlAdapter= New-Object "Data.SqlServerCE.SqlCeDataAdapter" ($sqlStatement, $sqlConnection) $sqlAdapter.SelectCommand.CommandTimeout = 0 $dataSet = New-Object Data.DataSet $rowCount = $sqlAdapter.Fill($dataSet) } elseif ($UseSQLite) { $sqlAdapter= New-Object "Data.SQLite.SQLiteDataAdapter" ($sqlStatement, $sqlConnection) $sqlAdapter.SelectCommand.CommandTimeout = 0 $dataSet = New-Object Data.DataSet $rowCount = $sqlAdapter.Fill($dataSet) } elseif ($UseMySql) { $sqlAdapter= New-Object "MySql.Data.MySqlClient.MySqlDataAdapter" ($sqlStatement, $sqlConnection) $sqlAdapter.SelectCommand.CommandTimeout = 0 $dataSet = New-Object Data.DataSet $rowCount = $sqlAdapter.Fill($dataSet) } else { $sqlAdapter= New-Object "Data.SqlClient.SqlDataAdapter" ($sqlStatement, $sqlConnection) $sqlAdapter.SelectCommand.CommandTimeout = 0 $dataSet = New-Object Data.DataSet $rowCount = $sqlAdapter.Fill($dataSet) } } catch { $shouldKeepTrying = $false Write-Error $_ Write-Debug $_ } } else { $shouldKeepTrying = $false Write-Debug $_ Write-Error $_ } } } while ($shouldKeepTrying) } else { $shouldKeepTrying = $false Write-Debug $_ Write-Error $_ } } } while ($shouldKeepTrying) if ($Passthru) { $InputObject } } if (-not $HideProgress) { Write-Progress "Updating $TableName" "Completed" -Completed -Id $progressId } if ($sqlConnection -and -not $keepConnected) { $sqlConnection.Close() $sqlConnection.Dispose() } } } |