SQL Server - копіюйте збережені процедури з одного базу даних на інший


87

Я новачок у SQL, і мені потрібно було об’єднати 2 бази даних .mdf в одну. Я зробив це за допомогою диспетчера SQL Server 2008 - Завдання> Імпорт / експорт таблиць. Таблиці та подання були скопійовані успішно, але в новій базі даних немає збережених процедур. Чи можна це зробити?


1
Якщо ви хочете скопіювати їх програмно, почніть тут: stackoverflow.com/a/6124487/138938
Джон Кроуелл

Відповіді:


138
  • Клацніть правою кнопкою миші на базі даних
  • Завдання
  • Створення сценаріїв
  • Виберіть об’єкти, які ви хочете створити
  • Скрипт у файл
  • Запустити згенеровані сценарії проти цільової бази даних

Привіт, дякую за швидку відповідь. Чи можете ви пояснити, як використовувати скрипт проти цільової бази даних? Я новачок у цьому.
Дуб

1
@BarryKaye Що робити, якщо він має 30-40 збережених процедур? Чи не буде натискання правої кнопки трохи повільним?
rvphx

@Oak Відкрийте файл створення сценарію в SQL Management Studio. Змініть підключення до нової бази даних. Змініть рядок у верхній частині файлу, де написано «Використовувати ім’я бази даних», до вашої бази даних і запустіть.
Джаймал Чохан

Ого. Тепер я подумав, що мені єдиному подобається підхід на основі графічного інтерфейсу !!
rvphx

10
@RajivVarma - ви робите це завдання один раз для бази даних - не кожен SP! Якщо встановити прапорець верхнього рівня поруч із «Збережені процедури», він виділить їх усі разом - 1 клік.
Barry Kaye,

19

Цей код копіює всі збережені процедури в головній базі даних у цільову базу даних. Ви можете скопіювати лише ті процедури, які вам подобаються, відфільтрувавши запит на ім'я процедури.

@sql визначається як nvarchar (max), @Name - цільова база даних

DECLARE c CURSOR FOR 
   SELECT Definition
   FROM [ResiDazeMaster].[sys].[procedures] p
   INNER JOIN [ResiDazeMaster].sys.sql_modules m ON p.object_id = m.object_id

OPEN c

FETCH NEXT FROM c INTO @sql

WHILE @@FETCH_STATUS = 0 
BEGIN
   SET @sql = REPLACE(@sql,'''','''''')
   SET @sql = 'USE [' + @Name + ']; EXEC(''' + @sql + ''')'

   EXEC(@sql)

   FETCH NEXT FROM c INTO @sql
END             

CLOSE c
DEALLOCATE c

Дякую! ... У коментарях, але не задекларовані в коді, @sql& @Name:DECLARE @sql NVARCHAR(MAX); DECLARE @Name NVARCHAR(32);
datalifenyc

Чи є спосіб зробити це те саме на різних серверах? Від сервера A до сервера B?
Раджарам1991

5

Пізній, але надає більше деталей, які можуть бути корисними ...

Ось список речей, які ви можете зробити з перевагами та недоліками

Створюйте сценарії за допомогою SSMS

  • Плюси: надзвичайно простий у використанні та підтримується за замовчуванням
  • Мінуси: сценарії можуть мати неправильний порядок виконання, і ви можете отримати помилки, якщо збережена процедура вже існує у вторинній базі даних. Не забудьте переглянути сценарій перед виконанням.

Сторонні інструменти

  • Плюси: такі інструменти, як ApexSQL Diff (саме цим я користуюся, але є багато інших, такі як інструменти від Red Gate або Dev Art), порівняють дві бази даних одним клацанням миші та згенерують сценарій, який ви зможете негайно виконати
  • Мінуси: вони не безкоштовні (хоча більшість постачальників мають повністю функціональну пробну версію)

Перегляди системи

  • Плюси: Ви можете легко побачити, які збережені процедури існують на вторинному сервері, і генерувати лише ті, яких у вас немає.
  • Мінуси: Потрібно трохи більше знань SQL

Ось як отримати список усіх процедур у якійсь базі даних, яких немає в іншій базі даних

select *
from DB1.sys.procedures P
where P.name not in 
 (select name from DB2.sys.procedures P2)

5

Спочатку я знайшов цю публікацію, шукаючи рішення для копіювання збережених процедур з моєї віддаленої виробничої бази даних у мою локальну базу даних розвитку. Після успіху, використовуючи запропонований підхід у цій темі, я зрозумів, що став дедалі лінішим (або винахідливим, залежно від того, що вам більше подобається) і хочу, щоб це було автоматизовано. Я натрапив на це посилання , яке виявилось дуже корисним (спасибі vincpa), і я продовжив його, в результаті чого з’явився такий файл (schema_backup.ps1):

$server             = "servername"
$database           = "databaseName"
$output_path        = "D:\prod_schema_backup"
$login = "username"
$password = "password"

$schema             = "dbo"
$table_path         = "$output_path\table\"
$storedProcs_path   = "$output_path\stp\"
$views_path         = "$output_path\view\"
$udfs_path          = "$output_path\udf\"
$textCatalog_path   = "$output_path\fulltextcat\"
$udtts_path         = "$output_path\udtt\"

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo")  | out-null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | out-null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended")  | out-null
$srvConn = new-object Microsoft.SqlServer.Management.Common.ServerConnection
$srvConn.ServerInstance = $server
$srvConn.LoginSecure = $false
$srvConn.Login = $login
$srvConn.Password = $password
$srv        = New-Object Microsoft.SqlServer.Management.SMO.Server($srvConn)
$db         = New-Object ("Microsoft.SqlServer.Management.SMO.Database")
$tbl        = New-Object ("Microsoft.SqlServer.Management.SMO.Table")
$scripter   = New-Object Microsoft.SqlServer.Management.SMO.Scripter($srvConn)

# Get the database and table objects
$db = $srv.Databases[$database]

$tbl            = $db.tables | Where-object { $_.schema -eq $schema  -and -not $_.IsSystemObject } 
$storedProcs    = $db.StoredProcedures | Where-object { $_.schema -eq $schema -and -not $_.IsSystemObject } 
$views          = $db.Views | Where-object { $_.schema -eq $schema } 
$udfs           = $db.UserDefinedFunctions | Where-object { $_.schema -eq $schema -and -not $_.IsSystemObject } 
$catlog         = $db.FullTextCatalogs
$udtts          = $db.UserDefinedTableTypes | Where-object { $_.schema -eq $schema } 

# Set scripter options to ensure only data is scripted
$scripter.Options.ScriptSchema  = $true;
$scripter.Options.ScriptData    = $false;

#Exclude GOs after every line
$scripter.Options.NoCommandTerminator   = $false;
$scripter.Options.ToFileOnly            = $true
$scripter.Options.AllowSystemObjects    = $false
$scripter.Options.Permissions           = $true
$scripter.Options.DriAllConstraints     = $true
$scripter.Options.SchemaQualify         = $true
$scripter.Options.AnsiFile              = $true

$scripter.Options.SchemaQualifyForeignKeysReferences = $true

$scripter.Options.Indexes               = $true
$scripter.Options.DriIndexes            = $true
$scripter.Options.DriClustered          = $true
$scripter.Options.DriNonClustered       = $true
$scripter.Options.NonClusteredIndexes   = $true
$scripter.Options.ClusteredIndexes      = $true
$scripter.Options.FullTextIndexes       = $true

$scripter.Options.EnforceScriptingOptions   = $true

function CopyObjectsToFiles($objects, $outDir) {
    #clear out before 
    Remove-Item $outDir* -Force -Recurse
    if (-not (Test-Path $outDir)) {
        [System.IO.Directory]::CreateDirectory($outDir)
    }   

    foreach ($o in $objects) { 

        if ($o -ne $null) {

            $schemaPrefix = ""

            if ($o.Schema -ne $null -and $o.Schema -ne "") {
                $schemaPrefix = $o.Schema + "."
            }

            #removed the next line so I can use the filename to drop the stored proc 
            #on the destination and recreate it
            #$scripter.Options.FileName = $outDir + $schemaPrefix + $o.Name + ".sql"
            $scripter.Options.FileName = $outDir + $schemaPrefix + $o.Name
            Write-Host "Writing " $scripter.Options.FileName
            $scripter.EnumScript($o)
        }
    }
}

# Output the scripts
CopyObjectsToFiles $tbl $table_path
CopyObjectsToFiles $storedProcs $storedProcs_path
CopyObjectsToFiles $views $views_path
CopyObjectsToFiles $catlog $textCatalog_path
CopyObjectsToFiles $udtts $udtts_path
CopyObjectsToFiles $udfs $udfs_path

Write-Host "Finished at" (Get-Date)
$srv.ConnectionContext.Disconnect()

У мене є файл .bat, який викликає це і викликається із Планувальника завдань. Після виклику файлу Powershell у мене є:

for /f %f in ('dir /b d:\prod_schema_backup\stp\') do sqlcmd /S localhost /d dest_db /Q "DROP PROCEDURE %f"

Цей рядок пройде через каталог і скине процедури, які він збирається відтворити. Якби це не було середовищем для розробки, я б не хотів програмно відмовлятися від процедур таким чином. Потім я перейменовую всі збережені файли процедур у .sql:

powershell Dir d:\prod_schema_backup\stp\ | Rename-Item -NewName { $_.name + ".sql" }

А потім запустіть:

for /f %f in ('dir /b d:\prod_schema_backup\stp\') do sqlcmd /S localhost /d dest_db /E /i "%f".sql

І це перебирає всі файли .sql і відтворює збережені процедури. Я сподіваюся, що будь-яка частина цього стане комусь корисною.


Мені це подобається. Мені доводиться писати процес архівування фрагментів виробничої БД один рік за один раз. Я не хочу, щоб у мене зависали файли SQL, які, ймовірно, не оновлюватимуться в міру розвитку схеми, тому я адаптую це для створення порожньої БД на основі цілі без проміжного кроку запису файлів на диск (більше прибирати). Я гадаю, це, мабуть, найкраща та найбільш повторна відповідь на це питання, поважаю, сер!
Steve Pettifer

3

Ви можете скористатися функцією SSMS "Генерувати сценарії ...", щоб виписати все, що потрібно для передачі. Клацніть правою кнопкою миші на вихідній базі даних у SSMS, виберіть "Створити сценарії ..." та дотримуйтесь інструкцій майстра. Потім запустіть результуючий сценарій, який тепер міститиме збережені процедури створення операторів.


3

використання

select * from sys.procedures

показати всі ваші процедури;

sp_helptext @objname = 'Procedure_name'

щоб отримати код

і ваша креативність, щоб побудувати щось, щоб прокрутити їх усі та сформувати код експорту :)


3

Ви можете створити сценарій збережених процесів, як показано в інших відповідях. Після того, як сценарій буде згенерований, ви можете використовувати його sqlcmdдля виконання щодо цільової БД, наприклад

sqlcmd -S <server name> -U <user name> -d <DB name> -i <script file> -o <output log file> 

0

У програмі Mgmt Studio клацніть правою кнопкою миші на вихідній базі даних, а потім - Завдання, а потім Створити сценарії ... - дотримуйтесь майстра.


0

ВИБЕРІТЬ визначення + char (13) + "ПЕРЕЙТИ" З MyDatabase.sys.sql_modules s ВНУТРІШНЄ ПРИЄДНАННЯ MyDatabase.sys.procedures p ON [s]. [Object_id] = [p]. [Object_id] WHERE p.name LIKE 'Something% '"запит" c: \ SP_scripts.sql -S MyInstance -T -t -w

отримати sp і виконати його


Це дуже приємне рішення, але 1) слід зазначити, що потрібен вихід тексту або файлу (не відображайте результати в сітці, інакше ви втратите символи EOL) і 2), схоже, існує обмеження 8 к для виведення тексту в студії управління SQL Server.
DAB,

0

Іншим варіантом є передача збережених процедур за допомогою служб інтеграції SQL Server (SSIS) . Існує завдання, яке називається Завдання передачі об’єктів SQL Server . За допомогою завдання можна передати такі елементи:

  • Столи
  • Перегляди
  • Зберігаються процедури
  • Визначені користувачем функції
  • За замовчуванням
  • Типи даних, що визначаються користувачем
  • Функції розділів
  • Схеми розділів
  • Схеми
  • Асамблеї
  • Визначені користувачем агрегати
  • Визначені користувачем типи
  • Колекція схем XML

Це графічний посібник із перенесення завдань SQL Server Objects.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.