A integração do SQL Server com o .NET framework é uma das principais características implementadas no SQL Server para ajudar os desenvolvedores que podem mover seus códigos .NET para mais perto do banco de dados usando CLR – CLR significa Common Language Runtime.
O CLR proporciona um ambiente otimizado para o processamento de tarefas de uso intenso que podem ser executados na camada de SQL Server da arquitetura do seu software.
Os DBAs possuem a necessidade de um forte conhecimento de CLR para auxiliá-los na tomada de decisões no momento do desenvolvimento da solução. Mas se o DBA ignorar o CLR, vai estar perdendo uma parte significante do potencial que o SQL Server pode oferecer aos seus projetos, limitando assim a sua eficácia com o produto.
CLR é um tópico muito debatido nas comunidades técnicas, mas também é frequentemente mal interpretado, pois os desenvolvedores costumam falar que o CLR é uma caixa preta e adiciona mais trabalho na escrita de códigos.
Inquestionavelmente, haverá trabalho adicional para escrever código CLR, mas esse trabalho será recompensado com um acréscimo nas opções de desenvolvimento.
O que é SQLCLR?
SQLCLR é um recurso presente no SQL Server desde a versão 2005 e que permite inserir lógica escrita em C# e Vb.Net para ser utilizado pelo Transact-SQL em objetos como stored procedures, funções, triggers, agregações e tipos definidos pelo usuario. As aplicações-cliente interagem com essas rotinas como se elas estivessem escritas em SQL nativo.
Internamente, o código como seqüência de manipulações e cálculos complexos tornam-se mais fácil de programar, porque você não está restrito a usar somente Transact-SQL e agora têm acesso a estruturada .Net para poder expandir seus códigos.
Externamente, a lógica de criar é envolta em protótipos Transact-SQL para que o aplicativo cliente não tenha conhecimento dos detalhes da aplicação. Isto é vantajoso, pois você pode empregar CLR onde você precisa de verdade, sem refazer seu código de cliente existente. Com o CLR voce também está livre da restrição da lógica que se aplica somente dentro do contexto do banco de dados; no código Transact-SQL.
Você pode escrever, desde que tenha as permissões adequadas, a lógica para ler e gravar em sistemas de arquivos, lógica de utilização confinada em objetos COM ou DLLs, ou mesmo um resultado de processos de Web Services.
Uma vantagem que algumas empresas de desenvolvimento de software utilizam, é após criar o assembly no SQL Server, apagar a DLL original pois não se faz mais necessário a sua existencia no servidor SQL Server. Ou seja, após a criação do assembly a DLL se torna inútil para todo o processo do CLR ser executado no SQL Server. Esta é uma grande vantagem em relação à sistemas legados que utilizavam o acesso à DLL para executar seus processos (principalmente para validar se a instalação estava dentro do contrato de licenciamento, por exemplo).
Quais são os objetivos do CLR?
Os arquitetos do time de integração do CLR com o SQL Server tiveram alguns objetivos para esta funcionalidade:
1) Confiabilidade: O código gerenciado escrito por um desenvolvedor não deve ser capaz de comprometer o servidor SQL Server que está hospedando o codigo.
2) Escalabilidade: O código gerenciado não deve parar o SQL Server a partir do suporte de milhares de sessôes concorrentes do usuário, o qual foi projetado para suportar a demanda.
3) Segurança: O mesmo código gerenciado deve aderir as práticas de segurança padrão do SQL Server e também as suas permissões. Os administradores deverão ser capaz de controlar os tipos de recursos que os Assemblies CLR podem acessar.
4) Performance: O código gerenciado a ser hospedado no SQL Server deve ser executado tão rapidamente como se ele estivesse sendo executado através de uma aplicação fora do SQL Server.
Objetos suportados pelo CLR no SQL Server:
Um desenvolvedor pode criar código CLR para manipular os seguintes objetos do SQL Server:
1) Stored procedures
2) Triggers
3) User-defined Functions (UDF)
4) User-defined aggregates (UDA)
5) User-defined types (UDT)
Modelo de Segurança:
O modelo de segurança do SQLCLR é chamado de segurança de acesso ao código ou CAS do ingles “code access security”. O principal objetivo do CAS é evitar que código não-autenticado realize tarefas que devem exigir autenticação prévia. O CLR identifica código e seus grupos de código relacionado como “workloads” em tempo de execução. O grupo de códigos é a entidade que auxilia o CLR em associar um assembly com o conjunto de permissões. Este conjunto de permissões detemina quais ações são permitidas para serem executadas no código.
Conjunto de permissões são atribuidas pelo administrador do servidor em que o SQL Server está sendo executado.Vamos ver, rapidamente, o conjunto de permissões CAS:
Quando o desenvolvedor cria os assemblies no SQL Server, ele deve atribuir um conjunto de permissões. Essas permissões determinam quais ações correspondentes o assembly pode realizar. Existem 3 permissões-padrão que voce pode atribuir aos seus assemblies quando está carregando-os no SQL Server:
SAFE – Indica que o acesso local é permitido e seguro.
EXTERNAL_ACCESS – Esta permissão vai herdar todas as permissões atribuidas pelo SAFE mais as permissões para acessar arquivos no file system, acesso as redes e ao registro além das variaveis de ambiente. Ou seja, além do acesso interno ao SQL Server, com esta permissão o codigo poderá fazer acesso ao registry ou file system, por exemplo.
UNSAFE – é o mesmo que o EXTERNAL_ACCESS sem algumas das suas restrições e inclui a capacidade para executar código não gerenciado. Ou seja, é o menos seguro das 3 permissões.
Qual a melhor opção: Usar CLR ou Transact-SQL?
Uma pergunta bastante frequente: Quando devo implementar CLR ou Transact-SQL? O CLR não é um substituto para o Transact-SQL; ele o complementa.
Algumas diferenças básicas entre os dois modelos: o código CLR é compilado no modelo SQLCLR e interpretado no Transact-SQL. Uma grande vantagem quando se utiliza o CLR é que este acessa diretamente as bibliotecas de classes do .NET Framework. Sendo assim, em determinadas situações do seu projeto, se voce deseja alta performance em calculos complexos, a melhor opção provavelmente será usar CLR.
Usando CLR ou eXtended-Stored Procedures?
As eXended-stored Procedures (ou XPs) são escritas em C/C++, e a partir daí são geradas APIs que produzem as DLLs que o SQL Server pode carregar, executar e descarregar em tempo de execução. As eXtended-stored Procedures são notórias por causar vasamentos de memória e comprometer a integridade dos processos do SQL Server. Além disso, todos já ouviram falar que a Microsoft pretende em versões futuras do SQL Server não suportar mais as eXtended-stored Procedures. Com isso, o CLR fornece uma alternativa segura de substituição as eXtended-stored Procedures desenvolvidas.
E o CLR na vida de um DBA? É uma boa opção? Vale a pena?
O DBA é normalmente muito cauteloso ao dar aos desenvolvedores a flexibilidade necessária para que estes realizem suas tarefas de desenvolvimento no banco de dados. Um pedaço de código mal escrito pode comprometer toda a instancia do SQL Server no qual ele esteja sendo executado.
Como mencionei anteriormente, uma eXtended-stored Procedure pode ser a causadora de problemas na instancia em que está sendo executada no SQL Server, e isto reforça a politica do DBA em dar permissões bastante restritivas aos Desenvolvedores; afinal o DBA é o responsavel por manter a boa performance e a segurança no SQL Server.
O CLR é desabilitado por padrão após a instalação do SQL Server, isto devido a estratégia da Microsoft chamada “secure by default”, ou traduzindo, segurança por padrão. Óbvio que manter o CLR desabilitado não é necessariamente uma opção ruim, mas caso seja necessário habilita-lo o DBA pode aplicar aos desenvolvedores as permissões de acesso via CAS que considero a melhor solução.
A partir do momento que o DBA aceita executar CLR em seu ambiente SQL Server, os desenvolvedores terão um ambiente seguro para desenvolver código CLR integrado com Transact-SQL e o mais importante, com as permissões corretas.
Passo-a-passo para criação e entrega de rotinas CLR:
Os procedimentos para criação, entrega e uso de uma rotina baseada em CLR no SQL Server é extremamente simples e segue uma ordem, vamos observar a figura abaixo e ir identificado cada etapa do processo:
1) Criar a classe publica usando linguagem .NET tendo pelo menos um método estatico e um ponto de entrada;
2) Compilar a classe gerando um arquivo .DLL;
3) Carregar o arquivo .DLL dentro do SQL Server de destino usando o comando CREATE ASSEMBLY;
4) No objeto do SQL Server que pode ser stored procedure, function, trigger, deve ser feita referencia ao assembly criado;
5) Feito isto, basta utilizar o objeto criado no SQL Server;
6) Opcionalmente, voce pode apagar a DLL pois a mesma não será mais utilizada pelo SQL Server.
Na essencia, um exemplo do funcionamento de uma estrutura com SQL CLR poderia ser a seguinte:
1) O desenvolvedor cria suas DLLs cujo conteudo podem ser a logica de negócios, exemplo validação do CPF e validação de e-mail. Essas DLLs são criadas em VB.NET ou Visual C# por exemplo;
2) O DBA cria o assembly especifico no banco de dados desejado;
3) O desenvolvedor, tendo as permissões adequadas, cria um stored procedure em T-SQL que fará a chamada a DLL especifica que contém a regra de negócios;
4) O DBA gerencia as permissões tanto para os desenvolvedores quanto para os usuários que estarão fazendo chamadas a stored procedure criada pelo desenvolvedor;
5) A aplicação executa a stored procedure armazenada no servidor SQL Server.
6) Para o usuário final todo o processo é transparente, não sabendo identificar identificar se o codigo encontra-se em stored procedure escrita em formato padrão do SQL Server (Transact-SQL) ou a Stored Procedure faz uma chamada ao CLR.
Vamos ver na prática todos os passos, desde a criação no Visual Studio 2008 até a execucação no SQL Server. Esta demonstração apresenta o uso de CLR através de um código VB.NET e tem como objetivo apagar backups do SQL Server anteriores a um determinado numero de dias. Primeiro, vamos observar na figura abaixo que existem diversos backups do SQL Server que foram realizados (12 no total):
No Visual Studio…
1) O nosso primeiro passo, é no Visual Studio 2008 criar um novo projeto, Selecionar em “Project Types” -> Visual Basic;
2) clicar em “Class Library” para criar uma DLL, sem esquecer de selecionar o framework a ser utilizado (NET Framework 3.5);
3) Em “name” digitar “CLRapagabackups” e Ok;

4) Em “Solution Explorer” clicar em “CLRapagabackups” com o botão direito. Em seguida clicar em “Adicionar” e “Item Existente”. Vamos em “e:\projetos\CLR”, selecionar “CLRapagabackups.vb”. Agora basta clicar em “Adicionar”;
5) No “Solution Explorer” clicar com o botão direito em “class1.vb” e “Delete” + “Ok”;
6) Duplo clique em “CLRapagabackups”;
7) Observando o codigo, notamos uma classe publica "CLRFunctions" e uma função chamada "DeleteFiles" que recebe como parametros o caminho, quantos dias para trás devemos apagar os arquivos de backup e qual a extensão do arquivo de backup (ver figura abaixo):
8) No meio do código existe um For Each que fica em loop procurando os arquivos que satisfaçam os parametros que foram passados e aplica um delete nos arquivos;
9) Clicar em Save ALL;
10) Neste ponto vamos precisar gerar a DLL, clicando em “Build” + "Solution", podemos observar que na saida não tivemos nenhum erro… e a DLL foi gerada com sucesso;
11) Nosso trabalho com o Visual Studio acabou, vamos para o SQL Server….
No SQL Server Management Studio…
Com o SSMS aberto e estando no database "master", vamos precisar configurar o "master" com ALTER DATABASE model SET TRUSTWORTHY ON para que Os módulos de banco de dados (por exemplo, UDF ou Stored Procedures) que usam um contexto de representação possam acessar recursos fora do banco de dados.
Aproveitamos para verificar se está habilitado o CLR no servidor (o default é 0 – zero).
O valor encontra-se em 0, ou seja, está desabilitado… Para habilitar basta digitar a linha abaixo:
Agora, vamos criar o Assembly…
Criado o vinculo, vamos agora criar uma função:
Criada a função, vamos executa-la passando como parametros o diretorio aonde estão os arquivos de backup com mais de 5 dias de existencia e a extensão do arquivo de backup. Ou seja, no exemplo abaixo, ele irá manter os backups realizados nas ultimas 120 horas independente do numero de backups diarios existentes e apagará somente arquivos com extensão .BAK (default do SQL Server para arquivos de backup).
Resultado: 7 arquivos de backup com extensão .BAK foram apagados, vamos notar que outros arquivos mais antigos mas com extensão diferente foram mantidos, ou seja a regra “arquivos com extensão BAK com mais de 120 horas” foram excluidos; os demais mantidos intactos.
Abraços,
Alexandre Lopes