SQL Server: copie los procedimientos almacenados de una base de datos a otra

Soy nuevo en SQL y lo que tenía que hacer era combinar 2 bases de datos .mdf en una sola. Lo hice usando el Administrador de SQL Server 2008 - Tareas > Importar/Exportar tablas. Las tablas y vistas se copiaron correctamente, pero no hay procedimientos almacenados en la nueva base de datos. ¿Hay alguna forma de hacer eso?

preguntado el 22 de mayo de 12 a las 14:05

Si desea copiarlos programáticamente, comience aquí: stackoverflow.com/a/6124487/138938 -

10 Respuestas

  • Haga clic derecho en la base de datos
  • tareas
  • Generar guiones
  • Seleccione los objetos que desea secuenciar
  • Guión a archivo
  • Ejecutar scripts generados contra la base de datos de destino

contestado el 22 de mayo de 12 a las 14:05

Hola, gracias por la respuesta rápida. ¿Puede explicar cómo usar el script contra la base de datos de destino? Soy nuevo en esto. - Roble

@BarryKaye ¿Qué pasa si tiene 30-40 procedimientos almacenados? ¿No sería un poco lento hacer clic derecho? - rvphx

@Oak Abra el archivo de script de generación en SQL Management Studio. Cambie la conexión a su nueva base de datos. Cambie la línea en la parte superior del archivo donde dice 'Use DatabaseName' a su base de datos y ejecute. - Jaimal Chohán

Guau. ¡Ahora pensé que era el único al que le gustaba el enfoque basado en GUI! - rvphx

@RajivVarma: realiza esta tarea una vez para la base de datos, ¡no para cada SP! Si marca la casilla de verificación de nivel superior junto a "Procedimientos almacenados", los selecciona todos juntos: 1 clic. - barry kaye

Este código copia todos los procedimientos almacenados en la base de datos maestra a la base de datos de destino, puede copiar solo los procedimientos que desee filtrando la consulta por el nombre del procedimiento.

@sql se define como nvarchar(max), @Name es la base de datos de destino

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

Respondido 28 Oct 13, 13:10

¡Gracias!... En los comentarios, pero no declarados en el código, están @sql & @Name: DECLARE @sql NVARCHAR(MAX); DECLARE @Name NVARCHAR(32); - datalifenyc

¿Hay alguna manera de hacer esto mismo en diferentes servidores? ¿Del servidor A al servidor B? - Rajaram1991

Uno tardío pero da más detalles que podrían ser útiles...

Aquí hay una lista de cosas que puede hacer con ventajas y desventajas

Generar scripts usando SSMS

  • Pros: extremadamente fácil de usar y compatible de forma predeterminada
  • Contras: los scripts pueden no estar en el orden de ejecución correcto y es posible que obtenga errores si el procedimiento almacenado ya existe en la base de datos secundaria. Asegúrese de revisar el script antes de ejecutarlo.

Herramientas de terceros

  • Pros: herramientas como ApexSQL Diff (esto es lo que uso, pero hay muchas otras herramientas como Red Gate o Dev Art) comparará dos bases de datos con un solo clic y generará un script que puede ejecutar de inmediato
  • Contras: estos no son gratuitos (aunque la mayoría de los proveedores tienen una versión de prueba completamente funcional)

Vistas del sistema

  • Pros: Puede ver fácilmente qué procedimientos almacenados existen en el servidor secundario y solo generar aquellos que no tiene.
  • Contras: Requiere un poco más de conocimiento de SQL

Aquí se explica cómo obtener una lista de todos los procedimientos en alguna base de datos que no existen en otra base de datos

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

Respondido 07 ago 13, 09:08

Originalmente encontré esta publicación buscando una solución para copiar procedimientos almacenados desde mi base de datos de producción remota a mi base de datos de desarrollo local. Después de usar con éxito el enfoque sugerido en este hilo, me di cuenta de que me volvía cada vez más perezoso (o ingenioso, lo que prefieras) y quería que esto se automatizara. Me encontré con este enlace, que resultó ser muy útil (gracias, vincpa), y lo amplié, lo que resultó en el siguiente archivo (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()

Tengo un archivo .bat que llama a esto y se llama desde el Programador de tareas. Después de la llamada al archivo de Powershell, tengo:

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

Esa línea pasará por el directorio y soltará los procedimientos que va a recrear. Si este no fuera un entorno de desarrollo, no me gustaría eliminar los procedimientos mediante programación de esta manera. Luego cambio el nombre de todos los archivos de procedimientos almacenados para que tengan .sql:

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

Y luego ejecuta:

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

Y eso itera a través de todos los archivos .sql y recrea los procedimientos almacenados. Espero que cualquier parte de esto resulte útil para alguien.

Respondido 20 Feb 14, 19:02

me gusta esto Tengo que escribir un proceso para archivar fragmentos de una base de datos de producción un año a la vez. No quiero tener que tener archivos SQL dando vueltas que probablemente no se actualizarán a medida que se desarrolla el esquema, así que estoy adaptando esto para crear una base de datos vacía basada en un objetivo sin el paso intermedio de escribir archivos en el disco (más limpiar). Creo que esta es probablemente la mejor y más reutilizable respuesta a esta pregunta, ¡felicitaciones, señor! - Steve Pettifer

utilizado

select * from sys.procedures

para mostrar todos sus procedimientos;

sp_helptext @objname = 'Procedure_name'

para obtener el código

y su creatividad para construir algo para recorrerlos todos y generar el código de exportación :)

contestado el 22 de mayo de 12 a las 14:05

Puede usar la función "Generar secuencias de comandos..." de SSMS para generar secuencias de comandos de lo que necesite transferir. Haga clic con el botón derecho en la base de datos de origen en SSMS, elija "Generar scripts..." y siga las instrucciones del asistente. Luego ejecute su secuencia de comandos resultante que ahora contendrá las declaraciones de creación del procedimiento almacenado.

contestado el 22 de mayo de 12 a las 14:05

Puede generar secuencias de comandos de los procesos almacenados como se muestra en otras respuestas. Una vez que se ha generado el script, puede utilizar sqlcmd para ejecutarlos contra la base de datos de destino como

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

contestado el 22 de mayo de 12 a las 15:05

Otra opción es transferir procedimientos almacenados usando Servicios de integración de SQL Server (SSIS). Hay una tarea llamada Tarea Transferir objetos de SQL Server. Puede utilizar la tarea para transferir los siguientes elementos:

  • Mesas
  • Vistas
  • Procedimientos almacenados
  • Funciones definidas por el usuario
  • predeterminados
  • Tipos de datos definidos por el usuario
  • Funciones de partición
  • Esquemas de partición
  • Esquemas
  • asambleas
  • Agregados definidos por el usuario
  • Tipos definidos por el usuario
  • Colección de esquemas XML

Se trata de un tutorial gráfico para la tarea Transferir objetos de SQL Server.

respondido 26 mar '20, 13:03

En Mgmt Studio, haga clic con el botón derecho en su base de datos original, luego Tareas, luego Generar secuencias de comandos... - siga el asistente.

contestado el 22 de mayo de 12 a las 14:05

SELECCIONE definición + char(13) + 'IR' DE MyDatabase.sys.sql_modules s INNER JOIN MyDatabase.sys.procedures p ON [s].[object_id] = [p].[object_id] DONDE p.name LIKE 'Algo% '" consulta "c:\SP_scripts.sql -S MiInstancia -T -t -w

obtener el sp y ejecutarlo

Respondido 24 Oct 13, 11:10

Esta es una muy buena solución, pero 1) debe señalar que se necesita la salida de texto o archivo (no muestre los resultados en la cuadrícula o perderá los caracteres EOL) y 2) parece haber un límite de 8k para salida de texto en SQL Server Management Studio. - DAB

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.