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

SQL コマンド ALTER DATABASE はパラメーターを許可しないため、@name をパラメーターとしてではなく実際の名前として扱います。

データベースの変更

NAME ファイルの論理名を指定します。logical_file_name ファイルを参照するときに Microsoft SQL Server で使用される名前です。名前はデータベース内で一意であり、識別子の規則に準拠している必要があります。名前は、文字または Unicode 定数、通常の識別子、または区切り識別子のいずれかです。詳細については、識別子の使用を参照してください。

于 2013-10-30T06:45:55.897 に答える
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 に答える