无法在sql server中恢复数据库(single_user)

时间:2010-09-03 20:58:20

标签: sql-server sql-server-2005-express

我正在尝试在我的sql server 2005 express版中恢复数据库。我知道要恢复数据库,我需要让它成为单个用户。我将此命令发送给单个用户

USE [master]
ALTER DATABASE database_name SET SINGLE_USER WITH ROLLBACK IMMEDIATE

此命令执行正常,我甚至可以在此数据库的对象资源管理器中看到一个小图像,显示现在是单用户。

现在我正在尝试按照这些步骤恢复数据库   - >右键单击数据库和任务,然后恢复数据库。我正在选择备份文件所在的路径,然后单击“还原”。

但是我仍然得到了这个错误“因为数据库正在使用中无法获得独占访问权限(microsoft.sqlserver.smo)。我错过了什么。我用Google搜索了所有网站并建议数据库需要在单用户模式下,没有别的。

我没有尝试分离和附加数据库方法。我以前从未这样做过,并且想知道这样做是否安全。

编辑:感谢您的回答。两个人都建议我回答相同,所以我选择了一个答案。

我甚至选择从选项覆盖现有数据库。

3 个答案:

答案 0 :(得分:4)

首先,最好备份和恢复,而不是分离和附加。

其次,您尝试运行还原时,您用于将数据库设置为SINGLE_USER的会话最有可能仍然存在(因为您正在使用GUI,它正在连接在它自己的会话下,所以它无法访问)。

将还原作为文本命令执行,或者将查询窗口切换为首先使用其他数据库,例如master。或者您可以关闭查询窗口,使其不再连接。

您随时可以查看与select * from master.dbo.sysprocesses相关联的人。

<强>更新

假设您要还原的数据库已经存在,并且您在磁盘上有一个备份文件(其中没有多个备份),并且在还原完整备份后无需还原日志文件,那么还原通过脚本超级,超级简单:

RESTORE DATABASE DBName FROM DISK = 'C:\path\DBNameBackup.bak';

学习这种语法会让您的生活更轻松,因为当您设置SINGLE_USER时,您已经处于连接的唯一会话中。另外,我发现键入restore命令比使用GUI更快,我喜欢控制器。重复这一点最终会让你心满意足,而且你不必再查找语法了。

恢复日志文件甚至都不困难。只需要记住一件简单的事情,WITH NORECOVERY

RESTORE DATABASE DBName FROM DISK = 'C:\path\DBNameBackup.bak' WITH NORECOVERY;
RESTORE LOG DBName FROM DISK = 'C:\path\DBNameBackup1.log' WITH NORECOVERY;
RESTORE LOG DBName FROM DISK = 'C:\path\DBNameBackup2.log' WITH NORECOVERY;
RESTORE LOG DBName FROM DISK = 'C:\path\DBNameBackup3.log' WITH NORECOVERY;
... 4 5 6 7 and so on
RESTORE LOG DBName FROM DISK = 'C:\path\DBNameBackupX.log' WITH RECOVERY;

有......你很容易恢复你的日志文件。您甚至可以使用WITH STOPAT恢复到准确的时间点!此外,如果您忘记并意外提交了上一个日志还原语句WITH NORECOVERY,那么您只需发出RESTORE DATABASE DBName WITH RECOVERY;来执行最终步骤以使数据库可用(回滚未提交的事务等)。

答案 1 :(得分:2)

您可以使用此脚本使用数据库终止所有进程,然后再次尝试将其还原:

declare @sql as varchar(20), @spid as int
select @spid = min(spid)  from master..sysprocesses  where dbid = db_id('<database_name>') 
and spid != @@spid    

while (@spid is not null)
begin
    print 'Killing process ' + cast(@spid as varchar) + ' ...'
    set @sql = 'kill ' + cast(@spid as varchar)
    exec (@sql)

    select 
        @spid = min(spid)  
    from 
        master..sysprocesses  
    where 
        dbid = db_id('<database_name>') 
        and spid != @@spid
end 

print 'Process completed...'

答案 2 :(得分:1)

  • 转到左侧列表中“常规”下方的“选项”项目。
  • 确保选中“覆盖现有数据库”(“还原选项”部分)。
祝你好运。