Массовая замена текста в объектах SQL Server

by Alexey Knyazev 27. сентября 2016 23:57

Если у вас возникнет потребность внести массовые изменения во все объекты БД (заменить одно значение на другое), то следующий скрипт сможет облегчить вам эту задачу. Кроме того, что он заменять указанный текст на новый, он ещё сохраняет на диск старую и новую версию файла, а это поможет вам в последствии легко заменить файлы в системе контроля версий, например, в TFS.
Скрипт написан на PowerShell и в текущей реализации работает с процедурами, функциями, триггерами и представлениями, но может быть легко дополнен. Для выгрузки скриптов в файлы используются два параметра: $backupFolder и $changeFolder. Кроме того, если вам не нужно заменять объекты на сервере, а только выгрузить файлы для последующей замены, то достаточно поменять параметр $alter с $true на $false.

$ServerName=Read-Host "Укажите имя сервера БД"
# Определяем имя БД
$DatabaseName=Read-Host "Введите имя БД"
# Определяем текст для поиска
$OldText=Read-Host "Введите текст для поиска" 
# Определяем текст для замены
$NewText=Read-Host "Введите текст для замены" 

$backupFolder = "c:\temp\old\";  
$changeFolder = "c:\temp\new\";
$alter = $true;  

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | Out-Null
$server=new-object("Microsoft.SqlServer.Management.Smo.Server") $ServerName
 
#Имя БД, с которой работаем
$db = $server.Databases[$DatabaseName]

 
# Создаём соединение
$SQLConnection = New-Object System.Data.SqlClient.SqlConnection("Data Source=$ServerName;Integrated Security=SSPI;Initial Catalog=$DatabaseName") 
 
# Создаем SQL команду, используя наш запрос и созданное соединение
$SQLCommand = New-Object System.Data.SqlClient.SqlCommand("
select object_schema_name(m.object_id) as sch
     , object_name(m.object_id) as obj
     , o.type   
     , o.type_desc
     , object_schema_name(o.parent_object_id) as parent_sch
     , object_name(o.parent_object_id) as parent_obj
    from sys.sql_modules m
        inner join sys.objects o
          on m.object_id = o.object_id
    where m.definition like '%$OldText%'
    order by 2
", $SQLConnection) 
 
# Открываем соединение
$SQLConnection.Open()
 
# Выполняем….
$SQLAdapter = New-Object System.Data.SqlClient.SqlDataAdapter($SQLCommand)
$DataSet = New-Object System.Data.DataSet;
$SQLAdapter.Fill($DataSet);
$DataTable=New-Object System.Data.DataTable
$DataTable=$DataSet.Tables[0]
 
$DataTable.DefaultView | Out-GridView

foreach ($Row in $DataTable.Rows)
{
   $type = $($Row[2])
   
   #StoredProcedures
   if ( $type -match "P" )
   {
    $proc = $db.StoredProcedures | where {$_.Schema -eq $($Row[0]) -and $_.Name -eq $($Row[1])}
    $proc.Script() | Out-File ($backupFolder + "StoredProcedures\" + [string]$proc.name + ".sql");
    $proc.Script() -replace($OldText, $NewText) | Out-File ($changeFolder + "StoredProcedures\" + [string]$proc.name + ".sql");
        if($alter)
        {
        $proc.TextBody = $proc.TextBody -replace($OldText, $NewText);
        $proc.Alter();
        Write-Host "Altered " $proc.Name;
        }    
   }
   
   #Views
   if ( $type -match "V" )
   {
    $view = $db.Views | where {$_.Schema -eq $($Row[0]) -and $_.Name -eq $($Row[1])}
    $view.Script() | Out-File ($backupFolder + "Views\" + [string]$view.name + ".sql");
    $view.Script() -replace($OldText, $NewText) | Out-File ($changeFolder + "Views\" + [string]$view.name + ".sql");
        if($alter)
        {
        $view.TextBody = $view.TextBody -replace($OldText, $NewText);
        $view.Alter();
        Write-Host "Altered " $view.Name;
        }    
   }
   
   #Triggers
   if ( $type -match "TR" )
   {
    $table = $db.Tables | where {$_.Schema -eq $($Row[4]) -and $_.Name -eq $($Row[5])}
    $trigger = $table.Triggers | where {$_.Name -eq $($Row[1])}
    $trigger.Script() | Out-File ($backupFolder + "Triggers\" + [string]$trigger.name + ".sql");
    $trigger.Script() -replace($OldText, $NewText) | Out-File ($changeFolder + "Triggers\" + [string]$trigger.name + ".sql");
        if($alter)
        {
        $trigger.TextBody = $trigger.TextBody -replace($OldText, $NewText);
        $trigger.Alter();
        Write-Host "Altered " $trigger.Name;
        }    
   }
   
   #UserDefinedFunctions (SQL_SCALAR_FUNCTION, SQL_INLINE_TABLE_VALUED_FUNCTION, SQL_TABLE_VALUED_FUNCTION)
   if ( ( $type -match "FN" ) -or ( $type -match "IF" ) -or ( $type -match "TF" ) )
   {
    $func = $db.UserDefinedFunctions | where {$_.Schema -eq $($Row[0]) -and $_.Name -eq $($Row[1])}
    $func.Script() | Out-File ($backupFolder + "UserDefinedFunctions\" + [string]$func.name + ".sql");
    $func.Script() -replace($OldText, $NewText) | Out-File ($changeFolder + "UserDefinedFunctions\" + [string]$func.name + ".sql");
        if($alter)
        {
        $func.TextBody = $func.TextBody -replace($OldText, $NewText);
        $func.Alter();
        Write-Host "Altered " $func.Name;
        }    
   }
     
}

# Закрываем соединение
$SQLConnection.Close()

Tags: ,

PowerShell | SQL Server

Добавить комментарий

  Country flag

biuquote
  • Комментарий
  • Предпросмотр
Loading