O SID do proprietário do banco de dados registrado no banco de dados mestre difere do SID do proprietário do banco de dados

86

Quando tento instalar o tSQLt em um banco de dados existente, recebo o seguinte erro:

O SID do proprietário do banco de dados registrado no banco de dados mestre difere do SID do proprietário do banco de dados registrado no banco de dados ''. Você deve corrigir esta situação redefinindo o proprietário do banco de dados '' usando a instrução ALTER AUTHORIZATION.

JDPeckham
fonte

Respostas:

141

Esse problema pode surgir quando um banco de dados restaurado de um backup e o SID do proprietário do banco de dados não corresponde ao SID do proprietário listado no banco de dados mestre. Aqui está uma solução que usa a instrução "ALTER AUTHORIZATION" recomendada na mensagem de erro:

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
fonte
Obrigado! Isso parece mais apropriado. Você acha que não vale a pena usar quotename () em vez de colocar '[' na string? Também pode selecionar em var DBName e var LoginName e, em seguida, colocá-los juntos em var Command em vez de usar REPLACE ()?
JDPeckham
3
Se você tiver espaços ou caracteres especiais como '-' no nome do seu banco de dados, este script apresentará um erro. Portanto, basta colocar [] colchetes como este: 'ALTER AUTHORIZATION ON DATABASE :: [<<DatabaseName>>] TO [<<LoginName>>]'
buhtla
9
Quando eu executo isso, obtenho o erro "O novo proprietário do banco de dados proposto já é um usuário ou um alias no banco de dados"
MobileMon
Para este script, a junção interna com syslogins não funciona para mim, provavelmente porque a incompatibilidade de SID é o problema.
crokusek
31

Adicionado ao topo do script 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
fonte
Isso funcionou perfeitamente tSQLt Version: 1.0.5873.27393e parece ser uma solução mais simples. Usando o MS SQL Server 2019 Developer e SSMS 18.
prata
19

Aplique o script abaixo no banco de dados e obtenha o erro:

EXEC sp_changedbowner 'sa'

ALTER DATABASE [database_name] SET TRUSTWORTHY ON 
NarendraMishra
fonte
A segunda instrução casos a seguinte vulnerabilidade de segurança: VA1102 - O bit confiável deve ser desativado em todos os bancos de dados, exceto MSDB
Shadi Namrouti
5

Necromaning:
se você não quiser usar as visualizações do SQL-Server 2000 (obsoletas), use:

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

Também evita bug em banco de dados ou usuário com nome estranho, e também corrige bug se nenhum usuário estiver associado (usa login sa).

Stefan Steiger
fonte
3

A maneira mais simples de alterar o proprietário do banco de dados é:

EXEC SP_ChangeDBOwner 'sa'
Shadi Namrouti
fonte
Sim, nós estabelecemos isso.
JDPeckham
0

Também encontrei esse problema e descobri que o proprietário do banco de dados de destino não existia no banco de dados mestre. O mapeamento desse usuário para o banco de dados mestre resolveu o problema para mim.

Rolan
fonte
O mapeamento para mestre não altera o proprietário. Você deve executar o seguinte após o mapeamento: EXEC sp_changedbowner 'TheOwnerName'
Shadi Namrouti