views:

27

answers:

1

I've written a Powershell script which will compare two databases and come up with a list of objects in one of the databases to remove. I put those items (as a customized object with a name and schema) into an array.

In the next step of my script I iterate through the objects in the database and see if they match an object in my array. If I find a match then I go ahead and drop the object from my database. The problem that I ran into though, was that if I try to drop the object then the collection through which I'm iterating gets changed and I get an error message that the collection changed and IEnumerable won't work when that happens.

I tried to make a copy of collection, but I can't seem to stuff it into an array using the CopyTo method. Any suggestions?

My current code is below. When I run this the array $sprocs is empty.

Thanks!

function DropSQLObjects
{
 param([object]$database, [object]$objectsToDrop)

 $sprocs = @()
 $database.StoredProcedures.CopyTo($sprocs, 0)

 # If I do a $sprocs | out-host I see that the array is still empty

 foreach ($objectToDrop in $objectsToDrop)
 {
  foreach ($sproc in $sprocs)
  {
   if ($sproc.Name -eq $objectToDrop.Name -and $sproc.Schema -eq $objectToDrop.Schema)
   {
    $sproc.Drop()
    LogToSQL $database "Dropped Stored Procedure: $($objectToDrop.Schema).$($objectToDrop.Name)"
   }
  }
 }
}
A: 

I'm adding this as an answer in case anyone else has need of this in the future. It turns out that I was really making things harder than they needed to be. Since I was using Powershell, the "where" function was better than iterating through the stored procedures.

Here's the code which solved my issue:

function DropSQLObjects
{
    param([object]$database, [object]$objectsToDrop)

    foreach ($objectToDrop in $objectsToDrop)
    {
        if ($database.StoredProcedures.Contains($objectToDrop.Name, $objectToDrop.Schema))
        {
            $sproc = $database.StoredProcedures | where {$_.Schema -eq $objectToDrop.Schema -and $_.Name -eq $objectToDrop.Name}
            $sproc.Drop()
            LogToSQL $database "Dropped Stored Procedure: $($objectToDrop.Schema).$($objectToDrop.Name)"
        }
    }
}

In actuality, I also have code to go against UserDefinedFunctions, but the code is mostly a cut-and-paste from the StoredProcedures portion.

Tom H.