SQL Server: copia le stored procedure da un database a un altro


86

Sono nuovo in SQL e quello che dovevo fare era combinare 2 database .mdf in uno solo. L'ho fatto utilizzando SQL Server 2008 Manager - Attività> Importa / Esporta tabelle. Le tabelle e le viste sono state copiate correttamente, ma non ci sono procedure memorizzate nel nuovo database. C'è un modo per farlo?


1
Se vuoi copiarli a livello di programmazione, inizia qui: stackoverflow.com/a/6124487/138938
Jon Crowell,

Risposte:


137
  • Fare clic con il tasto destro sul database
  • Compiti
  • Genera script
  • Seleziona gli oggetti che desideri scrivere
  • Script su file
  • Esegui script generati sul database di destinazione

Ciao, grazie per la risposta veloce. Puoi spiegare come utilizzare lo script sul database di destinazione. Sono nuovo a questo.
Quercia

1
@BarryKaye E se avesse 30-40 stored procedure? Fare clic con il pulsante destro del mouse non sarebbe un po 'lento?
rvphx

@Oak Apre il file script di generazione in SQL Management Studio. Cambia la connessione al tuo nuovo database. Cambia la riga nella parte superiore del file dove dice "Usa DatabaseName" nel tuo database ed esegui.
Jaimal Chohan

Wow. Ora pensavo di essere l'unico a cui piaceva l'approccio basato su GUI !!
rvphx

10
@RajivVarma - esegui questa attività una volta per il database, non ogni SP! Se si spunta la casella di controllo di primo livello accanto a "Stored Procedures", vengono selezionate tutte insieme - 1 clic.
Barry Kaye

19

Questo codice copia tutte le stored procedure nel database Master nel database di destinazione, è possibile copiare solo le procedure che ti piacciono filtrando la query sul nome della procedura.

@sql è definito come nvarchar (max), @Name è il database di destinazione

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

Grazie! ... Nei commenti, ma non dichiarati nel codice ci sono @sql& @Name:DECLARE @sql NVARCHAR(MAX); DECLARE @Name NVARCHAR(32);
datalifenyc

C'è un modo per fare lo stesso su server diversi? Dal server A al server B?
Rajaram1991,

5

Uno in ritardo ma fornisce ulteriori dettagli che potrebbero essere utili ...

Ecco un elenco di cose che puoi fare con vantaggi e svantaggi

Genera script utilizzando SSMS

  • Pro: estremamente facile da usare e supportato di default
  • Contro: gli script potrebbero non essere nell'ordine di esecuzione corretto e potresti ricevere errori se la stored procedure esiste già sul database secondario. Assicurati di rivedere lo script prima di eseguirlo.

Strumenti di terze parti

  • Pro: strumenti come ApexSQL Diff (questo è quello che uso ma ce ne sono molti altri come strumenti di Red Gate o Dev Art) confronteranno due database con un clic e genereranno script che puoi eseguire immediatamente
  • Contro: non sono gratuiti (la maggior parte dei fornitori ha una versione di prova completamente funzionante)

Viste di sistema

  • Pro: puoi facilmente vedere quali stored procedure esistono sul server secondario e generare solo quelle che non hai.
  • Contro: richiede un po 'più di conoscenza SQL

Ecco come ottenere un elenco di tutte le procedure in alcuni database che non esistono in un altro database

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

5

Inizialmente ho trovato questo post alla ricerca di una soluzione per copiare le stored procedure dal mio database di produzione remota al mio database di sviluppo locale. Dopo il successo utilizzando l'approccio suggerito in questo thread, mi sono reso conto di essere diventato sempre più pigro (o pieno di risorse, a seconda di quale preferisci) e volevo che fosse automatizzato. Mi sono imbattuto in questo collegamento , che si è rivelato molto utile (grazie vincpa), e l'ho esteso, risultando nel seguente file (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()

Ho un file .bat che lo chiama e viene chiamato dall'utilità di pianificazione. Dopo la chiamata al file Powershell, ho:

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

Quella riga passerà attraverso la directory e lascerà cadere le procedure che sta per ricreare. Se questo non fosse un ambiente di sviluppo, non mi piacerebbe eliminare le procedure a livello di codice in questo modo. Quindi rinomino tutti i file della procedura memorizzata in .sql:

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

E poi esegui:

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

E che itera attraverso tutti i file .sql e ricrea le procedure memorizzate. Spero che qualsiasi parte di questo si riveli utile a qualcuno.


Mi piace questo. Devo scrivere un processo per archiviare pezzi di un DB di produzione un anno alla volta. Non voglio avere file SQL sospesi su cui probabilmente non verranno aggiornati man mano che lo schema si sviluppa, quindi lo sto adattando per creare un DB vuoto basato su un obiettivo senza il passaggio intermedio di scrittura di file su disco (altro pulire). Penso che questa sia probabilmente la risposta migliore e più riutilizzabile a questa domanda, complimenti signore!
Steve Pettifer

3

È possibile utilizzare la funzione "Genera script ..." di SSMS per eseguire lo script di tutto ciò che è necessario trasferire. Fare clic con il pulsante destro del mouse sul database di origine in SSMS, scegliere "Genera script ..." e seguire la procedura guidata. Quindi eseguire lo script risultante che ora conterrà le istruzioni create della procedura memorizzata.


3

uso

select * from sys.procedures

per mostrare tutte le tue procedure;

sp_helptext @objname = 'Procedure_name'

per ottenere il codice

e la tua creatività per costruire qualcosa per scorrere tutti e generare il codice di esportazione :)


3

È possibile generare lo script delle procedure memorizzate come illustrato in altre risposte. Una volta che lo script è stato generato, è possibile utilizzarli sqlcmdper eseguirli su DB di destinazione come

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

0

In Mgmt Studio, fai clic con il pulsante destro del mouse sul database originale, quindi su Attività, quindi su Genera script ... - segui la procedura guidata.


0

SELEZIONA definizione + char (13) + 'GO' FROM MyDatabase.sys.sql_modules s INNER JOIN MyDatabase.sys.procedures p ON [s]. [Object_id] = [p]. [Object_id] WHERE p.name LIKE 'Something% '"queryout" c: \ SP_scripts.sql -S MyInstance -T -t -w

ottenere la sp ed eseguirla


Questa è una soluzione molto carina, ma 1) dovresti sottolineare che è necessario l'output di testo o file (non visualizzare i risultati nella griglia, o perderai i caratteri EOL) e 2) sembra esserci un limite di 8k per l'output di testo in SQL Server Management Studio.
DAB

0

Un'altra opzione è trasferire le stored procedure utilizzando SQL Server Integration Services (SSIS) . Esiste un'attività denominata Trasferisci attività oggetti SQL Server . È possibile utilizzare l'attività per trasferire i seguenti elementi:

  • Tabelle
  • Visualizzazioni
  • Procedura di archiviazione
  • Funzioni definite dall'utente
  • Default
  • Tipi di dati definiti dall'utente
  • Funzioni di partizione
  • Schemi di partizione
  • Schemi
  • Assemblee
  • Aggregati definiti dall'utente
  • Tipi definiti dall'utente
  • Raccolta di schemi XML

È un'esercitazione grafica per l'attività di trasferimento di oggetti SQL Server.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.