Identyfikator SID właściciela bazy danych zapisany w bazie danych master różni się od identyfikatora SID właściciela bazy danych

86

Kiedy próbuję zainstalować tSQLt w istniejącej bazie danych, pojawia się następujący błąd:

Identyfikator SID właściciela bazy danych zapisany w bazie danych master różni się od identyfikatora SID właściciela bazy danych zapisanego w bazie danych ''. Należy naprawić tę sytuację, resetując właściciela bazy danych „” za pomocą instrukcji ALTER AUTHORIZATION.

JDPeckham
źródło

Odpowiedzi:

141

Ten problem może wystąpić, gdy baza danych została przywrócona z kopii zapasowej, a identyfikator SID właściciela bazy danych nie jest zgodny z identyfikatorem SID właściciela wymienionym w głównej bazie danych. Oto rozwiązanie, które używa instrukcji „ALTER AUTHORIZATION” zalecanej w komunikacie o błędzie:

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)
JohnnyM
źródło
Dzięki! To wydaje się bardziej odpowiednie. Czy uważasz, że nie warto używać cudzysłowu () zamiast umieszczać „[” w ciągu? Może też wybierając var DBName i var LoginName, a następnie łącząc je w var Command zamiast używać REPLACE ()?
JDPeckham
3
Jeśli masz spacje lub znaki specjalne, takie jak „-” w nazwie bazy danych, ten skrypt wyświetli błąd. Więc po prostu umieść [] nawiasy w ten sposób: „ZMIEŃ AUTORYZACJĘ W BAZIE DANYCH :: [<<Nazwa Bazy Danych>>] DO [<<NazwaLogin>>]”
buhtla
9
Kiedy to uruchamiam, pojawia się błąd „Proponowany nowy właściciel bazy danych jest już użytkownikiem lub ma alias w bazie danych”
MobileMon
W przypadku tego skryptu wewnętrzne sprzężenie z syslogins nie działa dla mnie prawdopodobnie dlatego, że problemem jest niezgodność identyfikatora SID .
crokusek
31

Dodano to na początku skryptu 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)
JDPeckham
źródło
To działało jak urok z tSQLt Version: 1.0.5873.27393prostszym rozwiązaniem i wydaje się, że jest prostszym rozwiązaniem. Korzystanie z MS SQL Server 2019 Developer i SSMS 18
srebrny
19

Zastosuj poniższy skrypt do bazy danych, a otrzymasz błąd:

EXEC sp_changedbowner 'sa'

ALTER DATABASE [database_name] SET TRUSTWORTHY ON 
NarendraMishra
źródło
Drugie stwierdzenie dotyczy następującej luki w zabezpieczeniach: VA1102 - Bit Godny zaufania powinien być wyłączony we wszystkich bazach danych z wyjątkiem MSDB
Shadi Namrouti
5

Nekromancja:
Jeśli nie chcesz używać widoków SQL-Server 2000 (przestarzałe), użyj tego:

-- 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

Zapobiega również błędom w dziwnie nazwanej bazie danych lub użytkowniku, a także naprawia błąd, jeśli żaden użytkownik nie jest powiązany (używa loginu sa).

Stefan Steiger
źródło
3

Najprostszym sposobem zmiany właściciela bazy danych jest:

EXEC SP_ChangeDBOwner 'sa'
Shadi Namrouti
źródło
Tak, ustaliliśmy to.
JDPeckham,
0

Natknąłem się również na ten problem i stwierdziłem, że właściciel docelowej bazy danych nie istnieje w głównej bazie danych. Odwzorowanie tego użytkownika na główną bazę danych rozwiązało problem.

Rolan
źródło
Mapowanie do wzorca nie zmienia właściciela. Po zmapowaniu należy uruchomić następujące polecenie: EXEC sp_changedbowner 'TheOwnerName'
Shadi Namrouti,