Salvar uma instrução SQL em uma tabela para execução posterior é uma má idéia?

21

Salvar uma instrução SQL em uma tabela MySQL para execução posterior é uma má idéia? As instruções SQL estarão prontas para execução, ou seja, não haverá parâmetros para trocar nem nada, por exemplo DELETE FROM users WHERE id=1.

Acho que estou sendo preguiçoso, mas pensei nessa idéia porque estou trabalhando em um projeto que exigirá alguns trabalhos cron que executam instruções SQL periodicamente.

Amged Rustom
fonte
Você deve esclarecer se pretende executar essas instruções SQL uma vez ou se deseja executar o mesmo conjunto de instruções repetidamente.
GrandmasterB
10
Essa questão toda parece ser uma daquelas situações em que a abordagem fundamental está errada. Mas é difícil dizer exatamente o quê, porque sabemos muito pouco sobre o espaço problemático.
Erick Robertson

Respostas:

46

É seguro, se é isso que você está perguntando. Contanto que você tenha tanto cuidado com sua segurança quanto com a segurança de seus dados.

Mas não reinvente a roda, procedimentos armazenados são bits de SQL armazenados em uma tabela. E eles apóiam, não encorajam, a parametrização.

Observe também que você pode simplificar sua segurança E reduzir o número de pontos de falha E reduzir as comunicações de rede usando o MySql Event Scheduler em vez de cron.

Outros bancos de dados têm equivalentes a esses, por um bom motivo. Você não é o primeiro a precisar dessa funcionalidade.

pdr
fonte
1
+1 em usar o agendador. Limitar o acesso do agendador apenas aos procs é melhor que o acesso à tabela.
JeffO
Mas e se você precisar criar dinamicamente essas consultas, digamos a partir de uma interface do usuário? Por exemplo, se você permitir que usuários administradores definam dinamicamente regras de acesso ao conteúdo da Web com base em consultas complexas. Você não deseja que a interface do usuário crie um novo processo no banco de dados. Penso que, em algumas circunstâncias, as consultas armazenadas são melhores que os procs.
DiscipleMichael
32

Se você deseja salvar instruções SQL em um banco de dados para execução posterior, há uma opção melhor do que colocá-las em uma tabela: use a funcionalidade interna fornecida para esse fim específico. Coloque-os em procedimentos armazenados.

Mason Wheeler
fonte
2
Então, onde o trabalho cron armazena a lista de procedimentos armazenados a serem executados?
61114 JeffO
1
isso pode ser útil stackoverflow.com/questions/6560639/… embora não esteja usando cron
MetaFight 6/14
Não sei o que eu estava pensando. Uma lista de procs pode ser executada a partir de um único proc, portanto, o trabalho cron precisa apenas executar um.
JeffO
11

Não, eu diria que não é uma boa ideia.

Isso significa que toda consulta / atualização "real" precisará de 2 ocorrências no banco de dados - uma para obter a consulta / atualização "real" e outra para executá-la.

Isso pode não ser um grande problema em um sistema pequeno, mas quanto mais usuários / transações o seu sistema obtiver, menos ele será dimensionado.

Acho que isso vem da procura de uma alternativa para incorporar SQL no seu código?

Encapsular o SQL em um procedimento armazenado, como sugeriu Mason Wheeler, seria uma maneira muito melhor do que essa idéia.

ozz
fonte
+1, esse é o principal motivo pelo qual a solução @Mason Wheeler é a correta - ele apenas deixou de destacar isso. Embora o IMHO não seja o problema de desempenho que eu vejo aqui mais importante - simplesmente não há necessidade de complicar as coisas extraindo uma instrução SQL do banco de dados e enviando-a de volta para execução em seguida.
Doc Brown
Por que a lista de instruções sql precisa ser armazenada no mesmo banco de dados / servidor, etc?
JeffO
1
o OP é aquele que propõe 2 ocorrências no banco de dados. Eu digo que ele não deveria fazer isso. Você então pergunta por que deve ser o mesmo banco de dados / servidor. Eu pergunto quem disse que sim? você então pergunta de que outra forma você recebe 2 hits no banco de dados. Por que você não declara sua pergunta real, e não o que você está fazendo?
ozz
1
@JeffO Mesmo que seja um banco de dados diferente, ainda é 2 consultas de banco de dados para o que deveria ser uma consulta, que é desaceleração desnecessária
Izkata
1
@Ozz: você dá muito peso ao aspecto de desempenho da sua resposta - o desempenho provavelmente é negligenciável na maioria dos cenários do mundo real. Mas a necessidade de duas ações (a primeira para obter a consulta / atualização "real", a segunda para executá-la) torna as coisas apenas mais complicadas do que o necessário.
Doc Brown
4

Desculpe, não acho que seja uma boa ideia.

Considere o caso em que a tabela em questão é alterada. Digamos que sua coluna de ID seja renomeada para new_id .

Além da alteração em si, existe uma versão do seu código escrita para um vintage antigo do banco de dados que pode não ser mais executado. Claro, talvez você deva verificar a tabela de códigos, mas isso não é imediatamente óbvio para outra pessoa.

Para uma mudança como eu descrevi, eu normalmente procurava arquivos SQL autônomos, procedimentos armazenados, gatilhos, SQL em linha no código do cliente (VB, C #, C ++ etc.), mas o último lugar que eu pensaria em procurar está nas tabelas de banco de dados. Embora talvez eu vá agora! :)

Robbie Dee
fonte
2

Existem motivos válidos para armazenar SQL em uma tabela. O software com o qual trabalho no trabalho agora inclui um sistema para gerar documentos e os documentos precisam incluir cálculos bastante complexos usando dados em um banco de dados. Os documentos são atualizados com freqüência, geralmente são significativamente diferentes em termos dos dados necessários e dos cálculos que precisam ser executados. O SQL está sendo usado, basicamente, como uma linguagem de script para executar esses cálculos e o SQL é armazenado em tabelas que também armazenam outras informações para esses documentos. As pessoas que mantêm esses documentos não são programadores ou DBAs, mas estão familiarizadas com o esquema do banco de dados e são proficientes em SQL. Seria uma sobrecarga significativa para eles manterem esse código SQL na forma de procedimentos armazenados.

Pelo que você descreveu - "... um projeto que exigirá algumas tarefas cron que executam instruções SQL periodicamente" - as outras respostas provavelmente estão corretas ao sugerir que você usou procedimentos de armazenamento, ou o equivalente, para o DBMS que você ' re usando.

Um bom critério para decidir se é sensato armazenar SQL em uma tabela versus em um procedimento armazenado é determinar quem manterá esse SQL. Se os usuários mantêm esse SQL, ou seja, eles o escrevem e o alteram sempre que desejam, pode ser perfeitamente bom e, na verdade, melhor armazenar esse SQL em uma tabela. Se os desenvolvedores mantiverem esse SQL, ele deverá ser armazenado em um formulário que possa ser atualizado pelos seus procedimentos de criação e implantação (esperançosamente automatizados), por exemplo, armazenados como um objeto, como um procedimento armazenado no próprio banco de dados.

Kenny Evitt
fonte
1
Obrigado pela resposta. Acabei usando eventos MySQL para agendar as consultas para execução. Muitas pessoas pensaram "a abordagem fundamental está errada" :) quando tudo que eu precisava era executar algumas instruções SQL após 15 minutos a partir de uma ação específica do usuário.
Alterado Rustom
2
@AmgadSuliman - é importante ser caridoso com todos, especialmente nos sites da SE. É bom ter opiniões fortes, mas é muito fácil superar os padrões contra os quais gostamos de investigar. Mas parte de ser caridoso com outras pessoas nesses sites está fornecendo contexto suficiente; muito pode obscurecer a questão real, mas geralmente isso é bastante fácil de corrigir pela edição subsequente.
Kenny Evitt 9/14
1

A saída mais fácil seria ter um arquivo .ini ou outro arquivo de configuração para manter as consultas. Dessa forma, você pode tê-las em um só lugar, alterar qualquer coisa sem ter que acessar o banco de dados, não acessar o banco de dados várias vezes. e você também pode querer / precisar em algum momento usar parâmetros ou adicionar condições às suas consultas (aumente-as com itens mais complexos para um caso específico em seu código).

É claro que você pode mantê-los no nível do banco de dados (em uma tabela ou, melhor ainda, como procedimentos armazenados), no entanto, se você é tão preguiçoso quanto eu ;-) mas também se preocupa com desempenho, um arquivo .ini e PHP O amado método parse_ini para lê-lo, é o caminho a percorrer (se você estiver optando por outra linguagem de programação, estará descobrindo abordagens semelhantes)! Normalmente, eu lia esse arquivo no carregador de inicialização do aplicativo e o mantinha em um objeto estático (talvez com uma camada de cache na parte superior) para realmente acelerar as coisas se estivermos falando de um número muito grande de consultas distintas.

Thyamarkos
fonte
1

Se você precisar da instrução SQL apenas uma vez, por exemplo, se estiver enfileirando várias operações para executar fora do horário comercial, sim, colocá-las em uma tabela funcionará perfeitamente.

Se você precisar executar a mesma instrução SQL em intervalos especificados, a rota do procedimento armazenado que outras pessoas mencionaram provavelmente será uma escolha melhor para você.

Dito isto, o que você está perguntando é bastante incomum e pode ser uma indicação de algum outro problema. Por exemplo, se você estiver esperando para excluir um usuário de um banco de dados, talvez seja melhor chamar um script agendado que faça a operação através do código do aplicativo, em vez de gravar as instruções SQL reais. Dessa forma, o SQL e o código nunca estão fora de sincronia.

GrandmasterB
fonte