SQLShack (Português)

Os cursores do SQL Server são um tópico comum na Internet . Você encontrará opiniões diferentes sobre quando usá-los e quando não usá-los. Hoje, também falaremos sobre eles e responderemos à pergunta quando (não) usá-los.

O modelo de dados e a ideia geral

No artigo anterior, Introdução ao SQL Loops de servidor, falamos sobre loops do SQL Server, mas não usamos dados do banco de dados. Isso era estranho, mas deveria ficar muito mais claro agora. Hoje, ao explicar os cursores, usaremos os dados do banco de dados para mostrar quando (não) usar os cursores. O modelo de dados que usaremos é o mesmo que usamos em toda esta série.

O SQL Server suporta 3 diferentes implementações de cursores – cursores Transact-SQL, cursores de API e cursores de cliente. Neste artigo, vamos nos concentrar nos cursores Transact-SQL. Você os reconhecerá facilmente porque são baseados na sintaxe DECLARE CURSOR.

Cursor do SQL Server – Introdução

Antes de passarmos para o código e os exemplos, devemos explicar quais são os cursores do SQL Server são.

O cursor do SQL Server é a lógica T-SQL, que nos permite percorrer o resultado da consulta relacionada. Isso nos permite realizar as ações sequencialmente – por exemplo, realizar uma atualização em uma única linha.

Às vezes, isso pode (parece) ser útil, mas ao trabalhar com bancos de dados, você não deve usar padrões de programação procedural mas sim manter a programação declarativa. Um dos principais motivos é que os SGBDs já estão otimizados para realizar ações em conjuntos de dados e, portanto, você não deve ser aquele que está tentando ser “mais inteligente que o sistema”.

Mesmo assim, é bom para saber como funcionam. No mínimo, talvez você os encontre no código que herdou e terá que reescrever a lógica. E antes de fazer qualquer coisa, você deve entender como funciona.

Então, caso você precise de cursores, isto é o que você deve saber sobre eles:

  • Cursores usam variáveis para armazenar valores retornados em cada parte do loop. Portanto, você precisará DECLARAR todas as variáveis de que você precisa
  • A próxima coisa a fazer é DECLARAR … CURSOR PARA SELECIONAR a consulta, onde você declarará um cursor e também definirá a consulta relacionada a (preencher) esse cursor
  • Você ABRIRÁ o cursor e FETCH NEXT do cursor
  • No loop WHILE, você testará a variável @@ FETCH_STATUS (WHILE @@ FETCH_STATUS = 0). Se a condição for mantida, você entrarei no loop BEGIN … END bloco e execute instruções dentro desse bloco
  • Depois de percorrer todo o conjunto de resultados, você sairá do loop. Você deve FECHAR o cursor e DEALOCÁ-LO. A desalocação é importante porque isso deve excluir a definição do cursor e liberar a memória usada

Cursor do SQL Server – exemplos

Vamos agora dar uma olhada em dois exemplos de cursor. Embora sejam muito simples, eles explicam muito bem como os cursores funcionam.

No primeiro exemplo, queremos obter os ids e nomes de todas as cidades, junto com seus nomes de países relacionados. Usaremos o comando PRINT para imprimir combinações em cada passagem do loop.

Usando o cursor do SQL Server e o while loop retornou exatamente o que esperávamos – ids e nomes de todas as cidades e países relacionados, que temos no banco de dados.

O mais importante a mencionar aqui é que poderíamos simplesmente retornar este conjunto de resultados usando a consulta SQL original armazenada na parte DECLARE do cursor, portanto, não há necessidade de um cursor.

Vamos lá com mais um exemplo. Desta vez, consultaremos o banco de dados do esquema de informações para retornar as 5 primeiras tabelas ordenadas por nome de tabela. Embora não haja muito sentido em usar tal consulta, este exemplo mostra:

  • Como consultar o banco de dados do esquema de informações
  • Como combinar alguns comandos / instruções que já mencionado em artigos anteriores (IF… ELSE, WHILE loop, CONCAT)

Do lado da codificação, Gostaria de enfatizar que, desta vez, não imprimimos nada em um loop, mas sim criamos uma string usando CONCAT. Além disso, usamos a instrução IF para testar se estamos na primeira passagem e, em caso afirmativo, não adicionamos “,”. Caso contrário, adicionaríamos “,” à string.

Após o loop, imprimimos a string de resultado, fechamos e desalocamos o cursor.

Podemos fazer isso usando a função STRING_AGG. Este está disponível a partir do SQL Server 2017 e é o equivalente da função MySQL GROUP_CONCAT.

Cursor do SQL Server – Quando (não) usá-los?

Vou tentar dê uma resposta objetiva à pergunta – “Quando você deve usar cursores do SQL Server e quando não”? Como as coisas mudam com o tempo e melhorias devem ser feitas, seja nos cursores, seja em outros objetos que os “substituam”, leve em consideração a data em que este artigo foi escrito.Então, vamos começar.

Você não deve usar cursores:

  • Quase sempre 🙂 Isso pode parecer estúpido, mas é verdade na maioria dos casos. O SQL Server implementa um grande número de funções de objetos & que fazem exatamente o que você provavelmente tentaria resolver usando cursores. Antes de decidir ir com o cursor, certifique-se de ter investigado o suficiente para concluir que o cursor é a única (boa) solução possível. Mesmo significa loops em bancos de dados. No artigo anterior, Introdução aos loops do SQL Server, usamos loops, mas não para fazer o loop pelos dados.

Você pode usar cursores:

  • Principalmente para tarefas de administração de banco de dados, como backups, verificações de integridade, reconstrução de índices
  • Para uma única vez tarefas quando você tiver certeza de que um possível desempenho ruim não afetará o desempenho geral do sistema
  • Chamar um procedimento armazenado algumas vezes usando parâmetros diferentes. Nesse caso, você obteria parâmetros de variáveis de cursor e faria chamadas dentro do loop

    Chamar um procedimento armazenado ou outra consulta dentro do cursor (ou loop) afeta muito o desempenho, porque, em cada etapa do loop do cursor, você executará a consulta / procedimento desde o início. Se você decidir fazer isso, deve estar ciente das possíveis consequências.

  • A dica anterior nos leva ao último marcador quando você deve usar cursores. Se você está completamente ciente de como eles funcionam e tem certeza de que não afetará o desempenho, vá em frente

Cursor do SQL Server – Por que as pessoas (não) os usam ?

A última pergunta que gostaria de responder é: Por que alguém usaria um cursor? É assim que eu vejo:

  • As pessoas que os usam para empregos ocasionais ou ações regulares em que não afetarão o desempenho têm a desculpa. Um dos motivos é que esse código é procedural e, se você está acostumado, é muito legível.
  • Por outro lado, aqueles que começaram a aprender sobre bancos de dados e estão acostumados com programação procedural podem usam cursores porque, como mencionado, eles estão muito mais próximos da programação procedural do que dos bancos de dados. Isso não é uma razão para usá-los, porque a única desculpa aqui seria que você simplesmente não conhece a outra maneira (certa) de fazer as coisas
  • O mais importante sobre os cursores é que eles são lentos quando comparados às instruções SQL e, portanto, você deve evitar usá-los porque mais cedo ou mais tarde eles causarão problemas de desempenho (a menos que você saiba exatamente o que está fazendo e por quê)

I ache útil que você entenda o conceito de cursores porque há uma grande chance de você conhecê-los ao longo do caminho. Eles eram populares antes de algumas novas opções serem adicionadas ao SQL Server. Além disso, há uma chance de você continuar trabalhando em um sistema em que alguém antes de você os usava e você terá que continuar de onde eles pararam. Talvez você precise substituir o cursor (código procedural) por SQL (código declarativo).

Conclusão

Não há melhor conclusão sobre cursores do que – não os use 🙂 O SQL Server implementou muitas mudanças que resolvem problemas que antes eram difíceis de resolver com o uso de código declarativo. É melhor gastar algum tempo investigando e aprendendo algo novo e, finalmente, produzindo o código ideal. Claro, você pode usá-los se souber por que está fazendo isso e estiver ciente dos possíveis problemas relacionados a eles.

Índice

Aprenda SQL : CREATE DATABASE & Operações CREATE TABLE

Aprenda SQL: INSERT INTO TABLE

Aprenda SQL: chave primária

Aprenda SQL: Chave estrangeira

Aprenda SQL: Instrução SELECT

Aprenda SQL: INNER JOIN vs LEFT JOIN

Aprenda SQL: Scripts SQL

Aprenda SQL: Tipos de relações

Aprenda SQL: Una várias tabelas

Aprenda SQL: Funções de agregação

Aprenda SQL: como escrever uma consulta SELECT complexa?

Aprenda SQL: o banco de dados INFORMATION_SCHEMA

Aprenda SQL: Tipos de dados SQL

Aprenda SQL: Teoria dos conjuntos

Aprenda SQL: funções definidas pelo usuário

Aprenda SQL: procedimentos armazenados definidos pelo usuário

Aprenda SQL: exibições de SQL

Aprenda SQL: SQL Triggers

Aprenda SQL: Pratique consultas SQL

Aprenda SQL: Exemplos de consulta SQL

Aprenda SQL: crie um relatório manualmente usando consultas SQL

Aprenda SQL: funções de data e hora do SQL Server

Aprenda SQL: crie relatórios do SQL Server usando funções de data e hora

Aprenda SQL: tabelas dinâmicas do SQL Server

Aprenda SQL: exportação do SQL Server para o Excel

Aprenda SQL: Introdução aos loops do SQL Server

Aprenda SQL: Cursores do SQL Server

Aprenda SQL: Práticas recomendadas de SQL para exclusão e atualização de dados

Aprenda SQL: Convenções de nomenclatura

Aprenda SQL: Trabalhos relacionados a SQL

Aprenda SQL: Associações não-Equi no SQL Server

Aprenda SQL: injeção de SQL

  • Autor
  • Postagens recentes
Emil é um profissional de banco de dados com mais de 10 anos de experiência em tudo relacionado a bancos de dados. Durante os anos, ele trabalhou na indústria de TI e finanças e agora trabalha como freelancer.
Seus compromissos passados e presentes variam de design de banco de dados e codificação a ensino, consultoria e escrita sobre bancos de dados. Sem esquecer também, BI, criando algoritmos, xadrez, filatelia, 2 cachorros, 2 gatos, 1 esposa, 1 bebê …
Você pode encontrá-lo no LinkedIn
Ver todas as postagens de Emil Drkusic

Postagens mais recentes de Emil Drkusic (ver todos)
  • Aprenda SQL: SQL Injection – 2 de novembro de 2020
  • Aprenda SQL: Non-Equi Joins no SQL Server – 29 de setembro de 2020
  • Aprenda SQL: Trabalhos relacionados a SQL – 1 de setembro de 2020

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *