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 exige que eu leia cada livro, divulgue cada palavra e execute-a através dessa função (eu a salvei como Procedimento Armazenado).
Eu tenho uma tabela que contém cada palavra, sem duplicatas.
Minha pergunta: existe uma maneira de fazer algum tipo de loop "para cada" na tabela Palavras usando meu procedimento armazenado?
ie passe ao procedimento armazenado um ID e uma palavra do livro e registre o resultado. Fazendo cada palavra, para cada livro. Assim, poupando muito tempo manual ... Isso é algo que eu deveria estar fazendo do lado do banco de dados? Em vez disso, devo tentar com PHP?
Honestamente, qualquer contribuição é muito apreciada!
fonte
count(explode(' ', $pageText))+1
. Ou algo mais complexo para lidar com vários espaços entre as palavras, talvez envolvendopreg_replace('/\s+/', ' ', $pageText)
1+split(/\s+/, $pageText)
. O 1 é porque a contagem é de espaços, não de palavras.Respostas:
Crie um segundo procedimento que use dois cursores aninhados.
Os cursores nos procedimentos armazenados permitem que você faça algo não muito semelhante ao SQL: itere através de um conjunto de resultados uma linha por vez, colocando os valores da coluna selecionada em variáveis e fazendo coisas com eles.
Eles são facilmente mal utilizados, já que o SQL, sendo declarativo e não processual, geralmente não deve precisar "para cada" operações do tipo, mas nesse caso, parece um aplicativo válido.
Quando você pega o jeito, os cursores são fáceis, mas exigem uma abordagem estruturada no código de suporte que nem sempre é intuitiva.
Recentemente, forneci algum código "padrão padrão" para trabalhar com um cursor para chamar um procedimento armazenado em uma resposta no Stack Overflow , e emprestarei muito fortemente dessa resposta, abaixo.
O uso de um cursor requer algum código padrão para cercá-lo.
Você tem
SELECT
os valores que deseja transmitir, de onde quer que os esteja adquirindo (que pode ser uma tabela temporária, tabela base ou exibição e pode incluir chamadas para funções armazenadas) e, em seguida, chame seu procedimento existente 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 existem eventos que acontecem aqui em uma ordem específica por um motivo. As variáveis precisam ser declaradas primeiro, os cursores devem ser declarados antes dos manipuladores de continuar e os loops precisam seguir todas essas coisas.
Você não pode fazer coisas fora de ordem; portanto, quando aninha um cursor dentro de outro, é necessário 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, basta declará-lo dentro do loop, dentro de outro blocoBEGIN
...END
fonte
BEGIN
/END
e são implicitamente fechados quando ficam fora do escopo ... portanto, o fechamento dos cursores não é estritamente necessário. Por uma questão de prática, considero-o desnecessário e não o incluo, mas, para completar, adicionei aCLOSE
declaração à resposta.