我在SQL Server 2008 R2中有一个数据库,我创建了这个用于恢复数据库的存储过程:
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
当我执行代码时,我看到了这个错误:
过程,函数或中不允许使用USE数据库语句 触发。
如何解决此错误?
答案 0 :(得分:1)
你不能这样做 - 你基本上有两个选择:
坚持使用存储过程,但在这种情况下,您必须使用动态SQL。您的存储过程创建一个SQL语句字符串,允许它使用USE master
并允许它动态设置数据库名称等,然后使用sp_executesql @sqlRestoreStatement
执行该SQL语句。如果你想查看这个,你必须一切都是阅读(并理解)Erland Sommarskog的开创性文章The Curse and Blessings of Dynamic SQL
您可以使用常规SQL脚本,可能使用SQLCMD占位符(如果您在SQL Server Management Studio中启用了SQLCMD mode
)并从常规脚本执行还原(可以将其放入您的例如,自己的模板文件夹)。在这种情况下,你会有类似的东西:
: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
通过此设置,您可以轻松地将SQL脚本用作模板,并使用它恢复任何类型的数据库。
答案 1 :(得分:0)
您不需要USE声明。最好是删除Use语句并在master数据库本身上创建/更改此sp。
如果要进行备份,请从主数据库执行此SP。我看不到任何其他出路。
答案 2 :(得分:0)
您可以创建链接服务器并在存储过程中引用该服务器。 例如。 [DBO] LinkedServer.database。.StoredProcedure
看看这个 How to create the linked server for SQL Server 2008 where we have the database from 2000 and 2005