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.

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)

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)

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 

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


3

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

EXEC SP_ChangeDBOwner 'sa'

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.


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.