0

I have a PowerShell script which runs safely up to the point of an update. I connect to the database and can read from it, however, I have trouble updating.

Here is a copy of the error message I receive: "Exception calling "ExecuteNonQuery" with "0" argument(s): "There is already an open DataReader associated with this Command which must be closed first." At C:\xxx\xxx\ToolsController.ps1:37 char:5 + $InnerCommand.ExecuteNonQuery() + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : InvalidOperationException"

FYI: I posted this before and this is an update to the previous question. Any help at all would be greatly appreciated.

I have tried attaching the variable at the end of the string i.e '..+$varibale' also tried @" "@ and I have gotten the same result.

$Global:Server = "server"      
$Global:Database = "db"
$Global:u = "un"
$Global:p = "pw"
[string]$Query = "SELECT * FROM [dbo].[jobs] WHERE [Run] = 0"
try{
$ConnectionString = "server=$Server;Integrated Security=true;database=$Database;user id=$u;password=$p"
$Connection = New-Object System.Data.SqlClient.SqlConnection
$Connection.ConnectionString = $ConnectionString
$Connection.Open()
}
catch{
    "Failed to connect SQL Server"     
}

$Command = $Connection.CreateCommand()
$InnerCommand = $Connection.CreateCommand()
$Command.CommandText = $Query
$jobs = $Command.ExecuteReader()

    while ($jobs.Read()){

        switch($jobs["Script"]){                
            15
            {
                $traverse = $jobs["Frequency"] - 1
                While ($traverse -ge 0) {
                    c:\xx\xx\batch $jobs["Date"]
                    $traverse--
                }

                "Updating Database...."
                $Query2 = "UPDATE [dbo].jobs SET [Run] = 1 WHERE [ID] = $jobs['ID']" <------Error here.
                $InnerCommand.CommandText = $Query2
                $InnerCommand.ExecuteNonQuery()
                "Updating Completed!"
            }
        }
    }
$Connection.Close()
$Connection.Dispose()
Write-Host "Connection Closed"
3
  • Maybe just try simplifying by using Invoke-Sqlcmd and its parameters. Commented Jul 2, 2019 at 15:16
  • The message is clear: while you're reading from the DataReader, you cannot perform commands on the same connection. Read all the jobs into a collection first, then do a second loop where you perform the actual actions and update the jobs. Alternatively, you can open a second connection to do the UPDATE on, but this makes your processing far less efficient as you're holding the first connection open while you're doing something that could take a very long time (potentially longer than timeouts). Commented Jul 2, 2019 at 15:17
  • 1
    If I can toot my own horn for a moment, this answer has some code for conveniently reading objects from a DataReader (even more so than Invoke-Sqlcmd, which borrows all the weirdness of sqlcmd). Commented Jul 2, 2019 at 15:17

1 Answer 1

2

Add MultipleActiveResultSets=True to the connection string. This will allow interleaving of UPDATE statements while reading from the data reader.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.