数据库文件显示在master_files中,但不显示在database_files中

时间:2014-11-18 17:06:41

标签: sql-server sql-server-2008 sql-server-2012

我有一些我继承的SQL数据库。

我全新安装了SQL 2012

我已将数据库附加到服务器而没有问题。

然而,在我运行Select * From sys.database_files;时,他们不在那里,但当我运行Select * From sys.master_files;时,他们就是。

这会弄乱我试图通过抛出以下错误编写的一些代码:

Msg 102, Level 15, State 1, Line 1
Incorrect syntax near 'I:'.
Msg 8985, Level 16, State 1, Line 1
Could not locate file 'I:\SQL Databases\Cloud.CMS_log.ldf' for database 'master' in     sys.database_files. The file either does not exist, or was dropped. 

如何修复它以便它们在sys.database_files中,以便我的代码运行?

Declare @TempDBList Table
(
    Id int,
    DBName VarChar(250),
    FileType int,
    DBFile VarChar(1000)
);
Declare @BackupLocation VarChar(Max) = 'I:\SQL Databases\Backup';
Declare @FileLocation VarChar(Max);
Declare @DBName VarChar(250);
Declare @FileType Int;
Declare @DBBackup VarChar(Max);
Declare @LogBackup VarChar(Max);
Declare @Sql VarChar(Max);

Insert Into @TempDBList
(id, DBName, FileType, DBFile)
Select a.database_id DBid, a.Name , b.type FileType, b.physical_name As FileLocation
    From sys.databases a
    Inner Join sys.master_files b On b.database_id = a.database_id
    Where b.state = 0 AND a.database_id > 4;

Select @DBName = DBName, @FileType = FileType, @FileLocation = DBFile From @TempDBList Order By DBName;

While @@ROWCOUNT <> 0
Begin
    --- Set all databases to Simple Recovery
    Set @Sql = 'Alter DATABASE ' + QUOTENAME(@DBName) + ' Set RECOVERY SIMPLE';
    Exec(@Sql);

    Set @DBBackup = @BackupLocation + @DBName + '\' + @DBName + '_' + Convert(Varchar(500), GetDate(), 112)+ '.bak';
    Set @LogBackup = @BackupLocation + @DBName + '\' + @DBName + '_' + Convert(Varchar(500), GetDate(), 112)+ '.log.bak';

    If @FileType = 1
        Begin
            Set @Sql = 'Backup Database ' + QUOTENAME(@DBName) + ' To Disk = ' + @DBBackup;
            Exec(@Sql);
            Exec('DBCC SHRINKFILE(''' + @FileLocation + ''', TruncateOnly)');
        End
    Else If @FileType = 0
        Begin
            Set @Sql = 'Backup Log ' + QUOTENAME(@DBName) + ' To Disk = ' + @LogBackup;
            Exec(@Sql);
            Exec('DBCC SHRINKFILE(''' + @FileLocation + ''', TruncateOnly)');
        End
End

sys.database_files&amp;的屏幕截图sys.master_files

http://prntscr.com/57p49b

1 个答案:

答案 0 :(得分:1)

sys.master_files是一个系统范围的视图,它将显示您所连接的实例上的所有文件(您有足够的权限),sys.database_files是每个数据库视图,并且只显示指定数据库中的文件。您需要连接到正确的数据库才能查看文件,例如:

USE Master;
SELECT  *
FROM    sys.database_files;

或使用3部分对象名称:

SELECT  *
FROM    master.sys.database_files;

修改

我只是因为没有很好地解释自己而道歉,但上面的确指出了为什么你无法在sys.database_files中看到sys.master_files中可以看到的文件。

请看以下屏幕截图:

enter image description here

您可以看到在连接到其他数据库(USE TestDB)后,sys.database_files中显示了不同的文件,但sys.master_files中的记录计数(和实际记录)是相同的不管数据库。

现在,看看你的实际错误:

  

找不到sys.database_files中数据库'master'的文件'I:\ SQL Databases \ Cloud.CMS_log.ldf'。

这解释了问题,您已连接到数据库master,因此sys.database_files仅显示master数据库(master和masterlog)中的文件。您正在寻找可能位于数据库CMS_log中的CMS,因此要在sys.database_files中查看此文件,您需要运行:

USE CMS;
SELECT * FROM sys.database_files;

或者

SELECT * FROM CMS.sys.database_files;

您的实际错误是因为您尝试在连接到master数据库时收缩文件CMS_Log,而您无法执行此操作,您需要运行:

USE CMS;
DBCC SHRINKFILE('CMS_Log', TRUNCATEONLY);

希望这能解释您收到错误的原因。


完整脚本

DECLARE @BackupLocation VARCHAR(MAX) = '',
        @DBName SYSNAME,
        @DataFile SYSNAME,
        @LogFile SYSNAME,
        @SQL NVARCHAR(MAX);

DECLARE FileCursor CURSOR STATIC FORWARD_ONLY READ_ONLY
FOR
    SELECT  DBName = d.Name,
            DataFile = MAX(CASE WHEN f.Type = 0 THEN f.Name END),
            LogFile = MAX(CASE WHEN f.Type = 1 THEN f.Name END)
    FROM    sys.databases d
            INNER JOIN sys.master_files f
                ON d.database_id = f.database_id
    WHERE   d.Name NOT IN ('master', 'tempdb', 'model', 'msdb')
    AND     d.Name NOT LIKE 'ReportServer$%'
    GROUP BY d.Name;


OPEN FileCursor;
FETCH NEXT FROM FileCursor INTO @DBName, @DataFile, @LogFile;

WHILE @@FETCH_STATUS = 0
BEGIN

    SET @SQL = '
        USE ' + QUOTENAME(@DBName) + ';
        ALTER DATABASE ' + QUOTENAME(@DBName) + ' SET RECOVERY SIMPLE;

        BACKUP DATABASE ' + QUOTENAME(@DBName) + ' TO DISK = ''' + @BackupLocation + 
            + @DBName + '_' + CONVERT(VARCHAR(8), GETDATE(), 112) + '.bak'';

        ALTER DATABASE ' + QUOTENAME(@DBName) + ' SET RECOVERY FULL;

        BACKUP LOG ' + QUOTENAME(@DBName) + ' TO DISK = ''' + @BackupLocation + 
            + @DBName + '_' + CONVERT(VARCHAR(8), GETDATE(), 112) + '.log.bak'';

        DBCC SHRINKFILE(' + @DataFile + ', TRUNCATEONLY);
        DBCC SHRINKFILE(' + @LogFile + ', TRUNCATEONLY);';

    EXECUTE sp_executesql @SQL;

    FETCH NEXT FROM FileCursor INTO @DBName, @DataFile, @LogFile;
END

CLOSE FileCursor;
DEALLOCATE FileCursor;

这为每个数据库生成并执行如下命令:

USE [TestDB];
ALTER DATABASE [TestDB] SET RECOVERY SIMPLE;

BACKUP DATABASE [TestDB] TO DISK = 'I:\SQL Databases\Backup\TestDB_20141119.bak';

ALTER DATABASE [TestDB] SET RECOVERY FULL;

BACKUP LOG [TestDB] TO DISK = 'I:\SQL Databases\Backup\TestDB_20141119.log.bak';

DBCC SHRINKFILE(TestDB, TRUNCATEONLY);
DBCC SHRINKFILE(TestDB_log, TRUNCATEONLY);