마스터 데이터베이스에 기록 된 데이터베이스 소유자 SID가 데이터베이스 소유자 SID와 다릅니다.


87

기존 데이터베이스에 tSQLt를 설치하려고하면 다음 오류가 발생합니다.

master 데이터베이스에 기록 된 데이터베이스 소유자 SID가 ''데이터베이스에 기록 된 데이터베이스 소유자 SID와 다릅니다. ALTER AUTHORIZATION 문을 사용하여 ''데이터베이스의 소유자를 재설정하여이 상황을 수정해야합니다.

답변:


143

이 문제는 백업에서 복원 된 데이터베이스와 데이터베이스 소유자의 SID가 마스터 데이터베이스에 나열된 소유자 SID와 일치하지 않을 때 발생할 수 있습니다. 다음은 오류 메시지에서 권장되는 "ALTER AUTHORIZATION"문을 사용하는 솔루션입니다.

DECLARE @Command VARCHAR(MAX) = 'ALTER AUTHORIZATION ON DATABASE::[<<DatabaseName>>] TO 
[<<LoginName>>]' 

SELECT @Command = REPLACE(REPLACE(@Command 
            , '<<DatabaseName>>', SD.Name)
            , '<<LoginName>>', SL.Name)
FROM master..sysdatabases SD 
JOIN master..syslogins SL ON  SD.SID = SL.SID
WHERE  SD.Name = DB_NAME()

PRINT @Command
EXEC(@Command)

감사! 그게 더 적절 해 보입니다. 문자열에 '['를 넣는 대신 quotename ()을 사용하는 것이 가치가 없다고 생각하십니까? 또한 var DBName 및 var LoginName을 선택한 다음 REPLACE ()를 사용하는 대신 var Command에 함께 넣을 수 있습니까?
JDPeckham

3
DB 이름에 공백이나 '-'와 같은 특수 문자가 있으면이 스크립트에서 오류가 발생합니다. 따라서 [] 대괄호를 다음과 같이 넣으십시오. 'ALTER AUTHORIZATION ON DATABASE :: [<< DatabaseName >>] TO [<< LoginName >>]'
buhtla

10
이 작업을 실행하면 "제안 된 새 데이터베이스 소유자가 이미 사용자이거나 데이터베이스에서 별칭이 지정되었습니다"라는 오류 메시지가 나타납니다.
MobileMon

이 스크립트의 경우 SID 불일치 문제 이기 때문에 syslogins에 대한 내부 조인이 작동하지 않습니다 .
crokusek

31

이것을 tSQLt.class.sql 스크립트의 맨 위에 추가했습니다.

declare @user varchar(50)
SELECT  @user = quotename(SL.Name)
  FROM  master..sysdatabases SD inner join master..syslogins SL
    on  SD.SID = SL.SID
 Where  SD.Name = DB_NAME()
exec('exec sp_changedbowner ' + @user)

이것은 매력처럼 작동했으며 tSQLt Version: 1.0.5873.27393더 간단한 해결책으로 보입니다. MS SQL Server 2019 Developer 및 SSMS 18 사용.
silver

19

데이터베이스에 아래 스크립트를 적용하면 오류가 발생합니다.

EXEC sp_changedbowner 'sa'

ALTER DATABASE [database_name] SET TRUSTWORTHY ON 

1
두 번째 문장의 경우 다음과 같은 보안 취약점 : VA1102 - 신뢰할 수있는 비트가 MSDB를 제외한 모든 데이터베이스에 사용하지 않아야합니다
샤디 Namrouti

5

Necromaning :
SQL-Server 2000보기 (더 이상 사용되지 않음)를 사용하지 않으려면 다음을 사용하십시오.

-- Restore sid when db restored from backup... 
DECLARE @Command NVARCHAR(MAX) 
SET @Command = N'ALTER AUTHORIZATION ON DATABASE::<<DatabaseName>> TO <<LoginName>>' 
SELECT @Command = REPLACE 
                  ( 
                      REPLACE(@Command, N'<<DatabaseName>>', QUOTENAME(SD.Name)) 
                      , N'<<LoginName>>' 
                      ,
                      QUOTENAME
                      (
                          COALESCE
                          (
                               SL.name 
                              ,(SELECT TOP 1 name FROM sys.server_principals WHERE type_desc = 'SQL_LOGIN' AND is_disabled = 'false' ORDER BY principal_id ASC )
                          )
                      )
                  ) 
FROM sys.databases AS SD
LEFT JOIN sys.server_principals  AS SL 
    ON SL.SID = SD.owner_sid 


WHERE SD.Name = DB_NAME() 

PRINT @command 
EXECUTE(@command) 
GO

또한 이상한 이름의 데이터베이스 또는 사용자에 대한 버그를 방지하고 연결된 사용자가없는 경우 버그를 수정합니다 (sa 로그인 사용).


4

DB 소유자를 변경하는 가장 간단한 방법은 다음과 같습니다.

EXEC SP_ChangeDBOwner 'sa'

예, 우리는 그것을 확립했습니다.
JDPeckham
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.