Os procedimentos armazenados CLR são preferidos aos procedimentos armazenados TSQL no SQL 2005+?

StackOverflow https://stackoverflow.com/questions/58190

  •  09-06-2019
  •  | 
  •  

Pergunta

Minha visão atual é não, prefira os procedimentos armazenados do Transact SQL porque eles são uma opção mais leve e (possivelmente) de maior desempenho, enquanto os procedimentos CLR permitem que os desenvolvedores façam todo tipo de travessuras.

No entanto, recentemente precisei depurar alguns processos armazenados em TSQL muito mal escritos.Como de costume, encontrei muitos dos problemas devido ao desenvolvedor original não ter nenhuma experiência real em TSQL, eles eram focados em ASP.NET/C#.

Portanto, o uso de procedimentos CLR forneceria, em primeiro lugar, um conjunto de ferramentas muito mais familiar para esse tipo de desenvolvedor e, em segundo lugar, os recursos de depuração e teste seriam mais poderosos (ou seja, Visual Studio em vez de SQL Management Studio).

Eu estaria muito interessado em ouvir sua experiência, pois parece que não é uma escolha simples.

Foi útil?

Solução

Existem lugares para T-SQL e CLR bem escritos e bem pensados.Se alguma função não for chamada com frequência e exigir procedimentos estendidos no SQL Server 2000, o CLR pode ser uma opção.Também executar coisas como cálculos ao lado dos dados pode ser atraente.Mas resolver os maus programadores introduzindo novas tecnologias parece uma má ideia.

Outras dicas

Os procedimentos armazenados CLR não se destinam a substituir consultas baseadas em conjuntos.Se precisar consultar o banco de dados, você ainda precisará colocar SQL em seu código CLR, como se estivesse incorporado em código normal.Isso seria um desperdício de esforço.

Os procedimentos armazenados CLR servem para duas coisas principais:1) interação com o SO, como ler um arquivo ou descartar uma mensagem no MSMQ, e 2) realizar cálculos complexos, principalmente quando você já tem o código escrito em linguagem .NET para fazer o cálculo.

Hospedar o CLR no SQL Server tem como objetivo oferecer aos desenvolvedores de banco de dados opções mais flexíveis na forma como procuravam realizar as tarefas.Como outros mencionaram, SQL é ótimo para operações e modificações em conjuntos de dados.Qualquer pessoa que tenha feito um desenvolvimento extensivo de grandes aplicativos com regras complexas de negócios/domínio provavelmente diria a você - tentar impor algumas dessas regras usando SQL puro (algumas vezes em uma única consulta de macro) pode ser realmente um pesadelo.

Existem apenas algumas tarefas que são melhor tratadas de maneira processual ou OO.Ao ter a opção de usar o código .NET para quebrar a sequência de lógica, as operações de consulta podem ficar mais fáceis de ler e depurar.Tendo usado procs armazenados CLR, posso dizer que percorrer o depurador realmente torna mais fácil acompanhar o que está acontecendo no nível do banco de dados.

Apenas um exemplo: frequentemente usamos procs armazenados em CLR aqui como um "gateway" para consultas de pesquisa dinâmicas.Digamos que uma solicitação de pesquisa possa ter até 30 parâmetros de pesquisa diferentes.Os usuários obviamente não usam todos os 30, então a estrutura de dados passada terá 30 parâmetros, mas principalmente DBNULL.O lado do cliente tem nenhuma opção para gerar uma declaração dinâmica, por razões óbvias de segurança.A declaração dinâmica resultante é gerada internamente sem medo de "extras" externos.

Em geral você usa o CLR se tiver algo que não precisa fazer muita interface com o banco de dados.Digamos que você esteja analisando ou decodificando um valor.Isso é mais fácil de fazer no CLR e depois retornar o valor.

Tentar fazer uma consulta complexa no CLR simplesmente não é o caminho a percorrer.

Aliás, isso também não mudou em 2008.

Acredito que esses dois não sejam equivalentes...aptos para se enfrentarem.
A integração CLR deve eliminar gradualmente os "procedimentos armazenados estendidos" de antigamente. Temos alguns desses em nosso local de trabalho...essencialmente blocos de processamento/lógica sobre dados SQL que eram muito difíceis/impossíveis de serem executados por meio de procedimentos armazenados de banco de dados convencionais/T SQL.Então eles escreveram isso como procedimentos armazenados estendidos em DLLs C++ que podem ser invocados de forma semelhante.Agora eles foram eliminados e a integração do CLR é o substituto

  • Procedimentos armazenados do banco de dados:se isso puder ser feito em procs armazenados em T SQL, faça-o.
  • Procedimentos armazenados CLR:se a lógica for muito complexa ou tediosa para ser feita via T SQL...se for algo que exigirá menos linhas de código CLR para lidar com isso (manipulação de strings, classificação ou filtragem complexa/personalizada, etc.), use esta abordagem.

Além do acesso ao sistema de arquivos (onde os procs CLR têm uma vantagem muito pronunciada), eu usaria os procs T-SQL.Se você tiver cálculos especialmente complexos, poderá colocar essa parte em um CLR função e chame isso de dentro do seu processo (udf é onde descobri que a integração do CLR realmente brilha).Então você obtém os benefícios da integração CLR para essa parte específica de sua tarefa, mas mantém o máximo possível de sua lógica proc armazenada no banco de dados.

Dado o que você disse, prefiro que os desenvolvedores sejam devidamente treinados em t-SQl e bancos de dados em geral do que permitir que eles criem possivelmente muito mais danos ao desempenho, permitindo que executem tarefas t-sql em CLRs.Os desenvolvedores que não entendem de bancos de dados usam isso como desculpa para evitar fazer as coisas da maneira que é melhor para o desempenho do banco de dados, porque desejam seguir o que consideram o caminho mais fácil.

Sempre se trata da ferramenta certa para o trabalho, então realmente depende do que você está tentando realizar.

No entanto, como regra geral, você está certo ao dizer que os procs CLR têm uma sobrecarga maior e nunca serão executados em operações definidas como o T-SQL.Minha diretriz é fazer tudo em T-SQL, a menos que o que você precisa se torne muito complicado em T-SQL.Em seguida, tente mais fazer com que a abordagem T-SQL funcione.:-)

Os procs CLR são ótimos e têm seu lugar, mas seu uso deve ser a exceção, não a regra.

Os Manuais Online do SQL Server página sobre o assunto lista estes benefícios:

  • Um modelo de programação melhor. As linguagens .NET Framework são, em muitos aspectos, mais ricas que o Transact-SQL, oferecendo construções e recursos anteriormente não disponíveis para desenvolvedores do SQL Server.Os desenvolvedores também podem aproveitar o poder da Biblioteca .NET Framework, que fornece um extenso conjunto de classes que podem ser usadas para resolver problemas de programação de forma rápida e eficiente.

  • Maior segurança e proteção. O código gerenciado é executado em um ambiente de tempo de execução de linguagem comum, hospedado pelo Mecanismo de Banco de Dados.O SQL Server aproveita isso para fornecer uma alternativa mais segura aos procedimentos armazenados estendidos disponíveis em versões anteriores do SQL Server.

  • Capacidade de definir tipos de dados e funções agregadas. Os tipos definidos pelo usuário e as agregações definidas pelo usuário são dois novos objetos de banco de dados gerenciados que expandem os recursos de armazenamento e consulta do SQL Server.

  • Desenvolvimento simplificado por meio de um ambiente padronizado. O desenvolvimento de banco de dados está integrado em versões futuras do ambiente de desenvolvimento Microsoft Visual Studio .NET.Os desenvolvedores usam as mesmas ferramentas para desenvolver e depurar objetos e scripts de banco de dados que usam para escrever componentes e serviços do .NET Framework de camada intermediária ou de cliente.

  • Potencial para melhor desempenho e escalabilidade. Em muitas situações, os modelos de compilação e execução da linguagem .NET Framework oferecem melhor desempenho em relação ao Transact-SQL.

Encontramos uma situação com uma função CLR que foi chamada milhares de vezes em um procedimento SQL normal.Este foi um procedimento para importar dados de outro sistema.A função validou os dados e tratou bem os nulos.

Se fizéssemos a operação em TSQL, o proc terminava em cerca de 15 segundos.Se usarmos a função CLR, o processo terminará em 20 a 40 minutos.A função CLR parecia mais elegante, mas até onde pudemos perceber, houve um impacto inicial para cada uso da função CLR.Portanto, se você tiver uma operação grande realizada usando uma função CLR, tudo bem, pois o tempo de inicialização é pequeno comparado ao tempo da operação.Ou se você chamar a função CLR um número modesto de vezes, o tempo total de inicialização para todas as invocações da função será pequeno.Mas tome cuidado com os loops.

Além disso, para fins de manutenção, é melhor não ter mais idiomas do que você realmente precisa.

Eu acrescentaria alguns motivos para usar o CLR que talvez não tenham sido mencionados.

  • Substitua e estenda funções SQL básicas de consulta, não consulta e escalares.
    A) Relatórios de erros e alertas podem ser integrados com base em requisitos definidos.B) Defina facilmente os níveis de depuração.C) Permitir uma maneira mais fácil de interagir com servidores SQL estrangeiros
  • Mova o código legado para um ambiente gerenciado.

Postei a seguinte resposta para uma pergunta semelhante: Vantagem do SQL SERVER CLR.Acrescentarei aqui, porém, que C#/VB.net/etc é uma linguagem com a qual alguém se sente mais confortável do que o T-SQL deveria não ser um motivo para usar SQLCLR em vez de T-SQL.Se alguém não sabe como realizar algo em T-SQL, primeiro peça ajuda para encontrar uma solução T-SQL.Se um não existir, então siga a rota CLR.


A integração SQLCLR/CLR no SQL Server é apenas mais uma ferramenta para ajudar a resolver certos (não todos) problemas.Existem algumas coisas que ele faz melhor do que o que pode ser feito no T-SQL puro, e há algumas coisas que só podem ser feitas via SQLCLR.Escrevi um artigo para o SQL Server Central, Escada para SQLCLR Nível 1:O que é SQLCLR? (é necessário registro gratuito para ler artigos lá), que aborda essa questão.Os princípios básicos são (consulte o artigo vinculado para obter detalhes):

  • Funções com valor de tabela de streaming (sTVF)
  • SQL dinâmico (dentro de funções)
  • Melhor acesso a recursos externos/Substituir xp_cmdshell
    • Passar dados é mais fácil
    • Obter várias colunas de um resultado definido é mais fácil
    • Sem dependências externas (por exemplo7zip.exe)
    • Melhor segurança por meio de representação
  • Capacidade de multithread
  • Tratamento de erros (dentro de funções)
  • Agregados personalizados
  • Tipos personalizados
  • Modificar estado (dentro de uma função e sem OPENQUERY / OPENROWSET)
  • Execute um procedimento armazenado (somente leitura;dentro de uma função e sem OPENQUERY / OPENROWSET)
  • Desempenho (observação: isso é não significado em todos os casos, mas definitivamente em alguns casos dependendo do tipo e complexidade da operação)
  • Pode capturar saída (ou seja,o que é enviado para a guia Mensagens no SSMS) (por exemplo, PRINT e RAISERROR com um gravidade = 0 a 10) -- esqueci de mencionar esse no artigo ;-).

Outra coisa a considerar é que às vezes é benéfico poder compartilhar código entre o aplicativo e o banco de dados para que o banco de dados tenha insights sobre determinada lógica de negócios sem ter que criar telas personalizadas apenas internas apenas para acessar o código do aplicativo.Por exemplo, trabalhei em um sistema que importava arquivos de dados de clientes e usava um hash personalizado da maioria dos campos e salvava esse valor na linha do banco de dados.Isso permitiu pular facilmente as linhas ao importar seus dados novamente, pois o aplicativo faria o hash dos valores do arquivo de entrada e compararia com o valor do hash armazenado na linha.Se eles fossem iguais, saberíamos instantaneamente que nenhum dos campos havia mudado, então passamos para a próxima linha e foi uma comparação INT simples.Mas esse algoritmo para fazer o hash estava apenas no código do aplicativo, seja para depurar um caso de cliente ou procurar maneiras de descarregar algum processamento para serviços de back-end, sinalizando linhas que tinham pelo menos um campo com alterações (mudanças provenientes de nosso aplicativo em vez de procurar alterações em um arquivo de importação mais recente), não havia nada que eu pudesse fazer.Isso teria sido uma grande oportunidade de ter uma lógica de negócios bastante simples no banco de dados, mesmo que não fosse para processamento normal;ter o que equivale a um valor codificado no banco de dados sem capacidade de entender seu significado dificulta muito a solução de problemas.

Se estiver interessado em ver alguns desses recursos em ação sem precisar escrever nenhum código, a versão gratuita do SQL# (do qual sou o autor) possui funções RegEx, agregados personalizados (UDAs), tipos personalizados (UDTs), etc.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top