OlĂ¡ pessoal,
Boa tarde!
Neste post vou demonstrar como resolver um problema comum no desenvolvimento de bibliotecas CLR que ocorre quando vocĂª faz o restore de um database CLR vindo de outro servidor. Apesar da soluĂ§Ă£o sem bem simples, quando se depara com esse problema pela primeira vez, vocĂª pode demorar um pouco para resolver.
Identificando o problema e entendendo porque isso acontece
ApĂ³s vocĂª realizar o restore do database CLR no servidor de destino, ao tentar executar qualquer procedure ou function, ocorre a seguinte mensagem de erro:
The database owner SID recorded in the master database differs from the database owner SID recorded in database ‘CLR’. You should correct this situation by resetting the owner of database ‘CLR’ using the ALTER AUTHORIZATION statement.
Esse erro pode ocorrer quando o SID do owner desse database restaurado nĂ£o estĂ¡ presente na lista de owners do database master da sua instĂ¢ncia.
A soluĂ§Ă£o Ă© bem simples e basta redefinir o owner do database restaurado (pode alterar para um outro owner e voltar pro owner de mesmo nome que existe na instĂ¢ncia). Isso pode ser feito pela interface do SQL Server Management Studio, utilizando a sp master.dbo.sp_chagedbowner ou com o comando ALTER AUTHORIZATION.
Alterando o owner pela interface do SQL Server Management Studio
Para alterar o owner do database, basta clicar com o botĂ£o direito sobre o database na tela “Object Explorer” e selecionar a opĂ§Ă£o “Properties”. ApĂ³s isso, selecione o menu “Files” e entĂ£o vocĂª poderĂ¡ alterar o owner do banco e confirmar.
Alterando o owner com o sp_changedbowner
Uma forma de alterar o owner utilizando T-SQL Ă© utilizando a procedure sp_changedbowner, disponĂvel da versĂ£o 2008 atĂ© a 2014 e estĂ¡ marcada como descontinuada em futuras versões do SQL Server.
Exemplo:
1 2 3 4 5 6 7 8 |
USE [CLR] GO ALTER DATABASE [CLR] SET TRUSTWORTHY ON GO EXEC dbo.sp_changedbowner 'usuario' GO |
Restaurando o SID do database de forma automĂ¡tica:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
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) |
Alterando o owner com o ALTER AUTHORIZATION
Uma outra forma de alterar o owner de um database no SQL Server via T-SQL Ă© utilizando o comando ALTER AUTHORIZATION no database de destino, conforme exemplo abaixo.
A vantagem dessa soluĂ§Ă£o para a utilizando a sp_changedbowner Ă© que o comando ALTER AUTHORIZATION estĂ¡ disponĂvel desde a versĂ£o 2008 (assim como a SP), mas nĂ£o estĂ¡ marcada como descontinuada, ou seja, estarĂ¡ disponĂvel em futuras versões do SQL Server.
Exemplo:
1 2 3 4 5 6 7 8 |
USE [CLR] GO ALTER DATABASE [CLR] SET TRUSTWORTHY ON GO ALTER AUTHORIZATION ON DATABASE::[CLR] TO [usuario] GO |
Restaurando o SID do database de forma automĂ¡tica:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
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) |
É isso aĂ, pessoal. ApĂ³s adotar uma das soluções listadas acima, suas rotinas e funções no database CLR restaurado jĂ¡ estĂ£o funcionando corretamente.
Qualquer dĂºvida, Ă© sĂ³ deixar nos comentĂ¡rios.
Abraço!