답변:
인스턴스에서 데이터베이스를 분리하면 파일의 OS 레벨 삭제를 수행해야합니다. 보다 안전한 방법은 대신 데이터베이스를 삭제하는 것입니다.
내가 제안하는 것은 데이터베이스를 읽기 전용 모드로 설정 한 후 (백업 중 활동이 발생하지 않도록 데이터베이스 를 삭제 한 후) 데이터베이스 삭제 명령 을 통해 데이터베이스를 최종 백업하는 것입니다 .
전체 명령 세트는 다음과 유사합니다.
-- Use master db to ensure you don't have an active connection to the db you wish to affect
USE [master]
GO
-- This will kill any active transactions, but will force the database into a Read-Only state
ALTER DATABASE [db_name] SET READ_ONLY WITH ROLLBACK IMMEDIATE
GO
BACKUP DATABASE [db_name] -- Fill in more options here or use the UI to take a backup if you chooose
GO
-- This will kick out all connections from the database allowing you to drop it.
ALTER DATABASE [db_name] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO
-- Drop the database (which automatically removes the files from the OS)
DROP DATABASE [db_name]
GO
그런 다음 데이터베이스에 대해 스크립트를 실행 한 작업을 찾으십시오. 작업이 데이터베이스를 참조 할 수있는 여러 가지 방법 (모두 식별하기 쉬운 것은 아님)이 있기 때문에 실패한 작업 (스크립트를 작성 / 삭제할 수 있음)을 기다리는 것이 좋습니다.
마지막으로이 데이터베이스에만 액세스 할 수있는 인스턴스에서 모든 사용자를 제거하려고합니다. Max의 버전이 훨씬 깨끗하지만이 스크립트는 해당 사용자를 식별해야합니다 (이를 포함하도록 내 답변을 편집 한 후에야 그가 접근 방식을 게시 한 것을 알지 못했습니다).
DECLARE @ExecString NVARCHAR (4000)
-- Create Empty Table in a very lazy manner
SELECT name, principal_id, CAST('' AS NVARCHAR(128)) as database_name
INTO ##tmp_AllDBUsers
FROM sys.server_principals
WHERE 1 = 2
-- Declare Cursor to iterate through all DBs on the instance
DECLARE dbCursor CURSOR
FOR
SELECT name
FROM sys .databases
DECLARE @name NVARCHAR (128)
OPEN dbCursor
FETCH NEXT FROM dbCursor
INTO @name
WHILE @@FETCH_STATUS = 0
BEGIN
SET @ExecString =
'USE [' + @name + '];
INSERT INTO ##tmp_AllDBUsers
SELECT sp.name, sp.principal_id, DB_NAME()
FROM sys.server_principals sp INNER JOIN sys.database_principals dp
ON sp.sid = dp.sid'
EXEC(@ExecString)
FETCH NEXT FROM dbCursor
INTO @name
END
-- Close and deallocate the cursor because you've finished traversing all it's data
CLOSE dbCursor
DEALLOCATE dbCursor
-- Show all logins that do not belong to a server-level role nor have access to any databases
SELECT sp.*
FROM sys.server_principals sp LEFT JOIN ##tmp_AllDBUsers adu
ON sp.principal_id = adu.principal_id
WHERE adu.principal_id IS NULL
AND sp.principal_id NOT IN (SELECT member_principal_id
FROM sys.server_role_members)
AND TYPE IN ('S', 'U', 'G')
-- cleanup
DROP TABLE ##tmp_AllDBUsers
나는 요한의 대답을 옹호했다. 정리하려는 다른 항목에 대한 세부 정보를 추가하고 싶습니다.
SQL Server 에이전트 작업 및 경고가 데이터베이스를 참조 할 수 있습니다. 정리하면 불필요한 오류가보고되지 않습니다.
데이터베이스를 위해 특별히 작성된 로그인을 제거하십시오. 다음 T-SQL은 사용중인 후보 로그인 을 조사 할 수 있는 가능한 후보 로그인 을 식별 합니다 . 이 코드는 데이터베이스에서 참조하지 않는 로그인을 식별합니다.
DECLARE @cmd nvarchar(max);
SET @cmd = ' SELECT sp.sid
FROM master.sys.server_principals sp
';
SELECT @cmd = @cmd + ' EXCEPT
SELECT dp.sid
FROM ' + QUOTENAME(d.name) + '.sys.database_principals dp
'
FROM sys.databases d
WHERE d.[state] <> 6; --ignore offline DBs
SET @cmd = 'SELECT spr.*
FROM (
' + @cmd + '
) src
INNER JOIN master.sys.server_principals spr
ON src.sid = spr.sid
WHERE spr.type <> ''R''
AND spr.name NOT LIKE ''%##MS_%''
AND spr.name NOT LIKE ''NT %''
AND NOT EXISTS (
SELECT 1
FROM sys.server_role_members srm
WHERE srm.member_principal_id = spr.principal_id
)
ORDER BY spr.name;
';
EXEC sys.sp_executesql @cmd;
해당 데이터베이스에 대한 백업 장치가있을 수 있습니다. 그것들을 제거하는 것이 꼭 필요한 것은 아니지만, 사용하지 않는다면 미래의 혼란을 제거해야합니다.
서버 수준 트리거는 데이터베이스를 참조 할 수 있습니다.
데이터베이스를 참조하는 유지 보수 계획을 찾으십시오. 누락 된 데이터베이스를 제거하도록 업데이트되지 않으면 실패합니다.
모든 주요 사항은 이미 다루었습니다. 아래는 내 2 센트입니다.
데이터베이스를 분리하는 것은 서버 내에서 또는 다른 서버로 데이터베이스 파일을 이동시키기 위해 사용되는 영구적 인 솔루션이 아닙니다. SSMS의 삭제 옵션 또는 위에서 언급 한 DROP 데이터베이스 명령으로 데이터베이스를 영구적으로 제거 할 수 있습니다.
일반적으로 의도적으로 오프라인 상태로 유지되고 경고를 계속 생성하는 데이터베이스는 영구적으로 제거 (삭제) 될 때까지 분리하여 보관하는 데이터베이스입니다.
사전 분리 작업 : sp_helpdb dbname
파일 위치를 알고 실행 합니다.
정리 작업 :
로그인, 상담원 작업, 트리거 및 Max에서 이미 언급 한 지점 이외에도이 2 개를 볼 수 있습니다.