Restaurer la procédure stockée

J'ai une database dans SQL Server 2008 R2 et j'ai créé cette procédure stockée pour la restauration des bases de données:

CREATE PROCEDURE [dbo].[usp_DBRestore] @DBName nvarchar(60) ,@BackName nvarchar(120) ,@OutMessage nvarchar(4000) output --, --@DataName varchar(60), --@DataFileName varchar(120), --@LogName varchar(60), --@LogFileName varchar(120) AS BEGIN TRY USE [master] ALTER DATABASE @DBName SET SINGLE_USER WITH ROLLBACK IMMEDIATE RESTORE DATABASE @DBName FROM DISK = @BackName WITH FILE = 1, NOUNLOAD, REPLACE, PASSWORD = 'TEST' SET @OutMessage = 'OK'; ALTER DATABASE @DBName SET MULTI_USER WITH ROLLBACK IMMEDIATE END TRY BEGIN CATCH ALTER DATABASE @DBName SET MULTI_USER WITH ROLLBACK IMMEDIATE INSERT [dbo].[ErrorLog] ( [UserName], [ErrorNumber], [ErrorSeverity], [ErrorState], [ErrorProcedure], [ErrorLine], [ErrorMessage] ) VALUES( CONVERT(sysname, CURRENT_USER), ERROR_NUMBER(), ERROR_SEVERITY(), ERROR_STATE(), ERROR_PROCEDURE(), ERROR_LINE(), ERROR_MESSAGE() ) END CATCH 

Quand j'exécute du code, je vois cette erreur:

une instruction de database USE n'est pas autorisée dans une procédure, une fonction ou un triggersur.

Comment puis-je résoudre cette erreur?

Vous ne pouvez pas faire cela de cette façon – vous avez essentiellement deux options:

  1. s'en tenir à une procédure stockée, mais dans ce cas, vous devez utiliser SQL dynamic. Votre procédure stockée crée une string d'instructions SQL, ce qui lui permet d'utiliser USE master et lui permet de définir dynamicment le nom de la database etc., puis exécute cette instruction SQL à l'aide de sp_executesql @sqlRestoreStatement . Si vous voulez vérifier cela, vous DEVEZ être tous les moyens de lire (et de comprendre) l'article séminal d'Erland Sommarskog La malédiction et les bénédictions du SQL dynamic

  2. vous pouvez utiliser un script SQL normal, éventuellement avec des espaces réservés SQLCMD (si le SQLCMD mode activé dans SQL Server Management Studio) et exécuter la restauration à partir d'un script standard (que vous pouvez placer dans votre propre dossier de templates, par exemple). Dans ce cas, vous auriez quelque chose comme:

     :setvar dbname YourDatabaseNameHere DECLARE @FileName NVARCHAR(255) SET @FileName = N'D:\YourBackupDirectory\SomeDatabase.bak' RESTORE DATABASE [$(dbname)] FROM DISK = @FileName WITH FILE = 1, MOVE N'YourDatabase_Data' TO N'D:\MSSQL\Data\$(dbname).mdf', MOVE N'YourDatbase_Log' TO N'D:\MSSQL\Data\$(dbname)_Log.ldf', NOUNLOAD, REPLACE, STATS = 2 GO 

    Avec cette configuration, vous pouvez facilement utiliser le script SQL comme model et restaurer n'importe quel type de database en l'utilisant.

Vous n'avez pas besoin de l'instruction USE. Le mieux est de supprimer l'instruction Use et de créer / modifier cette sp sur la database master elle-même.

Si vous souhaitez effectuer une sauvegarde, exécutez ce SP à partir de la database principale. Je ne vois pas d'autre moyen de sortir.

Vous pouvez créer un server lié et le referencer dans votre procédure stockée. Par exemple. LinkedServer.database. [Dbo] .StoredProcedure

Découvrez ceci Comment créer le server lié pour SQL Server 2008 où nous avons la database de 2000 et 2005

Pourquoi ne pas save cette procédure stockée dans la database master? Cela serait-il un problème pour vous?