My goal is getting list of SQL server databases which files have been deleted. In other words. I attach a db from mount, then close the mount so actually I have the attached db without files.
At first it seemed to be easy. Just pretty easy select:
SELECT 'DB_NAME' = db.name, 'FILE_NAME' = mf.name, 'FILE_TYPE' = mf.type_desc, 'FILE_PATH' = mf.physical_name FROM sys.databases db INNER JOIN sys.master_files mf ON db.database_id = mf.database_id WHERE --and specific condition here
But it turned out differently. Sql server has almost the same information about a regular database and a database which doesn’t have files. So I had to try something else.
Further I tried to use state
of database. And it was quite strange.
Unfortunately the following query
gives me wrong(or not actual information):
SELECT state FROM sys.databases WHERE name = N'TestDB' state ----- 0
And 0
means ONLINE
according to this link
But actually the database has RECOVERY_PENDING
state. It looks like that sql server information about my TestDB
us out of date and should be refreshed. But I have no idea how to achieve this. But after executing any of following query this info(db state
) is being refreshed:
EXEC sp_helpdb N'TestDB' ALTER DATABASE N'TestDB' SET SINGLE_USER WITH ROLLBACK IMMEDIATE USE N'TestDB' --etc --all requests are terminated with the same error Msg 5120, Level 16, State 101, Line 10 Unable to open the physical file "C:MOUNTb4c059e8-3ba6-425f-9a2a-f1713e7719caTestDB.mdf". Operating system error 3: "3(The system cannot find the path specified.)". File activation failure. The physical file name "C:MOUNTb4c059e8-3ba6-425f-9a2a-f1713e7719caTestDB_log.ldf" may be incorrect. File activation failure. The physical file name "C:MOUNTb4c059e8-3ba6-425f-9a2a-f1713e7719caTestDB_log-2.ldf" may be incorrect. Msg 5181, Level 16, State 5, Line 10 Could not restart database "TestDB". Reverting to the previous status. Msg 5069, Level 16, State 1, Line 10 ALTER DATABASE statement failed.
So do you have any idea ? And also I’ve asked the question looks like this here differently.
Advertisement
Answer
Finally, I’ve found what i actually need. I can chech whether the specific file exists or not by sql server:
CREATE FUNCTION dbo.fn_FileExists(@path varchar(512)) RETURNS BIT AS BEGIN DECLARE @result INT EXEC master.dbo.xp_fileexist @path, @result OUTPUT RETURN cast(@result as bit) END; GO
So i just need to execute the function above for each file which i can get by executing for example following query:
SELECT DISTINCT 'FILE_PATH' = physical_name FROM sys.master_files