Je suis novice en SQL et je devais combiner 2 bases de données .mdf en une. Je l'ai fait à l'aide de SQL Server 2008 Manager - Tâches> Importer/Exporter des tables. Les tables et les vues ont été copiées avec succès, mais la nouvelle base de données ne contient aucune procédure stockée. Y'a-t'il un quelconque moyen d'y arriver?
Ce code copie toutes les procédures stockées dans la base de données principale dans la base de données cible. Vous pouvez copier uniquement les procédures souhaitées en filtrant la requête en fonction du nom de la procédure.
@sql est défini comme nvarchar (max), @Name est la base de données cible
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
Plus tard, mais donne plus de détails qui pourraient être utiles…
Voici une liste de choses que vous pouvez faire avec des avantages et des inconvénients
Générez des scripts à l'aide de SSMS
Outils tiers
Vues système
Voici comment obtenir une liste de toutes les procédures d’une base de données qui n’existent pas dans une autre base de données
select *
from DB1.sys.procedures P
where P.name not in
(select name from DB2.sys.procedures P2)
J'ai initialement trouvé cet article à la recherche d'une solution permettant de copier des procédures stockées de ma base de données de production distante vers ma base de données de développement locale. Après avoir utilisé avec succès l'approche suggérée dans ce fil, j'ai compris que je devenais de plus en plus paresseux (ou plein de ressources, selon votre préférence) et que je souhaitais que cela soit automatisé. Je suis tombé sur ce lien , ce qui s’est avéré très utile (merci vincpa), et j’ai prolongé, aboutissant au fichier suivant (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()
J'ai un fichier .bat qui appelle cela et s'appelle à partir du Planificateur de tâches. Après l'appel du fichier Powershell, j'ai:
for /f %f in ('dir /b d:\prod_schema_backup\stp\') do sqlcmd /S localhost /d dest_db /Q "DROP PROCEDURE %f"
Cette ligne passera par le répertoire et supprimera les procédures à recréer. S'il ne s'agissait pas d'un environnement de développement, je n'aimerais pas abandonner les procédures de cette manière. J'ai alors renommé tous les fichiers de procédure stockée pour avoir .sql:
powershell Dir d:\prod_schema_backup\stp\ | Rename-Item -NewName { $_.name + ".sql" }
Et puis courez:
for /f %f in ('dir /b d:\prod_schema_backup\stp\') do sqlcmd /S localhost /d dest_db /E /i "%f".sql
Et cela parcourt tous les fichiers .sql et recrée les procédures stockées. J'espère que n'importe quelle partie de ceci s'avérera utile à quelqu'un.
Vous pouvez générer un script de la procédure stockée comme décrit dans d'autres réponses. Une fois le script généré, vous pouvez utiliser sqlcmd
pour les exécuter sur le DB cible, comme
sqlcmd -S <server name> -U <user name> -d <DB name> -i <script file> -o <output log file>
Vous pouvez utiliser la fonction "Générer des scripts ..." de SSMS pour créer un script de ce que vous devez transférer. Cliquez avec le bouton droit sur la base de données source dans SSMS, choisissez "Générer des scripts ...", puis suivez les instructions de l'assistant. Ensuite, exécutez votre script résultant, qui contiendra désormais les instructions create de la procédure stockée.
utilisation
select * from sys.procedures
montrer toutes vos procédures;
sp_helptext @objname = 'Procedure_name'
pour obtenir le code
et votre créativité pour construire quelque chose pour les parcourir et générer le code d'exportation :)
Dans Mgmt Studio, cliquez avec le bouton droit de la souris sur votre base de données d'origine, puis sur Tâches, puis sur Générer des scripts ... - suivez l'assistant.
SELECT définition + caractère (13) + 'GO' FROM MyDatabase.sys.sql_modules s INNER JOIN s MyDatabase.sys.procedures p ON [s]. [Id_objet] = [p]. [Id_objet] WHERE nom p. LIKE 'Quelque chose% '"queryout" c:\SP_scripts.sql -S MonInstance -T -t -w
obtenir le sp et l'exécuter