Hola, chicos,
¡Buenas tardes!

En esta publicación, demostraré cómo resolver un problema común en el desarrollo de bibliotecas CLR que ocurre cuando restaura una base de datos CLR desde otro servidor. Aunque la solución no es muy sencilla, cuando te encuentras con este problema por primera vez, puede que te lleve un tiempo resolverlo.

Identificar el problema y comprender por qué sucede.

Después de restaurar la base de datos CLR en el servidor de destino, al intentar ejecutar cualquier procedimiento o función, aparece el siguiente mensaje de 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 'CLR'. Debe corregir esta situación restableciendo el propietario de la base de datos 'CLR' mediante la instrucción ALTER AUTHORIZATION.

Este error puede ocurrir cuando el SID del propietario de esta base de datos restaurada no está presente en la lista de propietarios de la base de datos maestra de su instancia.

La solución es muy simple y simplemente restablecer el propietario de la base de datos restaurada (puede cambiarla a otro propietario y volver al propietario con el mismo nombre que existe en la instancia). Esto se puede hacer a través de la interfaz de SQL Server Management Studio, usando sp master.dbo.sp_chagedbowner o con el comando ALTER AUTHORIZATION.

Cambiar el propietario a través de la interfaz de SQL Server Management Studio

Para cambiar el propietario de la base de datos, simplemente haga clic derecho en la base de datos en la pantalla "Explorador de objetos" y seleccione la opción "Propiedades". Después de eso, seleccione el menú "Archivos" y luego podrá cambiar el propietario del banco y confirmar.

SQL Server - Change DB Owner
SQL Server: cambiar el propietario de la base de datos

Cambiando el propietario con sp_changedbowner

Una forma de cambiar el propietario usando T-SQL es usar el procedimiento sp_changedbowner, disponible desde la versión 2008 a 2014 y está marcado como obsoleto en versiones futuras de SQL Server.

Ejemplo:

USE [CLR]
GO
 
ALTER DATABASE [CLR] SET TRUSTWORTHY ON
GO
 
EXEC dbo.sp_changedbowner 'usuario'
GO

Restaurar el SID de la base de datos automáticamente:

USE [CLR]
GO

DECLARE 
    @Comando VARCHAR(MAX)

SELECT
    @Comando = 'EXEC dbo.sp_changedbowner ' + QUOTENAME(B.name)
FROM
    sys.databases                       A
    JOIN sys.server_principals          B	ON	B.sid = A.owner_sid
WHERE
    A.name = DB_NAME()


PRINT @Comando
EXEC(@Comando)

Cambiar de propietario con ALTERAR AUTORIZACIÓN

Otra forma de cambiar el propietario de una base de datos en SQL Server a través de T-SQL es usar el comando ALTER AUTHORIZATION en la base de datos de destino, como se muestra en el siguiente ejemplo.

La ventaja de esta solución para usar sp_changedbowner es que el comando ALTER AUTHORIZATION está disponible desde la versión 2008 (al igual que SP), pero no está marcado como obsoleto, es decir, estará disponible en futuras versiones de SQL Server.

Ejemplo:

USE [CLR]
GO
 
ALTER DATABASE [CLR] SET TRUSTWORTHY ON
GO
 
ALTER AUTHORIZATION ON DATABASE::[CLR] TO [usuario]
GO

Restaurar el SID de la base de datos automáticamente:

USE [CLR]
GO

DECLARE 
    @Comando VARCHAR(MAX) = 'ALTER AUTHORIZATION ON DATABASE::<<DatabaseName>> TO <<LoginName>>',
    @Usuario VARCHAR(MAX) = ( SELECT TOP 1 name FROM sys.server_principals WHERE type_desc = 'SQL_LOGIN' AND is_disabled = 'false' ORDER BY principal_id ASC)

SELECT 
    @Comando = REPLACE(REPLACE(@Comando, '<<DatabaseName>>', QUOTENAME(A.name)), '<<LoginName>>', QUOTENAME(COALESCE(B.name, @Usuario)))
FROM
    sys.databases                               A
    LEFT JOIN sys.server_principals             B	ON	B.sid = A.owner_sid
WHERE
    A.name = DB_NAME()

PRINT @Comando 
EXEC(@Comando) 

Eso es todo, amigos. Después de adoptar una de las soluciones enumeradas anteriormente, sus rutinas y funciones en la base de datos CLR restaurada ahora funcionan correctamente.

Si tienes alguna pregunta, déjala en los comentarios.
¡Abrazo!