我有一些我继承的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
答案 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
中可以看到的文件。
请看以下屏幕截图:
您可以看到在连接到其他数据库(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);