0

エラーが発生するスクリプトを実行しています。スクリプトのセクションをコメントアウトすると、成功したと表示されますが、実際には何も実行されていません。このスクリプトは、複数のディレクトリにある複数のデータベースの復元スクリプトです。スクリプトは、これらのデータベースをデータベースと同じ名前のディレクトリに復元することになっています。ここにスクリプトを添付します。

   use [master]
GO

set nocount on

declare @curdir nvarchar(400)
declare @line varchar(400)
declare @command varchar(400)
declare @counter bigint
Declare @Database_name varchar(400)
Declare @directory varchar(400)
Declare @filename_name varchar(400)
declare @is_final_restore varchar(1)

set @is_final_restore = 'N'

If (select count (*) from sys.objects where name='Output') <> 0 DROP TABLE output  
If (select count (*) from tempdb.sys.objects where name like '%#Tempoutput%') <> 0 DROP TABLE #Tempoutput   
If (select count (*) from tempdb.sys.objects where name like '%#dirs%') <> 0 DROP TABLE #dirs   

create table #dirs (DIRID bigint identity(1,1), directory varchar(400))
  Set @command = 'dir "E:\MVE_Backups\Full" /S/B/A:A'
 insert into #dirs exec xp_cmdshell @command
  set @counter = (select count(*) from #dirs)
create table #tempoutput (line varchar(400))

create table output (Path_name varchar(400),Directory varchar(400),Files varchar(400),Database_name varchar(400), FileSize varchar(400))
    While @Counter <> 0
      Begin
        Declare @filesize bigint
        set @curdir = (select directory from #dirs where DIRID = @counter)
        set @command = 'dir "' + @curdir +'"'
        insert into #tempoutput
        exec master.dbo.xp_cmdshell @command
           select @line = ltrim(replace(substring(line, charindex(')', line)+1,len(line)), ',', ''))
           from #tempoutput where line like '%File(s)%bytes'
           Set @filesize  = Replace(@line, ' bytes', '')
           Set @filename_name = reverse(left(reverse(@curdir), charindex('\', reverse(@curdir)) -1))
           Set @directory  = reverse(Right(reverse(@curdir), len(@curdir)-charindex('\', reverse(@curdir))))
           Set @Database_name = reverse(left(reverse(@directory), charindex('\', reverse(@directory)) -1))
        Insert into output (Path_name,Directory, Files,Database_name, Filesize) values (@curdir,@directory,@filename_name,@Database_name, @filesize)
        Set @counter = @counter -1
       End
  Delete from output where Path_name is null

DECLARE @fname VARCHAR(200) 
DECLARE @dirfile VARCHAR(300) 
DECLARE @LogicalName NVARCHAR(128) 
DECLARE @PhysicalName NVARCHAR(260) 
DECLARE @type CHAR(1) 
DECLARE @DbName sysname 
DECLARE @sql NVARCHAR(1000) 

  --- Create Temp tables for Restoring


CREATE TABLE #bdev( 
 BackupName NVARCHAR(128) 
,BackupDescription NVARCHAR(255) 
,BackupType smallint 
,ExpirationDate datetime 
,Compressed tinyint 
,Position smallint 
,DeviceType tinyint 
,UserName NVARCHAR(128) 
,ServerName NVARCHAR(128) 
,DatabaseName NVARCHAR(128) 
,DatabaseVersion INT 
,DatabaseCreationDate datetime 
,BackupSize numeric(20,0) 
,FirstLSN numeric(25,0) 
,LastLSN numeric(25,0) 
,CheckpointLSN numeric(25,0) 
,DatabaseBackupLSN numeric(25,0) 
,BackupStartDate datetime 
,BackupFinishDate datetime 
,SortOrder smallint 
,CodePage smallint 
,UnicodeLocaleId INT 
,UnicodeComparisonStyle INT 
,CompatibilityLevel tinyint 
,SoftwareVendorId INT 
,SoftwareVersionMajor INT 
,SoftwareVersionMinor INT 
,SoftwareVersionBuild INT 
,MachineName NVARCHAR(128) 
,Flags INT 
,BindingID uniqueidentifier 
,RecoveryForkID uniqueidentifier 
,Collation NVARCHAR(128) 
,FamilyGUID uniqueidentifier 
,HasBulkLoggedData INT 
,IsSnapshot INT 
,IsReadOnly INT 
,IsSingleUser INT 
,HasBackupChecksums INT 
,IsDamaged INT 
,BegibsLogChain INT 
,HasIncompleteMetaData INT 
,IsForceOffline INT 
,IsCopyOnly INT 
,FirstRecoveryForkID uniqueidentifier 
,ForkPointLSN numeric(25,0) 
,RecoveryModel NVARCHAR(128) 
,DifferentialBaseLSN numeric(25,0) 
,DifferentialBaseGUID uniqueidentifier 
,BackupTypeDescription NVARCHAR(128) 
,BackupSetGUID uniqueidentifier 
,CompressedBackupSize bigint
) 

--Table to hold result from RESTORE FILELISTONLY. Need to generate the MOVE options to the RESTORE command 
CREATE TABLE #dbfiles( 
 LogicalName NVARCHAR(128) 
,PhysicalName NVARCHAR(260) 
,Type CHAR(1) 
,FileGroupName NVARCHAR(128) 
,Size numeric(20,0) 
,MaxSize numeric(20,0) 
,FileId INT 
,CreateLSN numeric(25,0) 
,DropLSN numeric(25,0) 
,UniqueId uniqueidentifier 
,ReadOnlyLSN numeric(25,0) 
,ReadWriteLSN numeric(25,0) 
,BackupSizeInBytes BIGINT 
,SourceBlockSize INT 
,FilegroupId INT 
,LogGroupGUID uniqueidentifier 
,DifferentialBaseLSN numeric(25) 
,DifferentialBaseGUID uniqueidentifier 
,IsReadOnly INT 
,IsPresent INT 
,TDEThumbPrint uniqueidentifier 
) 

DECLARE dbfiles CURSOR FOR 
SELECT LogicalName, PhysicalName, Type FROM #dbfiles 

declare backup_cur cursor for
    select Path_name, Database_name from output 
open backup_cur

fetch next from backup_cur into @filename_name, @database_name

--Loop through each script.
while @@FETCH_STATUS = 0
BEGIN

    if @is_final_restore = 'Y'
    BEGIN
        set @dirfile = @filename_name

        set @Database_name = @Database_name + '_temp'

        print 'RESTORE DATABASE [' + @database_name + '] FROM  DISK = N''' + @dirfile + ''' WITH FILE = 1, NOUNLOAD'
        print 'GO'
        print 'USE [' + @database_name + ']'
        print 'GO'
        print 'sp_changedbowner ''' + @database_name + '_user'''
        print 'GO'
        print 'USE [master]'
        print 'GO'
        print 'ALTER DATABASE [' + @database_name + '] SET TRUSTWORTHY on'
        print 'GO'
        print 'GRANT UNSAFE ASSEMBLY TO [' + @database_name + '_user]'
        print 'GO'
        print 'sp_configure ''clr enabled'', 1'
        print 'GO'
        print 'reconfigure'
        print 'GO'
    END

    ELSE
    BEGIN

        --PRINT ('Now Restoring Database '+ @database_name+' in Non-Recovery Mode. From File :'+@filename_name  )
        set @dirfile = @filename_name
        --Get database name from RESTORE HEADERONLY, assumes there's only one backup on each backup file. 
        TRUNCATE TABLE #bdev 
        INSERT #bdev 
        EXEC('RESTORE HEADERONLY FROM DISK = ''' + @dirfile + '''') 
        SET @DbName = (SELECT DatabaseName FROM #bdev) 

        --Construct the beginning for the RESTORE DATABASE command 
        SET @sql = 'RESTORE DATABASE [' + @DbName + '] FROM DISK = ''' + @dirfile + ''' WITH NORECOVERY, MOVE ' 

        --Get information about database files from backup device into temp table 
        TRUNCATE TABLE #dbfiles 
        INSERT #dbfiles 
        EXEC('RESTORE FILELISTONLY FROM DISK = ''' + @dirfile + '''') 

        OPEN dbfiles 
        FETCH NEXT FROM dbfiles INTO @LogicalName, @PhysicalName, @type 
        --For each database file that the database uses 
        WHILE @@FETCH_STATUS = 0 
        BEGIN 
        IF @type = 'D' 
        SET @sql = @sql + '''' + @LogicalName + ''' TO ''' + 'F:\Database_Files\'+@database_name+'\' + @LogicalName  + '.mdf'', MOVE ' 
        ELSE IF @type = 'L' 
        SET @sql = @sql + '''' + @LogicalName + ''' TO ''' + 'F:\Database_Files\'+@database_name+'\' + @LogicalName + '.ldf''' 
        FETCH NEXT FROM dbfiles INTO @LogicalName, @PhysicalName, @type 
        END 
        PRINT ('EXECUTE master.dbo.xp_create_subdir N'''+'F:\Database_Files\'+@database_name+'''')
        PRINT ('GO')
        PRINT @SQL
        PRINT ('GO')
        close dbfiles
    END
fetch next from backup_cur into @filename_name, @database_name  
END

close backup_cur
deallocate backup_cur
DEALLOCATE dbfiles 

drop table output;

drop table #bdev
drop table #dbfiles

これを実行したときのエラーは次のとおりです。

メッセージ 213、レベル 16、状態 7、行 1 列名または指定された値の数がテーブル定義と一致しません。メッセージ 3013、レベル 16、状態 1、行 1 RESTORE HEADERONLY が異常終了しています。

コメントアウトしたコードは次のとおりです。

BEGIN
    set @dirfile = @filename_name

    set @Database_name = @Database_name + '_temp'

    print 'RESTORE DATABASE [' + @database_name + '] FROM  DISK = N''' + @dirfile + ''' WITH FILE = 1, NOUNLOAD'
    print 'GO'
    print 'USE [' + @database_name + ']'
    print 'GO'
    print 'sp_changedbowner ''' + @database_name + '_user'''
    print 'GO'
    print 'USE [master]'
    print 'GO'
    print 'ALTER DATABASE [' + @database_name + '] SET TRUSTWORTHY on'
    print 'GO'
    print 'GRANT UNSAFE ASSEMBLY TO [' + @database_name + '_user]'
    print 'GO'
    print 'sp_configure ''clr enabled'', 1'
    print 'GO'
    print 'reconfigure'
    print 'GO'
END

ELSE
4

2 に答える 2

0

問題が何であるかを突き止めました... SQL 2008 R2 から SQL 2012 に移行すると、#bdev の作成時に欠落していた追加の列がありました。

両方の SQL サーバーのテーブル構造を確認して問題を解決したところ、SQL 2012 ではスクリプトにない新しい列が追加されていることがわかりました...この列を追加すると、スクリプトは正常に機能しました。

于 2013-04-19T13:38:49.373 に答える