Procedimentos armazenados uma má prática em uma das maiores empresas de consultoria de software de TI do mundo?


148

Estou trabalhando em um projeto em uma das três principais empresas de consultoria de TI do mundo, e um DBA me informou que os procedimentos armazenados estaduais das melhores práticas da empresa não são uma "melhor prática". Isso é tão contrário a tudo que aprendi.

Os procedimentos armazenados fornecem reutilização de código e encapsulamento (dois pilares do desenvolvimento de software), segurança (você pode conceder / revogar permissões em um processo armazenado individual), protegê-lo contra ataques de injeção de SQL e também ajudar com velocidade (embora o DBA tenha dito que começando no SQL Server 2008 que até consultas SQL regulares são compiladas se executadas o suficiente).

Estamos desenvolvendo um aplicativo complexo usando a metodologia de desenvolvimento de software Agile. Alguém pode pensar em boas razões pelas quais eles não gostariam de usar procs armazenados? Meu palpite era que os DBAs não queriam manter esses procs armazenados, mas parece haver muitos negativos para justificar tal decisão de design.


3
Que reutilização de código ele adiciona? E se o seu cliente usa um banco de dados diferente. Tem que jogar fora todos esses SPs e começar do zero. Não o proteja da injeção de sql. A velocidade é mínima na maioria dos casos.
Rig

32
Lembre-se de que a maioria das grandes empresas de consultoria em TI tem o objetivo de maximizar horas faturáveis, mantendo o rabo coberto. Os veteranos com alguma influência nessas empresas também tendem a ser jogadores e burocratas, e não técnicos. Eu pegaria coisas assim de uma empresa de consultoria com um pouco de sal - tirei as empresas de consultoria em mais de uma ocasião, consertando suas "melhores" práticas.
ConcernedOfTunbridgeWells

1
A reutilização do @Rig Code é adicionada da mesma forma que é para funções de qualquer idioma - envolvendo o código em um contêiner reutilizável. Certamente, os procedimentos armazenados protegem você da injeção de SQL, desde que você não execute uma string criada. Dizer que a velocidade é mínima parece simplesmente sem instrução. A maioria dos casos não se enquadra nas mesmas categorias em benefícios de desempenho, mas mostra uma grande disparidade.
Garet Claborn

1
@GaretClaborn Mas é muito mais provável que a arquitetura seja reestruturada do que anos e anos de dados históricos do banco de dados. De qualquer maneira, em qualquer aplicativo não trivial. E se você fizer isso, gastará meses portando código rico de procedimento armazenado. Há pouco benefício em adicionar mais uma dependência ao seu projeto, exceto em situações do edgecase. Existem, mas na maioria das vezes está apenas adicionando mais um obstáculo à agilidade do projeto e à reutilização de código.
Rig

2
Vindo de um plano de fundo em que usamos sps quase exclusivamente, posso dizer o benefício de se afastar deles e usar um ORM como o Entity Framework. Muitas vezes a lógica de negócios é encapsulada dentro do procedimento. Enquanto você pode versão procs com algumas ferramentas de trabalho e / ou de terceiros. Não é tão fácil quanto seria fazê-lo em uma estrutura como TFS ou GIT. O código do banco de dados emitido é independente do provedor do RDBMS. Assim, você pode trocar os provedores de RDBMS posteriormente com menos dor de cabeça.
ewahner

Respostas:


280

Na minha experiência trabalhando em projetos muito grandes, é preciso ter muita clareza sobre onde fica a lógica de negócios. Se você permitir um ambiente em que desenvolvedores individuais possam colocar a lógica de negócios na camada de objetos de negócios ou em um procedimento armazenado como entenderem, um aplicativo grande se tornará MUITO difícil de entender e manter.

Os procedimentos armazenados são ótimos para acelerar determinadas operações do banco de dados. Minha decisão arquitetônica é deixar toda a lógica na camada de negócios do aplicativo e empregar procedimentos armazenados de maneira direcionada para melhorar o desempenho, onde o benchmarking indica que isso é necessário.


37
Não vejo as coisas tão simples assim. Para mim, é toda lógica de negócios. O banco de dados, com ou sem procedimentos armazenados, fornece certos serviços e faz certas garantias. Idealmente, deve ser impossível para código de aplicativo incorreto colocar o banco de dados em um estado inconsistente. Se forem necessários procedimentos armazenados para manter essa consistência, eu os uso.
Kevin cline

12
@ Kevin Cline: Defina "estado inconsistente". Concordo que recursos de banco de dados, como integridade referencial, são valiosos e reduzem bastante a possibilidade de um erro de aplicativo causar sérios danos. No entanto, de um modo geral, a definição de "dados consistentes" depende da execução correta das regras de negócios.
Eric J.

16
adicione meu milhão aos milhões de Mayo. Lógica de negócios distribuídos leva você ao lado da rodovia de boas práticas, direto para a pista de loucura
Nico

27
+1 A penetração da lógica comercial no DAL é uma grande preocupação ao usar procedimentos armazenados.
System Down

30
@ChristopherMahan, NUNCA gostaria de usar um banco de dados que você cria. Essa é a pior prática possível da perspectiva do banco de dados. Os bancos de dados geralmente são afetados diretamente no banco de dados. É míope pensar que alguém usará a camada de negócios para atualizar um milhão de registros ou outras coisas que acontecem ao longo do tempo. As importações normalmente não passam pela camada de negócios (sim, quero processar minha importação de 21 milhões de registros, um registro por vez na camada de negócios). A fraude é muito mais fácil quando você não tem restrições no nível do banco de dados. Dados ruins são quase 100% certos.
HLGEM

163

Algumas Observações

Os procedimentos armazenados fornecem reutilização de código e encapsulamento (dois pilares do desenvolvimento de software),

Somente se você usá-los corretamente no contexto em que eles devem ser usados. A mesma afirmação pode ser dita sobre funções (em programação estruturada) ou métodos (em programação orientada a objetos); no entanto, vemos funções 1K e objetos mega-burros.

Os artefatos não oferecem esses benefícios. O uso adequado desses artefatos é o que oferece esses benefícios.

segurança (você pode conceder / revogar permissões em um processo armazenado individual),

Sim. Este é um bom ponto e um dos principais motivos pelos quais eu gosto de procedimentos armazenados. Eles fornecem um controle de acesso de granularidade mais fina do que o que normalmente pode ser alcançado com apenas visualizações e contas de usuário.

protegê-lo contra ataques de injeção de SQL,

Isso não é específico para os SPs, pois você pode obter o mesmo nível de proteção com instruções SQL parametrizadas e limpeza de entrada. Eu usaria SPs além desses, no entanto, como questão de "segurança em profundidade" .

e também ajuda na velocidade (embora o DBA tenha dito que, começando no SQL Server 2008, mesmo as consultas regulares do SQL são compiladas se forem executadas o tempo suficiente).

Isso é altamente específico do fornecedor do banco de dados, mas em geral seu DBA está certo. As instruções SQL (estáticas ou parametrizadas) são compiladas. Os SPs ajudam se você deseja / precisa agregar e computar dados que não podem ser executados com instruções SQL simples, mas estão fortemente integrados ao SQL e não justificam a viagem de ida e volta ao servidor de aplicativos.

Um bom exemplo é consultar dados em um cursor (ou cursores) temporário a partir do qual executar outro SQL em si. Você pode fazer isso de forma programática no servidor de aplicativos ou salvar as várias viagens de ida e volta fazendo isso no banco de dados.

Esta não deve ser a norma, no entanto. Se você tiver muitos desses casos, isso é um sinal de design incorreto do banco de dados (ou você está obtendo dados de esquemas de banco de dados não tão compatíveis entre departamentos).

Estamos desenvolvendo um aplicativo complexo usando a metodologia de desenvolvimento de software Agile.

A agilidade tem a ver com processos de engenharia de software e gerenciamento de requisitos, e não com tecnologias.

Alguém pode pensar em boas razões pelas quais eles não gostariam de usar procs armazenados?

Pergunta errada

A pergunta está errada e equivale a perguntar "existem boas razões para não usar o GOTO"? Sou do lado de Niklaus Wirth mais do que de Dijkstra sobre esse assunto. Eu posso entender de onde veio o sentimento de Dijkstra, mas não acredito que seja 100% aplicável em todos os casos. Mesmo com procs loja e qualquer tecnologia.

Uma ferramenta é boa quando usada bem para a finalidade a que se destina e quando é a melhor ferramenta para a tarefa específica. Usá-lo de outra forma não é uma indicação de que a ferramenta está errada, mas que o usuário não sabe o que está fazendo.

A pergunta apropriada é "que tipo de padrões de uso de procedimento armazenado deve ser evitado". Ou "sob quais condições devo (ou não) usar procedimentos armazenados" . Procurar razões para não usar uma tecnologia é simplesmente colocar a culpa na ferramenta, em vez de colocar a responsabilidade da engenharia diretamente onde ela pertence - no engenheiro.

Em outras palavras, é uma cópia ou uma declaração de ignorância.

Meu palpite era que os DBAs não queriam manter esses procs armazenados, mas parece haver muitos negativos para justificar tal decisão de design.

O que eles estão fazendo então é projetar os resultados de suas más decisões de engenharia nas ferramentas que eles usaram mal.

O que fazer no seu caso?

Minha experiência é que, quando em Roma, faça como os romanos .

Não lute contra isso. Se as pessoas da sua empresa quiserem rotular os processos da loja como uma prática ruim, deixe-os. Entretanto, esteja ciente de que isso pode ser uma bandeira vermelha em suas práticas de engenharia.

A rotulagem típica de coisas como más práticas geralmente é feita em organizações com toneladas de programadores incompetentes. Ao incluir na lista negra certas coisas, a organização tenta limitar o dano infligido internamente por sua própria incompetência. Eu cago não.

Generalizações são a mãe de todos os erros. Dizer que procs armazenados (ou qualquer tipo de tecnologia) é uma prática ruim, isso é uma generalização. Generalizações são cop-outs para os incompetentes. Os engenheiros não trabalham com generalizações flagrantes. Eles fazem análises caso a caso, fazem trocas de análises e executam decisões e soluções de engenharia de acordo com os fatos em questão, no contexto em que devem resolver um problema.

Bons engenheiros não rotulam as coisas como más práticas de maneira generalizada. Eles analisam o problema, selecionam a ferramenta apropriada, fazem trocas. Em outras palavras, eles fazem engenharia.

Minha opinião sobre como não usá-los

  • Não coloque lógica complexa além da coleta de dados (e talvez algumas transformações) nelas. Não há problema em colocar alguma lógica de massagem de dados neles ou agregar o resultado de várias consultas com eles. Mas é isso aí. Qualquer coisa além disso se qualificaria como lógica de negócios que deveria residir em outro lugar.

  • Não os use como seu único mecanismo de defesa contra a injeção de SQL. Você as deixa lá , caso algo ruim as atinja , mas deve haver uma grande quantidade de lógica defensiva na frente delas - validação / depuração do lado do cliente, validação / depuração do lado do servidor, possivelmente transformação em tipos que fazem sentido na sua modelo de domínio e, finalmente, ser passado para instruções parametrizadas (que podem ser instruções SQL parametrizadas ou procs armazenados parametrizados).

  • Não faça dos bancos de dados o único local que contém os procedimentos da sua loja. Os procs da sua loja devem ser tratados da mesma maneira que você trata o código-fonte C # ou Java. Ou seja, a fonte controla a definição textual dos processos da sua loja. As pessoas dizem que os produtos da loja não podem ser controlados pela fonte - porcaria, eles simplesmente não sabem do que diabos estão falando.

Minha opinião sobre como / onde usá-los

  • Seu aplicativo requer dados que precisam ser transpostos ou agregados de várias consultas ou visualizações. Você pode descarregar isso do aplicativo para o banco de dados. Aqui você deve fazer uma análise de desempenho, pois a) os mecanismos de banco de dados são mais eficientes que os servidores de aplicativos para fazer essas coisas, mas b) os servidores de aplicativos são (às vezes) mais fáceis de escalar horizontalmente.

  • Controle de acesso de grão fino. Você não deseja que algum idiota execute junções cartesianas em seu banco de dados, mas também não pode proibir as pessoas de executar instruções SQL arbitrárias assim. Uma solução típica é permitir instruções SQL arbitrárias em ambientes de desenvolvimento e UAT, enquanto as proíbe em ambientes de systest e produção. Qualquer declaração que deve chegar ao systest ou à produção entra em um procedimento de armazenamento, revisado por código pelos desenvolvedores e pelo dbas.

Qualquer necessidade válida de executar uma instrução SQL que não esteja em um processo de armazenamento passa por um nome de usuário / conta e pool de conexão diferentes (com o uso altamente monitorado e desencorajado).

  • Em sistemas como Oracle, você pode obter acesso ao LDAP ou criar links simbólicos para bancos de dados externos (por exemplo, chamar um processo de loja no banco de dados de um parceiro de negócios via vpn.) Maneira fácil de criar código espaguete, mas isso é verdade para todos os paradigmas de programação você tem requisitos específicos de negócios / ambiente para os quais esta é a única solução. Os procs da loja ajudam a encapsular essa maldade em um só lugar, perto dos dados e sem precisar passar para o servidor de aplicativos.

Se você executa isso no db como um processo de loja ou no servidor de aplicativos, depende da análise de trade-off que você, como engenheiro, precisa fazer. Ambas as opções devem ser analisadas e justificadas com algum tipo de análise. Indo de um jeito ou de outro, simplesmente acusando a outra alternativa como "má prática", isso é apenas uma bobagem de engenharia.

  • Em situações em que você simplesmente não pode aumentar o servidor de aplicativos (ou seja, sem orçamento para novas instâncias de hardware ou nuvem), mas com bastante capacidade no back-end db (isso é mais típico que muitas pessoas desejam admitir), vale a pena para mover a lógica de negócios para armazenar procs. Não é bonito e pode levar a modelos de domínio anêmicos ... mas, novamente ... análise de trade-off, a coisa na qual a maioria dos hackers de software é péssima.

Se isso se torna uma solução permanente ou não, isso é específico para as restrições observadas naquele momento específico.

Espero que ajude.


14
Esta é uma resposta muito boa.
yfeldblum

5
Boa resposta, mas isso era para ser irônico? "Generalizações são a mãe de todos os erros."
Bedwyr

2
Sim e não. Esse comentário meu foi destinado a essa sentença específica referida pelo OP em sua pergunta original ( procedimentos armazenados não são uma "melhor prática" .) Uma descrição grosseira dos procedimentos de armazenamento como boas ou más práticas é uma generalização. Ignorando o contexto em que pode ser bom ou ruim pode (e muitas vezes vai levar) para parafuso ups quando arquitetar ou projetar soluções;)
luis.espinal

7
+1 em "A rotulagem típica de coisas como más práticas geralmente é feita em organizações com muitos programadores incompetentes". - estive lá, vivi isso, inclusive sendo informado na minha frente por um gerente de desenvolvimento que ele achava que eu tinha uma ótima solução para um problema complicado, mas se ele fosse visto para me permitir implementá-lo, isso abriria as comportas para o Muppets.
Julia Hayward

1
@ Shane Você está certo. No entanto, acredito que o que essa resposta está tentando transmitir é a tendência de alguns grupos de engenheiros de desculpar sua falta de conhecimento ou análise, chamando o cartão de más práticas. A resposta pode ter uma melhora para os mais inexperientes de nós.
Cesar Hernandez

56

A lógica é que confiar em uma camada de procedimento armazenado limita a portabilidade e o vincula a um determinado banco de dados. Custos de manutenção adicionais também são citados como motivo. Eu também queria comentar sobre esse ponto que você fez:

(procedimentos armazenados) protegem você contra ataques de injeção SQL

Na verdade, é a consulta parametrizada que protege você, o que você pode fazer facilmente na consulta sql em texto sem formatação.


18
E se o seu proc armazenado estiver usando qualquer tipo de sql dinâmico junto com um parâmetro de string, você estará de volta ao ponto em que começou.
Jeffo

4
A diferença é que a permissão de acesso pode ser definida para procedimentos armazenados por procedimento, para consultas SQL parametrizadas, você deve confiar na sanidade dos programadores, + "blablabla"porque você deve permitir SQL simples e é aí que o controle termina.
Coder

19
Eu nunca entendi o argumento "liga você a um certo banco de dados". Com que frequência você pega seu programa e o migra para um banco de dados totalmente diferente?
Mason Wheeler

11
@MasonWheeler - +1 sempre. Em qualquer projeto suficientemente grande, seu aplicativo acaba sendo escrito contra os pontos fracos de um determinado produto de banco de dados. A conversão para outro banco de dados se torna um trabalho importante, não importa o motivo, porque o novo banco de dados terá esquisitices diferentes!
Michael Kohne

6
@HLGEM - mas no mundo COTS, vários bancos de dados são ESPERADOS desde o início (na verdade, você escolhe os bancos de dados compatíveis). Não é sua porta, é que você suporta back-ends diferentes, o que é um animal completamente diferente do que fazer uma porta.
precisa saber é o seguinte

46

Alguns dos motivos pelos quais eu concordo que os procs armazenados não são uma prática recomendada.

  • A lógica de negócios e aplicativos deve estar no código e não no banco de dados. Colocar a lógica no DB está misturando preocupações.
  • Você não pode testar procs armazenados de maneira tão integrada quanto o código em seus projetos de teste de unidade convencional com o restante da lógica do aplicativo.
  • Não considero os procs armazenados como propícios para testar a primeira programação quando estou escrevendo código.
  • Os procs armazenados não são tão fáceis de depurar como o código do aplicativo quando você está depurando seu programa no IDE.
  • Controle de versão / controle de origem do SP vs. código normal

7
Você também pode fazer a programação do primeiro teste nos procedimentos armazenados.

5
Hmmm, bem ... 1) O uso de procedimentos armazenados em banco de dados não implica necessariamente que a lógica de negócios esteja sendo colocada neles. 2) procs armazenados são algumas das coisas mais fáceis de testar na unidade. 3) os procs da loja não são necessariamente condutores das práticas de primeiro teste, é verdade, mas nem tudo que é computável pode ser testado primeiro. 4) a depuração não deve ser um problema, pois os procs de armazenamento não devem conter nada além de instruções e cursores SQL fáceis de verificar. Além disso, a depuração deve ocorrer primeiro testando e depurando as instruções SQL no código e depois movida para os procs da loja ... apenas IMO btw.
Luis.espinal

6
Você obviamente não é um desenvolvedor de DB. Controle de origem, IDEs - é muito fácil depurar um SP se você estiver usando o TOAD ou um IDE semelhante, o mesmo com o controle de versão.
Gbjbaanb

6
2) em testes de unidade procs armazenados. idk sobre outras estruturas de teste de unidade, mas pelo menos com o MS Test (VisualStudio.TestTools.UnitTesting), a execução de qualquer um dos métodos Assert no processo armazenado requer pelo menos uma conexão Db, que por definição o torna mais um teste de integração do que uma unidade teste. E um processo armazenado pode fazer referência ao estado sobre o banco de dados em um nível global do banco de dados. Eles podem não ser capazes de falsificar ou ter interfaces.
530

3
Além disso, as linguagens de procedimento armazenado (pl / sql, t-sql, plpgsql, etc) são muito desajeitadas e detalhadas. É muito mais fácil para mim usar uma linguagem de script para fazer uma conexão com o banco de dados e lidar com a lógica de negócios fora do banco de dados.

22

Os procedimentos armazenados fornecem reutilização de código e encapsulamento (dois pilares do desenvolvimento de software),

Sim, mas ao custo de poder atingir outras metas de design ágil. Eles são mais difíceis de manter, por um lado. Se o projeto em que estou inserida for alguma indicação, você provavelmente terminará com vários SPs incompatíveis que fazem essencialmente o mesmo trabalho, sem nenhum benefício.

protegê-lo contra ataques de injeção de SQL,

Não eles não. Eu não posso nem começar a adivinhar de onde essa idéia pode ter surgido, como eu ouvi muitas vezes, e isso simplesmente não é verdade. Pode atenuar certos tipos de ataques de injeção SQL, mas se você não estiver usando consultas parametrizadas, isso não importará. Ainda posso '; DROP TABLE Accounts; -

e também ajuda na velocidade (embora o DBA tenha dito que, começando no SQL Server 2008, mesmo as consultas regulares do SQL são compiladas se forem executadas o tempo suficiente).

Eles também são tipicamente compilados quando você usa instruções preparadas e parametrizadas (pelo menos com vários dos bancos de dados que usei). No momento em que seu aplicativo começa a executar a consulta (ou especialmente quando você executa a mesma consulta preparada várias vezes), qualquer vantagem de desempenho que você acha que seu SP possui é completamente discutível.

O único motivo para usar um procedimento armazenado, IMHO, é quando você deve fazer uma consulta complexa e de várias etapas que extrai de várias fontes intercaladas. Os SPs não devem conter lógica de decisão de baixo nível e nunca devem simplesmente encapsular uma consulta simples. Não há benefícios e apenas muitas desvantagens.

Ouça o seu DBA. Ele sabe o que se passa.


1
O Red Gate tem um produto SQL Source Control para SQL Server, mas eu concordo que inserir lógica nos procs armazenados é uma excelente maneira de garantir que você tenha uma lógica importante que não esteja sob nenhum tipo de controle de versão.
Carson63000

17
@greyfade - "Ainda tenho que ver o controle de origem dos SPs" - você está brincando comigo? Um processo de armazenamento é apenas um arquivo de texto sangrento que você carrega no mecanismo de banco de dados (que o pega, o compila e o instala para execução.) Em todo lugar em que trabalhei que armazenou processos, armazenamos o código-fonte do processo, digamos, CVS, clearcase ou qualquer SCM que estivesse em uso. Dizer que os procs da loja não podem ser controlados pela fonte (porque estão no banco de dados) é como dizer que o código-fonte do meu aplicativo (Java, C # ou qualquer outra coisa) não pode ser controlado pela fonte porque é compilado e implantado na produção.
Luis.espinal

2
@ luis.espinal: eu não disse que eles não poderiam estar no controle de origem. Eu apenas disse que não conhecia uma ferramenta específica para manter o histórico de SPs, o que implica manter esse histórico no banco de dados. Por favor, não fale comigo só porque você interpretou mal alguma coisa.
greyfade

1
Todos os nossos procs armazenados estão sob controle de origem, apenas porque você viu pacotes defeituosos no passado não significa que eles sejam inerentes ao uso de procs armazenados.
HLGEM

1
@ luis.espinal é típico que a fonte de um procedimento armazenado possa ser recuperada posteriormente no banco de dados? Nesse caso, você pode simplesmente ter uma ferramenta que a retira regularmente e ter outras ferramentas para recriar uma instalação do zero. Faça isso de vez em quando para garantir que seja preciso.

17

Essa era a linha oficial quando eu trabalhei em um dos cinco grandes há alguns anos. A lógica era que, como os SPs estão vinculados a implementações específicas (PL / SQL vs T / SQL vs ...), eles limitam desnecessariamente as opções de tecnologia.

Tendo vivido a migração de um grande sistema de T / SQL para PL / SQL, posso entender o argumento. Eu acho que é meio complicado - quantos lugares realmente se movem de um banco de dados para outro por um capricho?


10
@DaveE: Para uma solução corporativa, você provavelmente está certo. Se você estiver criando um software em pacote, assim que enviar o MSSQL, seu maior cliente em potencial desejará que ele seja executado no Oracle.
Eric J.

3
@ Eric: muito verdade. Onde estou agora, usamos toneladas de SPs e dizemos às pessoas 'não' se elas não querem o MSSQL. É bom poder fazer isso.
Davee

3
@DaveE: A equipe de vendas deseja que você possa dizer "sim"?
Eric J.

2
Não é tanto mover um sistema de um banco de dados para outro, mas ter um sistema capaz de usar qualquer sistema de banco de dados que o cliente já tenha. Grandes bancos de dados são caros.

@ EricJ: sim, mas depois que eles veem o custo da comissão, o pedido desaparece.
Davee

17

Todas as três empresas em que trabalho usaram procedimentos armazenados para sua lógica de aplicativo com o SQL Server. Eu realmente não vi as coisas de outra maneira. Mas para mim eles são uma grande bagunça. Normalmente, não existem recursos muito bons para lidar com erros ou recursos de reutilização de código com procedimentos armazenados.

Digamos que você tenha um procedimento armazenado que retorna um conjunto de dados que deseja usar, como você pode usá-lo em procedimentos armazenados futuros? Os mecanismos no SQL Server para isso não são muito bons. EXEC INTO ... só funciona para um ou dois níveis) de aninhamento (eu esqueço agora). Ou você tem que pré-definir uma tabela de trabalho e ter seu processo codificado. Ou você precisa pré-criar uma tabela temporária e fazer com que o procedimento a preencha. Mas e se duas pessoas chamarem uma tabela temporária da mesma maneira em dois procedimentos diferentes que nunca planejaram usar ao mesmo tempo? Em qualquer linguagem de programação normal, você pode simplesmente retornar um array de uma função ou apontar para uma estrutura global objeto / compartilhada entre eles (exceto para linguagens funcionais em que você retornaria a estrutura de dados em vez de apenas alterar uma estrutura global ... )

E quanto à reutilização de código? Se você começar a colocar expressões comuns em UDFs (ou subconsultas ainda piores), diminuirá a velocidade do código. Você não pode chamar um procedimento armazenado para executar um cálculo para uma coluna (a menos que use um cursor, passe os valores da coluna um por um e depois atualize sua tabela / conjunto de dados de alguma forma). Então, basicamente, para obter o máximo desempenho, você precisa cortar / colar expressões comuns em todo o lugar, o que é um pesadelo de manutenção ... Com uma linguagem de programação, você pode criar uma função para gerar o SQL comum e chamá-lo de qualquer lugar ao criar a sequência SQL. Então, se você precisar ajustar a fórmula, poderá fazer a alteração em um único local ...

E o tratamento de erros? O SQL Server possui muitos erros que impedem a execução imediata do procedimento armazenado e alguns até forçam uma desconexão. Desde 2005, existe tentativa / captura, mas ainda há vários erros que não podem ser capturados. Além disso, o mesmo ocorre com a duplicação de código no código de tratamento de erros e você realmente não pode passar exceções com tanta facilidade ou com bolhas até níveis mais altos com a mesma facilidade que a maioria das linguagens de programação ...

Também apenas velocidade. Muitas operações em conjuntos de dados não são orientadas para SET. Se você tentar fazer coisas orientadas a linhas, use um cursor ou um "cursor" (quando os desenvolvedores frequentemente consultam cada linha uma por uma e armazenam o conteúdo em variáveis ​​@ exatamente como um cursor. .. Mesmo que isso geralmente seja mais lento que um cursor FORWARD_ONLY). Com o SQL Server 2000, eu tinha algo que estava em execução por 1 hora antes de matá-lo. Reescrevi esse código no Perl e ele terminou em 20 minutos. Quando uma linguagem de script 20-80x mais lenta que C fuma SQL no desempenho, você definitivamente não tem negócios gravando operações orientadas a linhas no SQL.

Agora, o SQL Server tem integração com o CLR e muitos desses problemas desaparecem se você usar procedimentos armazenados do CLR. Mas muitos DBAs não sabem escrever programas .NET ou desativar o CLR devido a questões de segurança e ficar com o Transact SQL .... Além disso, mesmo com os CLRs, você ainda tem problemas para compartilhar dados entre vários procedimentos de maneira eficiente. .

Também, em geral, a coisa mais difícil de expandir é o banco de dados. Se toda a sua lógica de negócios estiver no banco de dados, quando o banco de dados ficar muito lento, você terá problemas. Se você possui uma camada de negócios, basta adicionar mais armazenamento em cache e mais servidores de negócios para aumentar o desempenho. Tradicionalmente, outro servidor para instalar o Windows / Linux e executar o .NET / Java é muito mais barato do que comprar outro servidor de banco de dados e licenciar mais SQL Server. No entanto, o SQL Server agora tem mais suporte a cluster, originalmente ele realmente não tinha nenhum. Portanto, se você tiver muito dinheiro, poderá adicionar cluster ou até mesmo enviar alguns logs para fazer várias cópias somente leitura. Mas, no geral, isso vai custar muito mais do que apenas ter uma gravação por trás do cache ou algo assim.

Veja também os recursos do Transact-SQL. Manipulação de String? Vou fazer as classes Java String Class / Tokenizer / Scanner / Regex a qualquer dia. Tabelas de hash / listas vinculadas / etc. Vou pegar as estruturas Java Collection, etc ... E o mesmo para .NET ... C # e Java são linguagens muito mais evoluídas que o Transact SQL ... Heck codificação com Transact-SQL me deixa com inveja de C .. .

No mais, os procedimentos armazenados são mais eficientes para trabalhar com um grande conjunto de dados e aplicar várias consultas / critérios para reduzi-lo antes de retorná-lo à camada de negócios. Se você precisar enviar vários conjuntos de dados enormes para o aplicativo cliente e dividir os dados no cliente, será muito mais ineficiente do que apenas fazer todo o trabalho no servidor.

Os procedimentos armazenados também são bons para segurança. Você pode cortar todo o acesso às tabelas subjacentes e permitir apenas o acesso através dos procedimentos armazenados. Com algumas técnicas modernas como XML, você pode ter procedimentos armazenados que fazem atualizações em lote. Todo o acesso é controlado através dos procedimentos armazenados, desde que seguros / corretos, os dados possam ter mais integridade.

O argumento de injeção SQL realmente não se aplica mais, pois temos consultas parametrizadas no lado da linguagem de programação. Além disso, mesmo antes das consultas parametrizadas, um pouco de substituição ("'", "' '") também funcionava a maior parte do tempo (embora ainda existam truques a serem usados ​​para passar pelo final da string e obter o que você deseja).

No geral, acho que SQL e Transact SQL são ótimas linguagens para consultar / atualizar dados. Mas, para codificar qualquer tipo de lógica, manipular seqüências de caracteres (ou manipulação de arquivos ...), você ficaria surpreso com o que pode fazer com xp_cmdshell ....) por favor, não. Espero encontrar um lugar futuro que não use procedimentos armazenados principalmente. Do ponto de vista da manutenção do código, eles são um pesadelo. Além disso, o que acontece se você quiser trocar de plataforma (embora, na verdade, se você pagou pelo Oracle / DB2 / Sybase / Sql Server / etc., Também poderá obter tudo o que puder usando todas as extensões proprietárias que puderem ajudá-lo. ..)

Também surpreendentemente, muitas vezes a lógica de negócios não é a mesma. No mundo ideal, você colocaria toda a lógica nos procedimentos armazenados e a compartilharia entre os aplicativos. Mas muitas vezes a lógica difere com base nos aplicativos e seus procedimentos armazenados acabam se tornando monólitos excessivamente complexos que as pessoas têm medo de mudar e não entendem todas as implicações de. Considerando que, com uma boa linguagem orientada a objetos, você pode codificar uma camada de acesso a dados que possui algumas interfaces / ganchos padrão que cada aplicativo pode substituir às suas próprias necessidades.


6
No entanto, não posso deixar de oferecer uma reflexão sobre toda a questão do processo versus o processo. Vi cursores de banco de dados usados ​​em todos os tipos de casos em que essa abordagem era apenas louca. Substituí pessoalmente o SQL explícito baseado em cursor (Oracle PL / SQL, nesse caso específico) por uma consulta orientada a conjunto e vi os resultados retornarem em menos de um segundo, em vez de 8 minutos. Levei 30 minutos para dissecar o código do cursor de 1.000 linhas e "obtê-lo". A consulta SQL resultante foi concisa, elegante, simples. As pessoas subestimam o poder de seus servidores de banco de dados com muita frequência e rapidez.
21414 Craig

12

Como você versão procedimentos armazenados no servidor?

Se você reimplementar procedimentos armazenados no servidor a partir do controle de versão, expulsará o plano de execução armazenado.

Os procedimentos armazenados não devem ser modificáveis ​​diretamente no servidor, caso contrário, como você sabe o que está realmente em execução agora? Caso contrário, a ferramenta de implantação precisa de acesso para gravar procedimentos armazenados no banco de dados. Você precisaria implantar em cada build (o plano de execução pode precisar ser diferente)

Embora os procedimentos armazenados não sejam portáveis, o SQL também não (em geral, já viu manipulação de datas Oracle - uggghhh).

Portanto, se você deseja portabilidade, crie uma API interna de acesso a dados. Você pode chamar isso como chamadas de função e internamente pode criar o idioma que desejar, com consultas parametrizadas, e pode ser controlado por versão.


6
Como você versão procedimentos armazenados no servidor? - você controla a versão do código fonte do proc da loja. Quando é hora de implantar, você pega os procs da loja (a partir de uma determinada linha de base) e você (ou seu dba) implementa na produção. A reimplantação (seja em teste ou produção) certamente explode o plano de exec armazenado, mas isso acontecerá independentemente de você controlar seus SPs de origem ou não.
Luis.espinal

1
@ BarryBrown Não funciona se as pessoas tiverem acesso direto ao servidor e puderem alterar os procedimentos armazenados. Eu teria que ter um processo que observa a SPs, ou ter um cheque antes de cada utilização ...
Christopher Mahan

2
Se você tem pessoas apenas alterando sprocs de maneira incontrolável nos servidores sem comprometer suas alterações no controle de origem, você tem um problema de processo que certamente está afetando seu desenvolvimento imperativo de código também, mesmo que você não saiba.
Craig

1
Uma das coisas que fiz no passado foi colocar uma instância de desenvolvimento do servidor de banco de dados nas estações de trabalho de desenvolvedores individuais ou, se isso não fosse possível, pelo menos ter instâncias "dev" e "produção" dos bancos de dados , e todos os scripts DDL e DML, bem como exemplos de dados e scripts de carregamento, vividos em seu próprio diretório na árvore de origem, e o banco de dados foi criado rotineiramente a partir desses scripts usando o arquivo MAKE. Os desenvolvedores também puderam usar o nmake para criar procs armazenados únicos. Se eles não o colocassem sob controle de origem, eles desapareceriam e eles sabiam disso.
21414 Craig

1
... não quis parecer depreciativo no meu comentário anterior, com a frase "..., mesmo que você não esteja ciente ...". O que eu pretendia transmitir era que, se esse tipo de coisa está acontecendo com procedimentos armazenados, provavelmente também está acontecendo em outras partes do projeto. Pessoalmente, meio que não gosto do controle de fonte integrado no IDE, em parte porque acho que isso torna as pessoas preguiçosas em termos de pensar sobre o que realmente significa para a equipe e o projeto como um todo fazer alterações e confirmar essas alterações no controle de fonte repositório. Essas coisas não devem ser "automáticas" na minha opinião.
21414 Craig

9

Isso é tão contrário a tudo que aprendi.

Você pode precisar sair mais. Sério, os procs armazenados estão em declínio há pelo menos 10 anos. Desde então, a n-camada substituiu o cliente-servidor. O declínio só foi acelerado pela adoção de linguagens OO como Java, C #, Python, etc.

Isso não quer dizer que os procs armazenados ainda não tenham seus proponentes e advogados - mas essa é uma discussão e debate de longa duração. Não é novo e provavelmente ainda continuará por algum tempo; Na IMO, os oponentes dos procs armazenados estão claramente vencendo.

Os procedimentos armazenados fornecem reutilização de código e encapsulamento (dois pilares do desenvolvimento de software)

Muito verdadeiro. Mas, o mesmo acontece com uma camada OO decentemente arquitetada.

segurança (você pode conceder / revogar permissões em um processo armazenado individual)

Embora você possa fazer isso, poucos o fazem devido às sérias limitações. A segurança no nível do banco de dados não é granular o suficiente para tomar decisões com reconhecimento de contexto. Por causa da sobrecarga de desempenho e gerenciamento, é incomum ter conexões por usuário também - portanto, você ainda precisa de algum nível de autorização no código do aplicativo. Você pode usar logons baseados em funções, mas precisará criá-los para novas funções, manter a função em que está executando, alternar conexões para que o "nível do sistema" funcione como log etc. etc. E, no final, se o seu aplicativo pertence - assim como sua conexão com o banco de dados.

protegê-lo contra ataques de injeção de SQL

Não mais do que fazer consultas parametrizadas. O que você precisa fazer de qualquer maneira.

e também ajuda na velocidade (embora o DBA tenha dito que, começando no SQL Server 2008, mesmo as consultas regulares do SQL são compiladas se forem executadas o tempo suficiente).

Acho que isso começou no MSSQL 7 ou 2000. Houve muitos debates, medições e informações erradas sobre o desempenho armazenado de proc vs SQL embutido - eu agrupo tudo no YAGNI. E, se você precisar, teste.

Estamos desenvolvendo um aplicativo complexo usando a metodologia de desenvolvimento de software Agile. Alguém pode pensar em boas razões pelas quais eles não gostariam de usar procs armazenados?

Eu não posso pensar em muitas razões que você quer fazer. Java / C # / qualquer terceira linguagem GL são todos muito mais capazes do que o T-SQL no encapsulamento, reutilização e felxibilidade, etc. A maioria é gratuita, devido a um ORM meio decente.

Além disso, dado o conselho de "distribuir conforme necessário, mas não mais" - acho que o ônus da prova atualmente está nos defensores de SP. Um motivo comum para o armazenamento pesado de processos é que o T-SQL é mais fácil que o OO, e a loja possui desenvolvedores T-SQL melhores que o OO. Ou então, o DBA para na camada do banco de dados e os procs armazenados são a interface entre o dev e o DBA. Ou você está enviando um produto semi-personalizado e os procs armazenados podem ser personalizados pelo usuário. Ausentes de algumas considerações como essa, acho que o padrão para qualquer projeto de Agile SW atualmente será ORM.


1
muito a melhorar no desempenho, se você não precisar transferir conjuntos de dados gigantes do banco de dados para fazer coisas simples. Meça e otimize se necessário.

Precisamente. Os procedimentos armazenados podem ser usados ​​como um bisturi. É uma garantia absoluta de que a E / S no servidor de banco de dados tenha mais largura de banda que a E / S entre o servidor de banco de dados e a camada intermediária. E você não escreverá códigos de junção de dados mais rápidos e eficientes na camada intermediária do que os desenvolvedores do mecanismo de banco de dados escreveram no servidor de banco de dados. Se você estiver transferindo 1.000.000 de linhas de dados para a camada intermediária para fazer uma junção, o que eu certamente vi, você deve ser açoitado ... É como os caras que afirmam que você deve "escrever seu próprio código de reversão". Insanidade.
21414 Craig

1
Não subestime seu servidor de banco de dados. Aprenda a usá-lo corretamente.
21414 Craig

1
FWIW, você não precisa de um procedimento armazenado para fazer uma junção no lado do banco de dados. E se você estiver usando um cursor para lógica processual, provavelmente já perdeu a guerra do desempenho. Desistir de procedimentos armazenados certamente não é o mesmo que desistir de SQL ou de soluções baseadas em conjunto.
Mark Brackett

1
Totalmente verdade, e eu estava realmente argumentando a favor do SQL mais do que argumentando especificamente para sprocs. Mas ter o SQL incorporado no seu código imperativo também não é necessariamente a chave da felicidade, certo? O que geralmente leva a todo o debate sobre ORM, o que me leva a apontar comparações de desempenho entre o acesso ao banco de dados controlado por ORM e apenas aprender a usar SQL. Eu já vi e ouvi falar de sistemas nos quais, digamos, os consultores da Oracle recomendavam manter toda a carga possível fora do servidor de banco de dados, levando a um middleware pesado (e muito caro!) Com desempenho péssimo .
22414 Craig

4

Considerando todos os casos acima, gostaria de acrescentar mais um. A escolha de SP pode depender também da escolha das pessoas.

Pessoalmente, sinto-me frustrado quando as pessoas colocam uma lógica muito complexa no SP e acredito que esse SP é muito complexo de manter e depurar. Mesmo em muitos casos, o próprio desenvolvedor enfrenta problemas ao depurar o código por trás (digamos parte do idioma) é muito mais fácil do que no SP.

O SP deve ser usado apenas para operações simples. Bem, essa é a minha escolha.


4

Eu quero cobrir alguns pro- e problemas com procs armazenados. Nós os usamos extensivamente com o LedgerSMB , e nossa regra é, com algumas extensões muito específicas, "se for uma consulta, torne-a um processo armazenado".

Nossa razão para fazer isso foi facilitar a reutilização de consultas em vários idiomas. Não há uma maneira melhor de fazer isso honestamente.

No final, a questão está sempre nos detalhes. Os procedimentos armazenados e bem usados ​​tornam as coisas muito mais fáceis e, quando mal utilizados, tornam as coisas muito mais difíceis.

Então, para o lado do golpe.

  1. Como tradicionalmente usado, os procedimentos armazenados são quebradiços. Usados ​​sozinhos, eles criam a possibilidade de adicionar bugs ao seu código em locais que você não esperava por nenhuma outra razão além da alteração da sintaxe da chamada. Usado sozinho, isso é um pouco problemático. Existe muita coesão entre as camadas e isso causa problemas.

  2. Sim, é possível ter injeção intra-sproc sql se estiver executando qualquer sql dinâmico. É ruim ter excesso de confiança nessa área e, consequentemente, é preciso ter uma experiência significativa em segurança nessa área.

  3. As alterações nas interfaces são um pouco problemáticas com os procedimentos armazenados pelo motivo nº 1 acima, mas isso pode se tornar um pesadelo muito grande se um grande número de aplicativos clientes estiver envolvido.

O exposto acima é bastante difícil de negar. Eles acontecem. Todo mundo, pró-SP e anti-SP provavelmente já teve histórias de horror sobre isso. Os problemas não são solucionáveis, mas se você não prestar atenção, não poderá resolvê-los (no LedgerSMB, usamos um localizador de serviço para criar dinamicamente chamadas de SP em tempo de execução, evitando os problemas acima. apenas algo semelhante poderia ser feito para outros bancos de dados).

Para os aspectos positivos. Supondo que você possa resolver os problemas acima, você obtém:

  1. A possibilidade de maior clareza nas operações definidas. Isso é particularmente verdadeiro se sua consulta for muito grande ou muito flexível. Isso também leva a maior testabilidade.

  2. Se eu já tenho um localizador de serviço trabalhando nessa área, acho que os procedimentos armazenados aceleram o ritmo do desenvolvimento, pois liberam o desenvolvedor de aplicativos das preocupações com o banco de dados e vice-versa. Isso tem algumas dificuldades em fazer o certo, mas não é tão difícil de fazer.

  3. Consulta reutilização.

Ah, e algumas coisas que você quase nunca deve fazer em um SP:

  1. lógica não transacional. Você enviou o e-mail de que o pedido foi enviado, mas a transação foi revertida ... ou agora você está esperando para continuar o servidor de e-mail ficar on-line .... ou pior, você reverte sua transação apenas porque não consegue acessar o servidor de email ....

  2. muitas pequenas consultas vagamente unidas, polvilhadas com lógica processual ...


Concordo totalmente, mantendo: lixo não-transacional fora dos procedimentos armazenados. Nesse exemplo de email, a mensagem de email deve ser descartada em uma fila e atendida de forma assíncrona, de qualquer maneira. Fale sobre a configuração de um enorme desempenho e comportamento desagradável sob carga, tornando as transações do banco de dados dependentes da resposta do seu servidor de email? Caramba!
Craig

3

Para quem você trabalha?

A resposta pode depender de quem você trabalha, da empresa de consultoria ou da própria empresa. O melhor para uma empresa geralmente não é o melhor para uma empresa de consultoria ou outro fornecedor de software. Por exemplo, uma empresa inteligente deseja ter uma vantagem permanente sobre seus concorrentes. Por outro lado, um fornecedor de software deseja conseguir a mesma solução para todas as empresas de um setor em particular, pelo menor custo. Se tiverem sucesso nisso, não haverá vantagem competitiva líquida para o cliente.

Nesse caso específico, os aplicativos vão e vêm, mas muitas vezes o banco de dados corporativo permanece para sempre. Uma das principais coisas que um RDBMS faz é impedir que dados indesejados entrem no banco de dados. Isso pode envolver procedimentos armazenados. Se a lógica é boa e altamente improvável de mudar de ano para ano, por que não deveria estar no banco de dados, mantendo-o internamente consistente, independentemente de qual aplicativo foi escrito para usar o banco de dados? Anos depois, alguém terá uma pergunta que deseja fazer no banco de dados e será responsável se houver impedimento de lixo eletrônico no banco de dados.

Então, talvez isso tenha algo a ver com o fato de seu DBA trabalhar para uma empresa de consultoria. Quanto mais portáteis eles puderem criar seu código, mais eles poderão reutilizar o código de cliente para cliente. Quanto mais lógica eles puderem amarrar no aplicativo, mais a empresa estará casada com o fornecedor. Se eles deixarem para trás uma grande bagunça no processo, serão pagos para limpá-la ou nunca mais a verão. De qualquer forma, é uma vitória para eles.

insira a descrição da imagem aqui

Para (muito) mais discussões dos dois lados da cerca, leia a discussão em codificação horror . FWIW Eu me inclino ao lado daqueles que defendem SPs.


1
Esta resposta se concentra em vincular a questão de usar ou não os procedimentos armazenados para a pergunta para quem você trabalha e quais são suas motivações. Voto negativo. Em vez disso, a resposta deve se concentrar em vincular a questão de usar ou não os procedimentos armazenados, os prós e os contras dos procedimentos armazenados. Se a resposta focasse na ideia de que os SPs evitem que o lixo entre no banco de dados, eu não teria votado negativamente. Eu discordaria, no interesse da divulgação, mas não teria votado mal.
precisa saber é o seguinte

Além disso, você vinculou um artigo de 2004, IMHO o cenário mudou bastante desde então. Os OR / M tornaram-se muito mais comuns. Ruby / Rails ActiveRecord, MS saiu com LINQ e EF, Django para Python, etc.
Brook

@Justice, ele está certo, porém, se as melhores práticas da área de processos armazenados dependem muito de quem é a empresa e qual o papel que ela desempenha. Por exemplo, procs armazenados permitem que você defina permissões no próprio processo e não diretamente na tabela. Se você estiver realizando algum trabalho financeiro e precisar considerar controles internos, eles são a única opção viável para proteger seus dados dos usuários. Mas se você estiver criando produtos COTS com possíveis back-end múltiplos, eles são muito específicos para o banco de dados. Se você é uma empresa de consultoria, pode ser necessário considerar várias abordagens diferentes da melhor maneira para as circunstâncias.
HLGEM

3
@HLGEM Não me oponho a nenhum dos pontos que você mencionou . Mas objeto à tese da resposta de que o principal motivo pelo qual o DBA pode colocar lógica no aplicativo é porque ele é um consultor e pretende estragar o cliente. Ele vincula a posição moral de uma pessoa à sua escolha de usar procedimentos armazenados. Na minha opinião, existem argumentos técnicos de ambos os lados, e os argumentos de ambos os lados diferem de aplicação para aplicação, tecnologia para tecnologia, empresa para empresa, setor para setor. E procurarei primeiro o mérito antes de impugnar o motivo.
Yfeldblum

Ele disse que trabalha para uma empresa de consultoria. Manter mais controle sobre o código versus os procedimentos armazenados implantados no site do cliente é um motivo muito legítimo, pois essa pode ser sua "melhor prática". Pode não ser "ferrar o cliente", mas pode muito bem ser uma questão de maior controle.
Jesse

3

É muito difícil alternar entre marcas de banco de dados e utilizar os mesmos procedimentos armazenados.

Sua equipe não tem um DBA e ninguém mais quer ter nada a ver com o sql.

Isso nada mais é do que um programador x concurso de mijar DBA.


2

OMI depende. Os procedimentos armazenados têm o seu lugar, mas não são uma prática recomendada nem devem ser evitados a todo custo. Um desenvolvedor inteligente sabe como avaliar adequadamente uma determinada situação e determinar se um procedimento armazenado é a resposta. Pessoalmente, sou fã de usar algum tipo de ORM (mesmo básico, como o Linq to Sql bruto), em vez de procedimentos armazenados, exceto talvez para relatórios predefinidos ou similares, mas, novamente, é realmente uma base caso a caso.


Os que recusam devem comentar.
SandRock

2

É sempre uma fonte de problemas dividir a lógica de negócios entre diferentes camadas, usando diferentes linguagens de programação. Rastrear um bug ou implementar uma mudança é muito mais difícil quando você precisa alternar entre mundos.

Dito isso, conheço empresas que se saem muito bem colocando toda a lógica de negócios em pacotes PL / SQL que vivem no banco de dados. Essas não são aplicações muito grandes, mas também não são triviais; digamos 20K-100K LOC. (O PL / SQL é mais adequado para esse tipo de sistema que o T-SQL, por isso, se você conhece apenas o T-SQL, provavelmente não concorda com isso agora ...)


2

Este é outro ponto ainda não mencionado:

As ferramentas de geração de código e as ferramentas de engenharia reversa não conseguem lidar bem com os procedimentos armazenados. A ferramenta geralmente não pode dizer o que o proc faz. O proc retorna um conjunto de resultados? Vários conjuntos de resultados? Ele busca seus conjuntos de resultados de várias tabelas e tabelas temporárias? O proc é apenas uma instrução de atualização encapsulada e não retorna nada? Ele retorna um conjunto de resultados, um valor de retorno e alguma "saída do console"?

Portanto, se você quiser usar uma ferramenta para criar automaticamente uma camada DTO e DAO de objeto de transferência de dados (como o "construtor de serviços" do liferay faz), não poderá fazê-lo facilmente.

Além disso, ORMs como o Hibernate não podem realmente funcionar corretamente quando a fonte de dados é um SP. O acesso a dados é somente leitura, na melhor das hipóteses.


É interessante que as ferramentas de geração de código aparentemente tenham dificuldade em descobrir se um procedimento armazenado retorna um conjunto de resultados, quando o próprio procedimento armazenado não tem nenhum problema com isso.
Craig

2

Programando sozinho, não resisto a escrever procedimentos armazenados.

Estou usando o MySQL principalmente. Eu não usei bancos de dados orientados a objetos antes, como o PostGreSQL, mas o que posso fazer com SPs no MySQL é abstrair um pouco a estrutura da tabela. SP de permitir-me para projetar essas ações primitivas, cujas entradas e saídas não vai mudar , mesmo se o banco de dados debaixo dela se mudar.

Então, eu tenho um procedimento chamado logIn. Quando você faz login, sempre passa usernamee password. O resultado retornado é o número inteiro userId.

Quando logIné um procedimento armazenado, agora posso adicionar trabalho adicional a ser feito no logon, que acontece ao mesmo tempo que o logon inicial. Acho mais fácil escrever do que a chamada ( uma série de instruções SQL com lógica incorporada em um procedimento armazenado) ambiente FETCH) -> (obtenha resultado) -> (chamando ambiente FETCH) que você precisa executar quando escreve seu lado do servidor lógico.


1

Quero salientar também que os procedimentos armazenados usam o tempo da CPU no servidor. Não muito, mas um pouco. Parte do trabalho realizado no procedimento de trabalho pode ser realizado no aplicativo. É mais fácil dimensionar a camada do aplicativo do que a camada de dados.


3
É difícil dimensionar um banco de dados?
Jeffo

1
É pelo menos significativamente mais caro (a menos que você esteja no MySQL) e em muitos lugares em que trabalhei obtendo outra licença do SQL Server Enterprise Edition é como puxar os dentes
ben f.

dimensionamento de banco de dados não é mais difícil do que escalar um final camada de aplicativo da história
Brian Ogden

1

Concordo com Mark que a comunidade realmente está se afastando dos procedimentos armazenados há algum tempo. Embora muitos dos pontos levantados pelo pôster original por que podemos querer usar SPs sejam válidos ao mesmo tempo, já faz um bom tempo e, como outro pôster disse, o ambiente mudou. Por exemplo, lembro-me de que um argumento para usar SPs 'de volta ao dia' foi o ganho de desempenho alcançado porque seus planos de execução foram 'pré-compilados' enquanto o SQL dinâmico do nosso código precisava ser 're-compilado' a cada execução. Este não é mais o caso, pois os principais bancos de dados foram alterados, aprimorados, adaptados etc.

Dito isto, estamos usando SPs no meu projeto atual. O motivo é simplesmente porque estamos construindo novos aplicativos sobre um banco de dados existente que ainda suporta aplicativos herdados. Como resultado, é muito difícil fazer alterações no esquema até desativar os aplicativos herdados. Tomamos uma decisão consciente de projetar nossos novos aplicativos com base no comportamento e nas regras necessárias para o aplicativo e usar os SPs para interagir temporariamente com o banco de dados da maneira que gostaríamos que fosse e permitir que os SPs se adaptassem ao SQL existente . Isso vai até o ponto anterior: os SPs facilitam fazer alterações no nível do banco de dados sem exigir alterações no código do aplicativo. Usar SPs como uma implementação do padrão do adaptador certamente faz sentido para mim (especialmente pelo meu projeto atual),

Fwiw, é nossa intenção remover os SPs quando o esquema for atualizado. Mas, como em todo o desenvolvimento corporativo, veremos se isso acontece! [sorri]


0

Eu só queria fazer uma visão geral concisa de como eu recomendaria o uso de procedimentos armazenados. Eu não acho que elas sejam uma má prática e, como outros disseram, devem ser usadas nas situações adequadas.

Eu vejo problemas nos quais procedimentos de gravação para aplicativos diferentes podem se tornar confusos em funcionalidade e separar a lógica comercial do aplicativo e resultar no banco de dados se tornando mais desorganizado e restritivo também.

Portanto, eu usaria um procedimento armazenado em tarefas orientadas a dados relacionais específicas ao banco de dados. Em outras palavras, se houver lógica usada para operações de banco de dados que seja consistente com os dados de qualquer aplicativo, um procedimento armazenado poderá ser usado para manter os dados armazenados de forma consistente (faz sentido). Penso que bons exemplos disso são: registro consistente, manutenção consistente, trabalho com informações confidenciais etc.

Outras tarefas: manipular os dados para atender às necessidades do aplicativo que seguem o forte modelo de dados do banco de dados, eu acho, devem ser armazenados em outra camada que contenha a lógica de negócios. Em resumo, a manipulação de dados específica do banco de dados para obter consistência pode usar procedimentos armazenados, nos quais a consistência se estende além do modelo de esquema de integridade do banco de dados.


-1

Os procedimentos armazenados "para mim" são adequados para operações OLAP "somente leitura", uso raro.

Para regras de negócios, operações de leitura / gravação OLTP, prefiro servidores de aplicativos Java. Para facilitar a codificação e, tanto quanto possível, aliviar a CPU e a carga de memória dos servidores mestre db. Nesta configuração, todo o código nos servidores de aplicativos não é difícil de revisar ou registrar e é escalável.

O importante para mim é que é mais fácil depurar na camada de negócios do que depurar procedimentos armazenados.


Você fez algumas suposições: que o OP precisa de OLAP (não declarado na pergunta); que a plataforma que está sendo usada possui servidores de aplicativos Java (improvável, pois a tag é sobre o SQL Server). Você responde também não traz nada que as outras 22 respostas ainda não cobriram #
Adam Zuckerman

Eu só estava dizendo que se eu iniciar um novo projeto, usará o procedimento armazenado raramente para operações somente leitura, apenas uma escolha pessoal. Acho mais conveniente fazer a maioria das codificações na camada de lógica de negócios, em vez da camada de dados.
jaizon lubaton

este não parece oferecer nada substancial sobre os pontos feitos e explicado em anteriores 24 respostas, dificilmente um conteúdo vale a pena bater um 4 anos velha questão
mosquito

-2

Além de distribuir a lógica de negócios desnecessariamente e vinculá-lo a um fornecedor de banco de dados específico, também acredito firmemente no uso de uma tecnologia para o que ela foi planejada. Um banco de dados é apenas isso, um armazenamento de dados relacional. Use-o para armazenar dados, nada mais.

Escolha suas ferramentas com sabedoria e você se salvará em um mundo de mágoas a longo prazo.


se você vai votar, faça isso, mas pelo menos explique o porquê.
Nico

provavelmente porque você está errado. Um SP não significa que você esteja escrevendo um código, apenas escrevendo suas consultas de acesso a dados (em 99% dos casos, eu acho). Além disso, apenas colocar gatilhos e restrições no modelo de dados conta como 'código' - isto é, lógica operacional, não dados. Daí o meu argumento de que você está errado.
Gbjbaanb

Onde você define transformações nos seus dados armazenados, exceto no banco de dados?
Chris Travers
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.