Eu tenho um banco de dados com 'livros' (contos para crianças) e seria extremamente informativo ter contagens de palavras de cada palavra nos livros.
Eu descobri como obter a contagem de palavras para cada palavra usando:
SELECT SUM
(
ROUND
(
(LENGTH(pageText) - LENGTH (REPLACE (pageText, "Word", "")))
/LENGTH("Word")
)
) FROM pages WHERE bookID = id;
O que funciona maravilhosamente para contar as palavras. MAS isso requer que eu passe por cada livro, e tire cada palavra, e execute-a por meio dessa função (eu a salvei como um procedimento armazenado).
Eu tenho uma tabela que contém cada palavra, sem duplicatas.
Minha pergunta: existe uma maneira de fazer algum tipo de loop "for each" na tabela Words usando meu procedimento armazenado?
ou seja. passe ao procedimento armazenado um ID de livro e uma palavra e registre o resultado. Fazendo CADA palavra, para CADA livro. Assim, economizando muito tempo manual... Isso é algo que eu deveria estar fazendo do lado do banco de dados? Devo tentar com PHP em vez disso?
Honestamente, qualquer entrada é muito apreciada!
Crie um segundo procedimento que usa dois cursores aninhados.
Os cursores em procedimentos armazenados permitem que você faça uma coisa muito diferente do SQL: itere através de um conjunto de resultados uma linha por vez, colocando os valores de coluna selecionados em variáveis e fazendo coisas com eles.
Eles são facilmente mal utilizados, já que o SQL, sendo declarativo ao invés de procedural, normalmente não deveria precisar de operações do tipo "for each", mas neste caso, parece ser uma aplicação válida.
Depois que você pega o jeito deles, os cursores são fáceis, mas eles exigem uma abordagem estruturada em seu código de suporte que nem sempre é intuitiva.
Recentemente, forneci um código "boilerplate" bastante padrão para trabalhar com um cursor para chamar um procedimento armazenado em uma resposta no Stack Overflow e tomarei emprestado muito dessa resposta abaixo.
Usar um cursor requer algum código clichê padrão para cercá-lo.
Você
SELECT
os valores que deseja passar, de onde quer que os esteja obtendo (que pode ser uma tabela temporária, tabela base ou exibição, e pode incluir chamadas para funções armazenadas) e, em seguida, chama seu procedimento existinf com esses valores.Aqui está um exemplo sintaticamente válido do código necessário, com comentários para explicar o que cada componente está fazendo.
Este exemplo usa 2 colunas para passar 2 valores para o procedimento chamado.
Observe que os eventos que acontecem aqui estão em uma ordem específica por um motivo. As variáveis devem ser declaradas primeiro, os cursores devem ser declarados antes de seus manipuladores continue e os loops devem seguir todas essas coisas.
Você não pode fazer coisas fora de ordem, então quando você aninha um cursor dentro de outro, você tem que redefinir o escopo do procedimento aninhando código adicional dentro de
BEGIN
...END
blocos dentro do corpo do procedimento; por exemplo, se você precisasse de um segundo cursor dentro do loop, bastaria declará-lo dentro do loop, dentro de outroBEGIN
...END
bloco.