El SID del propietario de la base de datos registrado en la base de datos maestra difiere del SID del propietario de la base de datos.

86

Cuando intento instalar tSQLt en una base de datos existente, aparece el siguiente error:

El SID del propietario de la base de datos registrado en la base de datos maestra difiere del SID del propietario de la base de datos registrado en la base de datos ''. Debe corregir esta situación restableciendo el propietario de la base de datos '' mediante la instrucción ALTER AUTHORIZATION.

JDPeckham
fuente

Respuestas:

141

Este problema puede surgir cuando una base de datos restaurada a partir de una copia de seguridad y el SID del propietario de la base de datos no coincide con el SID del propietario que figura en la base de datos maestra. A continuación, se muestra una solución que utiliza la declaración "ALTER AUTHORIZATION" recomendada en el mensaje de error:

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
fuente
¡Gracias! Eso parece más apropiado. ¿Crees que no vale la pena usar quotename () en lugar de poner '[' en la cadena? ¿También tal vez seleccionar en var DBName y var LoginName y luego juntarlos en var Command en lugar de usar REPLACE ()?
JDPeckham
3
Si tiene espacios o caracteres especiales como '-' en el nombre de su base de datos, este script le dará un error. Así que ponga [] corchetes como este: 'ALTER AUTORIZATION ON DATABASE :: [<<DatabaseName>>] TO [<<LoginName>>]'
buhtla
9
Cuando ejecuto esto, aparece el error "El nuevo propietario de la base de datos propuesto ya es un usuario o tiene un alias en la base de datos"
MobileMon
Para este script, la unión interna a syslogins no me funciona probablemente porque el problema es la falta de coincidencia de SID .
crokusek
31

Se agregó esto a la parte superior del 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
fuente
Esto funcionó de maravilla con tSQLt Version: 1.0.5873.27393y parece ser una solución más simple. Usando MS SQL Server 2019 Developer y SSMS 18.
plata
19

Aplique el siguiente script en la base de datos y obtendrá el error:

EXEC sp_changedbowner 'sa'

ALTER DATABASE [database_name] SET TRUSTWORTHY ON 
NarendraMishra
fuente
La segunda declaración presenta la siguiente vulnerabilidad de seguridad: VA1102: el bit confiable debe desactivarse en todas las bases de datos excepto en MSDB
Shadi Namrouti
5

Necromaning:
si no desea utilizar las vistas de SQL-Server 2000 (obsoletas), utilice esto:

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

También previene errores en bases de datos o usuarios con nombres extraños, y también corrige errores si no hay ningún usuario asociado (usa sa login)

Stefan Steiger
fuente
3

La forma más sencilla de cambiar el propietario de la base de datos es:

EXEC SP_ChangeDBOwner 'sa'
Shadi Namrouti
fuente
Sí, lo hemos establecido.
JDPeckham
0

También encontré este problema y descubrí que el propietario de la base de datos de destino no existía en la base de datos maestra. La asignación de ese usuario a la base de datos maestra resolvió el problema para mí.

Rolan
fuente
La asignación al maestro no cambia el propietario. Debe ejecutar lo siguiente después del mapeo: EXEC sp_changedbowner 'TheOwnerName'
Shadi Namrouti