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.
fonte
Respostas:
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.
fonte
Algumas Observações
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.
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.
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" .
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).
A agilidade tem a ver com processos de engenharia de software e gerenciamento de requisitos, e não com tecnologias.
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.
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).
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.
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.
fonte
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:
Na verdade, é a consulta parametrizada que protege você, o que você pode fazer facilmente na consulta sql em texto sem formatação.
fonte
+ "blablabla"
porque você deve permitir SQL simples e é aí que o controle termina.Alguns dos motivos pelos quais eu concordo que os procs armazenados não são uma prática recomendada.
fonte
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.
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; -
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.
fonte
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?
fonte
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.
fonte
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.
fonte
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.
Muito verdadeiro. Mas, o mesmo acontece com uma camada OO decentemente arquitetada.
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.
Não mais do que fazer consultas parametrizadas. O que você precisa fazer de qualquer maneira.
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.
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.
fonte
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.
fonte
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.
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.
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.
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:
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.
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.
Consulta reutilização.
Ah, e algumas coisas que você quase nunca deve fazer em um SP:
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 ....
muitas pequenas consultas vagamente unidas, polvilhadas com lógica processual ...
fonte
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.
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.
fonte
É 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.
fonte
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.
fonte
É 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 ...)
fonte
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.
fonte
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 passausername
epassword
. O resultado retornado é o número inteirouserId
.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.fonte
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.
fonte
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]
fonte
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.
fonte
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.
fonte
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.
fonte