Quando as consultas processuais são absolutamente necessárias?

8

Sei que tendemos a evitar cursores e loops no SQL Server a todo custo, mas quais são algumas das situações em que você absolutamente precisa de consultas processuais, e as consultas baseadas em conjuntos simplesmente não fornecem os resultados?

Entendo a diferença entre os dois, nunca cheguei a uma situação em que preciso usar um cursor. Eu estou querendo saber se existem tais situações.

Thomas Stringer
fonte

Respostas:

9

Nas minhas experiências, já me deparei com algumas vezes em que justificativas de procedimentos / iterativas eram necessárias.

API permite apenas operação em linha única

Se eu quisesse alterar programaticamente o tipo de dados de real para decimal em uma tabela que possui 500 colunas com erros de digitação, como a pergunta SO , o cursor é uma boa abordagem, pois o DDL não permite alterar várias colunas em uma única instrução.

O conjunto com base não é dimensionado

Se você possui o livro Deep Dives do SQL Server MVP , o capítulo 4 "Iteração baseada em conjunto: a terceira alternativa", de Hugo Kornelis, possui ótimos casos de uso para operações combinadas de cursor / conjunto. Dois dos problemas clássicos mencionados pelo autor do capítulo são os totais em execução e a embalagem de lixeira .

Usei a abordagem de iteração baseada em conjunto com êxito para um processo mal projetado que herdei no último trabalho. Em resumo, havia um processo que uma vez por ano tinha que atualizar linhas de 50 a 75 milhões e tentar fazê-lo em um único conjunto iria explodir nossos logs. Ao dividir as atualizações em lotes menores de N linhas, ele permitiu que o log se mantivesse e realmente terminasse mais rapidamente do que no ano anterior, quando eles apenas alocaram uma tonelada métrica de mais espaço em disco.

billinkc
fonte
6

Quando algo não pode ser feito com base em conjunto.

Sangramento óbvio, é claro. Mas observe que há diferença no "não baseado em conjuntos" e no uso de uma solução processual porque eles não entendem conjuntos ou não sabem como fazê-lo com código baseado em conjuntos.

Um exemplo de código processual seria enviar um email por linha com conteúdo diferente por linha

Muitos códigos SQL para uso do DBA são procedurais. Por exemplo, loop (CURSOR ou WHILE: sem diferença) sobre bancos de dados e tabelas para reconstruir índices e atualizar estatísticas.

Algumas construções SQL permitem o processamento linha a linha no contexto de um conjunto, como CROSS APPLY desta forma em SO: SELECT TOP 5 linhas para cada FK (observe também a solução ROW_NUMBER ())

Edit: estendendo a resposta de @ billinkc ...

O CROSS APPLY permite operações baseadas em conjuntos com UDFs que possuem uma "API de linha única"

gbn
fonte
2

Eu sei que você está perguntando sobre o SQL Server, mas no mundo Oracle (no passado), as tabelas temporárias tinham um custo muito alto; portanto, os procedimentos e acionadores com base no cursor eram mais rápidos e mais baixos no "custo" para o servidor. No SQL Server, os cursores costumavam ter um custo muito maior do que as tabelas temporárias, portanto, escrever código baseado em cursor era desencorajado. Tenho certeza de que essas discrepâncias foram eliminadas na década passada.

Para lidar com essas situações, a maioria das pessoas tem uma regra geral para evitar colocar a lógica de negócios no banco de dados. Se você puder fazer isso sempre totalmente, não haverá motivo para lógica processual nem no T-SQL nem no PL / SQL. Os bancos de dados relacionais são ótimos na lógica baseada em conjuntos. A maioria das linguagens de programação modernas são ótimas em lógica processual. É melhor usar cada um para o que eles são bons.

Alguns gatilhos de auditoria com os quais trabalhei tinham regras bastante complicadas para o que precisava ser verificado e onde as coisas tinham que ser atualizadas / registradas. Alguns eram para manter os sistemas de relatórios sincronizados com os sistemas transacionais (não era minha escolha, mas eles queriam assim). Alguns eram para um sistema de formulários . Um formulário é uma lista de medicamentos e, para cada companhia de seguros, o que eles cobrirão / não cobrirão e, se prescrito, drug_X quais substituições são cobertas pelo seguro. Também era comum que diferentes apólices de grupo na mesma companhia de seguros pagassem por medicamentos diferentes.

Tangurena
fonte