Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

SQL dinâmico vs procedimento armazenado


SQL dinâmico e procedimentos armazenados são dois dos componentes mais importantes do SQL Server. Neste artigo, veremos as vantagens e desvantagens de cada um deles e quando usá-los.

Desempenho


Todo mundo sabe a resposta para essa pergunta. Os procedimentos armazenados superam o SQL dinâmico em termos de desempenho. Um procedimento armazenado é armazenado em cache na memória do servidor e sua execução é muito mais rápida que o SQL dinâmico. Se todas as variáveis ​​restantes forem mantidas constantes, o procedimento armazenado supera o SQL dinâmico.

Separação de preocupações


Em termos de separação de interesses, os procedimentos armazenados superam o SQL dinâmico.

Os procedimentos armazenados permitem que você mantenha a lógica do banco de dados separada da lógica de negócios. Portanto, se ocorrer um erro em sua lógica de negócios, basta alterar o código do aplicativo. Por outro lado, se houver um problema com a lógica do banco de dados, apenas o procedimento armazenado precisará ser modificado. Além disso, se um procedimento armazenado for atualizado, o código do aplicativo não precisará ser recompilado e implantado.

Se você usar consultas SQL dinâmicas no código do cliente, será necessário atualizar o código do aplicativo se ocorrer um erro na consulta SQL. Isso significa que você terá que recompilar e implantar o código do aplicativo.

Tráfego de rede


Os procedimentos armazenados produzem menos tráfego de rede do que o SQL dinâmico, pois a execução de um procedimento armazenado requer que apenas o nome do procedimento e os parâmetros (se houver) sejam enviados pela rede.

A execução do SQL dinâmico exige que a consulta completa seja enviada pela rede, aumentando o tráfego da rede, principalmente se a consulta for muito grande.

Ataques de injeção de SQL


Os procedimentos armazenados não são vulneráveis ​​a ataques de SQL Injection.

As consultas SQL dinâmicas são vulneráveis ​​a ataques de injeção de SQL se as consultas parametrizadas não forem usadas, e as consultas parametrizadas não podem ser usadas com SQL dinâmico se um nome de tabela ou coluna for passado como parâmetro.

Nesse caso, a solução alternativa é que a função de nome de código pode ser usada para evitar ataques de injeção de SQL.

Reutilização de planos de consulta em cache


Os procedimentos armazenados melhoram o desempenho do banco de dados, pois permitem que os planos de consulta armazenados em cache sejam reutilizados. No caso de SQL dinâmico, você terá que usar consultas parametrizadas para aumentar a reutilização do plano de consulta em cache. Na ausência de planos de consulta parametrizados, o SQL Server detecta automaticamente os parâmetros e gera planos de consulta em cache, resultando em melhor desempenho.

É pertinente mencionar aqui que apenas os sistemas OLTP se beneficiam da reutilização do plano de consulta em cache. No caso dos sistemas OLAP, a escolha do otimizador muda, o sistema OLAP se beneficia do plano exclusivo.

Manutenção


Os procedimentos armazenados com SQL estático são mais fáceis de manter. Por exemplo, no caso de SQL estático em um procedimento armazenado, erros de sintaxe podem ser detectados antes de serem executados. No caso de SQL dinâmico dentro de procedimentos armazenados, os erros de sintaxe não podem ser detectados antes da execução da consulta.

Além disso, os procedimentos armazenados são mais parecidos com funções, são definidos uma vez e podem ser chamados em qualquer lugar do script. Portanto, se você deseja atualizar um procedimento armazenado, basta atualizá-lo em um local. Todas as partes do aplicativo que chamam o procedimento armazenado terão acesso à versão atualizada. No entanto, uma desvantagem é que essas partes do aplicativo também podem ser afetadas onde você não deseja o procedimento armazenado atualizado. No caso de SQL dinâmico, você pode ter que escrever o script SQL em vários locais, mas nesses casos, atualizar o script em um local não afeta o outro. A decisão entre usar um procedimento armazenado e SQL dinâmico depende da funcionalidade do aplicativo.

Segurança


Se vários aplicativos acessarem o banco de dados, é mais seguro usar procedimentos armazenados do que SQL dinâmico.

Os procedimentos armazenados fornecem uma camada extra de segurança, enquanto o contexto do usuário é a única maneira de controlar as permissões em scripts SQL dinâmicos. Em suma, proteger o SQL dinâmico é trabalhoso em comparação com os procedimentos armazenados.

Identificando dependências


Em um banco de dados relacional, as tabelas têm dependências de outras tabelas do banco de dados.

Considere um cenário em que você deseja remover uma tabela, mas, antes de fazer isso, deseja descobrir todas as dependências da tabela. Ou, em termos simples, você deseja encontrar as consultas que acessam a tabela que deseja excluir. Nesses casos, você pode usar o procedimento armazenado sp_depends.

No entanto, sp_depends só pode detectar as dependências em que SQL estático é usado dentro de um procedimento armazenado. No caso de SQL dinâmico ser dependente de uma tabela, essa dependência não pode ser detectada pelo procedimento armazenado sp_depends. Vamos ver isso em ação com a ajuda de um exemplo simples.

Preparando dados fictícios


Vamos criar alguns dados fictícios para ajudar a explicar o conceito de dependências em SQL estático e dinâmico.
CREATE DATABASE deptest;USE deptestCREATE TABLE aluno(Id int identity chave primária, Name VARCHAR(50) NOT NULL, Gender VARCHAR(50) NOT NULL, Age int)INSERT INTO studentVALUES('James', 'Male', 20 ),('Helene', 'Feminino', 20),('Sofia', 'Feminino', 20),('Ed', 'Homem', 20),('Ron', 'Feminino', 20) 
Agora temos um banco de dados de teste contendo uma tabela e alguns dados de teste. Agora vamos criar dois procedimentos armazenados que acessam a tabela de alunos.

O primeiro procedimento armazenado usa SQL estático para recuperar todos os registros da tabela de alunos:
USE deptestGOCREATE PROC spStatProcASBEGIN SELECT * FROM studentEND

Execute o script acima. Este script cria um procedimento armazenado “spStatProc” dentro do banco de dados deptest.

Vamos criar outro procedimento armazenado que contém SQL dinâmico que recupera todos os registros da tabela do aluno.
USE deptestGOCREATE PROC spDynProcASBEGIN DECLARE @query NVARCHAR(100) SET @query ='SELECT * FROM student' EXECUTE sp_execute @query END

Este script cria um procedimento armazenado “spDynProc” dentro do banco de dados deptest. Esse procedimento armazenado usa uma instrução SQL dinâmica para recuperar todos os registros da tabela de alunos.

Agora temos dois procedimentos armazenados que possuem uma dependência na tabela do aluno. Um deles contém SQL estático e o outro contém SQL dinâmico.

No entanto, se você executar o procedimento armazenado sp_depends e passar a tabela do aluno como parâmetro, verá que ele recuperará apenas o procedimento armazenado “spStatProc”. Isso ocorre porque ele contém SQL estático. O procedimento armazenado “spDynProc” será ignorado, pois contém SQL dinâmico.

Execute o script a seguir.
USE deptestGOEXECUTE sp_depends aluno

Ele obterá a seguinte saída:

[ID da tabela=40 /]

Você pode ver que sp_depends não conseguiu reportar a dependência “spDynProc” e reportou apenas “spStatProc”.

Complexidade


Os procedimentos armazenados podem ficar extremamente complexos se você estiver usando um grande número de filtros e houver várias cláusulas AND e OR entre os filtros. Por outro lado, usando SQL dinâmico você pode gerar dinamicamente cláusulas WHERE dependendo do tipo de filtros. Isso torna o SQL dinâmico as melhores escolhas se você deseja implementar uma lógica extremamente complexa.

Conclusão


No geral, o procedimento armazenado supera o SQL dinâmico em quase todos os aspectos. Eles são mais rápidos, seguros e fáceis de manter e exigem menos tráfego de rede. Como regra geral, os procedimentos armazenados devem ser usados ​​em cenários em que você não precisa modificar suas consultas e suas consultas não são muito complexas. No entanto, se você altera frequentemente nomes de tabelas, nomes de colunas ou o número de parâmetros em sua consulta, o SQL dinâmico é a melhor escolha devido à sua estratégia de implementação mais simples.

Links úteis

  • SQL dinâmico versus procedimentos armazenados
  • Não tenha medo do SQL dinâmico
  • Criando procedimentos armazenados de alto desempenho
  • Aulas sobre procedimentos armazenados