【问题标题】:Msg 5011, Level 14, State 5, Line 11 ALTER DATABASE statement failed消息 5011,级别 14,状态 5,第 11 行 ALTER DATABASE 语句失败
【发布时间】:2013-10-30 06:27:28
【问题描述】:

我运行了以下脚本

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 登录中运行了这个脚本。

【问题讨论】:

  • 为什么要让数据库单用户运行备份???

标签: sql-server database tsql


【解决方案1】:

错误信息清楚地说明了原因。这是因为 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

【讨论】:

    【解决方案2】:

    我改变了你的 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
    

    喜欢下图

    您在Back up 路径中最能访问 SQL Server 用户

    【讨论】:

      【解决方案3】:

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

      ALTER DATABASE

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

      【讨论】:

        【解决方案4】:

        你最常使用SP_ExecuteSQL来改变数据库的状态

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-04-26
          • 1970-01-01
          • 2019-09-14
          • 2017-05-07
          • 1970-01-01
          • 1970-01-01
          • 2019-06-30
          • 2016-10-28
          相关资源
          最近更新 更多