0

我运行了以下脚本

DECLARE @name VARCHAR(50)

DECLARE @Statment VARCHAR(500)

DECLARE DB_cursor CURSOR
FOR
SELECT  name
FROM    sys.databases
WHERE   name NOT IN ( 'master', 'tempdb', 'model', 'msdb',
                      'ReportServer$SQLEXPRESS',
                      'ReportServer$SQLEXPRESSTempDB' )

OPEN DB_cursor

FETCH NEXT FROM DB_cursor INTO @name

WHILE @@FETCH_STATUS = 0 
BEGIN

    PRINT @name

    ALTER DATABASE [@name] SET SINGLE_USER WITH ROLLBACK IMMEDIATE

    SET @Statment = 'Backup database ' + @name + ' To disk =N' + ''''
        + 'C:\Mas\' + @name + '.bak' + ''''

    PRINT @Statment

    EXEC(@Statment)
-- ALTER DATABASE [@name] SET MULTI_USER WITH ROLLBACK IMMEDIATE
-- EXEC sp_dboption @name, N'offline', N'false'
    FETCH NEXT FROM DB_cursor INTO @name
END 
CLOSE DB_cursor   
DEALLOCATE DB_cursor

我得到了下面的错误

消息 5011,级别 14,状态 5,第 11 行
用户无权更改数据库“@name”,数据库不存在,或数据库未处于允许访问检查的状态。

消息 5069,级别 16,状态 1,第 11 行
ALTER DATABASE 语句失败。

请让我知道如何解决此问题。

注意:- 我在 sa 登录中运行了这个脚本。

4

4 回答 4

2

错误消息清楚地说明了原因。这是因为 Alter database 命令将 [@name] 视为数据库而不是占位符。您可以在动态查询中包含这两个语句,然后执行。以下应该工作:

DECLARE @name VARCHAR(50)
DECLARE @Statment VARCHAR(500)
DECLARE @Statment1 VARCHAR(500)
DECLARE @Statment2 VARCHAR(500)

select name from sys.databases where name NOT IN('master','tempdb','model','msdb','ReportServer$SQLEXPRESS','ReportServer$SQLEXPRESSTempDB')

OPEN DB_cursor

FETCH NEXT FROM DB_cursor INTO @name

WHILE @@FETCH_STATUS = 0 

BEGIN

Print @name

SET @Statment = 'ALTER DATABASE ' +  @name + ' SET SINGLE_USER WITH ROLLBACK IMMEDIATE; '
EXEC(@Statment)
   SET @Statment1 = 'BACKUP DATABASE '  + @name + ' To disk =N' +''''+ 'C:\Mas\'+ @name          +'.bak'+''''
EXEC(@Statment1)
SET @Statment2 = 'ALTER DATABASE ' +  @name + ' SET MULTI_USER WITH ROLLBACK IMMEDIATE; '
EXEC(@Statment2)

EXEC(@Statment)
-- ALTER DATABASE [@name] SET MULTI_USER WITH ROLLBACK IMMEDIATE
-- EXEC sp_dboption @name, N'offline', N'false'
FETCH NEXT FROM DB_cursor INTO @name
END 
CLOSE DB_cursor   
DEALLOCATE DB_cursor
于 2013-10-30T06:55:47.330 回答
1

我改变了你的 T-SQL,这很有效。

你最喜欢这个示例在花药路径中更改备份文件的目标。

DECLARE @name VARCHAR(50)

DECLARE @Statment VARCHAR(500)

DECLARE DB_cursor CURSOR
FOR
SELECT  name
FROM    sys.databases
WHERE   name NOT IN ( 'master', 'tempdb', 'model', 'msdb',
                      'ReportServer$SQLEXPRESS',
                      'ReportServer$SQLEXPRESSTempDB' )

OPEN DB_cursor

FETCH NEXT FROM DB_cursor INTO @name

WHILE @@FETCH_STATUS = 0 
    BEGIN

    PRINT @name
--      DECLARE @A NVARCHAR(800) = ' ALTER DATABASE [' + @name + '] SET Multi_USER  WITH ROLLBACK IMMEDIATE '
    DECLARE @A NVARCHAR(800) = ' ALTER DATABASE [' + @name + '] SET SINGLE_USER WITH ROLLBACK IMMEDIATE '
    EXECUTE Sp_ExecuteSQL @A

    SET @Statment = 'Backup database ' + @name + ' To disk =N' + ''''
        + 'C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER2012\MSSQL\Backup\' 
        + @name + '.bak' + ''''

    PRINT @Statment

    EXEC(@Statment)
-- ALTER DATABASE [@name] SET MULTI_USER WITH ROLLBACK IMMEDIATE
-- EXEC sp_dboption @name, N'offline', N'false'
    FETCH NEXT FROM DB_cursor INTO @name
END 
CLOSE DB_cursor   
DEALLOCATE DB_cursor

喜欢下图

您最喜欢在您的路径中访问 SQL Server 用户Back up

在此处输入图像描述

于 2013-10-30T07:22:39.190 回答
0

您最常SP_ExecuteSQL用于更改数据库状态

DECLARE @A NVARCHAR(800) = ' ALTER DATABASE [' + 
                           @name + 
                           '] SET SINGLE_USER WITH ROLLBACK IMMEDIATE '
EXECUTE Sp_ExecuteSQL @A

然后您可以将数据库设置为单用户模式。

于 2013-10-30T07:09:04.487 回答
0

SQL 命令 ALTER DATABASE 不允许使用参数,因此它将@name 视为实际名称而不是参数。

更改数据库

NAME 指定文件的逻辑名称。logical_file_name 是引用文件时在 Microsoft SQL Server 中使用的名称。该名称在数据库中必须是唯一的,并且符合标识符规则。名称可以是字符或 Unicode 常量、常规标识符或定界标识符。有关详细信息,请参阅使用标识符

于 2013-10-30T06:45:55.897 回答