Publicidade

SQL – Cursores

Olá pessoal.

Vamos falar hoje sobre “Cursores” em SQL, mas vamos falar de forma simples e prática, sem enrolação.

“Cursores” são mais ou menos como sub-consultas retornadas em uma estrutura parecida com tabela, para uso de funções e procedures.

Como assim? Normalmente o select no retorna dados filtrados de tabelas, simples assim.

O “Cursor” nos retorna estes mesmo dados, mas de forma que consigamos aplicá-los em funções e procedures.

Vamos supor que eu tenha 3 tabelas, uma chamada “Usuarios”, outra chamada “Enderecos” e outra chamada “Completo”, como segue logo abaixo:

Usuarios:
Nome           Idade   Sexo
Juca Pimenta   33      M
Joao Silverio  25      M
Bruna Beleza   18      F

Enderecos:
Nome           Rua           Numero   Bairro
Juca Pimenta   Rua Feliz     115      Alegria
Joao Silverio  Av do Balão   25       Centro
Bruna Beleza   Tv Bambú      70       Jardim da Lagoa 

Completo:
Nome   Idade   Sexo   Endereco

Eu deixei a tabela “Completo” vazia de propósito para explicar o “Cursor”.

Neste caso, vamos filtrar as tabelas “Usuarios” e “Enderecos” e juntar tudo na tabela “Completo”.

Mas primeiro, vamos criar uma procedure para isso:

CREATE PROCEDURE procJuntaTudo(@pNome AS VARCHAR(20),
                               @pIdade AS INT,
                               @pSexo AS VARCHAR(1),
                               @pRua AS VARCHAR(20),
                               @pNumero AS INT,
                               @pBairro ASVARCHAR(20))
AS
BEGIN

INSERT INTO Completo
      (Nome,
       Idade,
       Sexo,
       Endereco)
VALUES(@pNome,
       @pIdade,
       @pSexo,
       @pRua + ', ' + @pNumero + ', ' + @pBairro)

END

Nessa função, repare que passo todos os campos das duas tabelas como parâmetros da função e depois gravo todos dados em somente uma.

Mas não podemos usar essa função dentro de um “Select”, ai entra a necessidade do “Cursor”.

No “Cursor” vamos montar o “Select” que filtrará os dados, e os deixará prontos para serem usados na função.

Vamos definir o “Cursor”:

DECLARE cursorJuntaTudo CURSOR LOCAL FORWARD_ONLY READ_ONLY FOR
    SELECT US.Nome,
           US.Idade,
           US.Sexo,
           END.Rua,
           END.Numero,
           END.Bairro
    FROM Usuarios US
    LEFT JOIN Enderecos END ON (END.Nome = US.Nome)

Vejam, nós declaramos um “Cursor” chamado “cursorJuntaTudo” e dentro dele fizemos um “Select” da tabela “Usuarios” com left join da tabela “Enderecos”.

O “Cursor” vai disponibilizar estes dados como se fossem uma tabela, e utilizaremos como segue:

DECLARE @Nome AS VARCHAR(20)
DECLARE @Idade AS INT
DECLARE @Sexo AS VARCHAR(1)
DECLARE @Rua AS VARCHAR(20)
DECLARE @Numero AS INT
DECLARE @Bairro AS VARCHAR(20)

DECLARE cursorJuntaTudo CURSOR LOCAL FORWARD_ONLY READ_ONLY FOR
    SELECT US.Nome,
           US.Idade,
           US.Sexo,
           END.Rua,
           END.Numero,
           END.Bairro
    FROM Usuarios US
    LEFT JOIN Enderecos END ON (END.Nome = US.Nome)

OPEN cursorJuntaTudo
  
FETCH NEXT FROM cursorJuntaTudo INTO @Nome, @Idade, @Sexo, @Rua, @Numero, @Bairro
WHILE @@FETCH_STATUS = 0
BEGIN
    EXEC procJuntaTudo @Nome, @Idade, @Sexo, @Rua, @Numero, @Bairro 
    
    FETCH NEXT FROM cursorJuntaTudo INTO @Nome, @Idade, @Sexo, @Rua, @Numero, @Bairro
END
  
CLOSE cursorJuntaTudo
DEALLOCATE cursorJuntaTudo

Logo após a declaração do “Cursor”, nós o abrimos com o comando “OPEN”.

Agora preste atenção no comando “FETCH NEXT”, ele indica para usar o próximo registro do “Cursor”, então logo após o “OPEN”, usamos o “FETCH” para apontar o “Cursor” para o primeiro registro dispovível.

O “FETCH” vai pegar a próxima linha do “Cursor” e jogar os dados para dentro das variáveis @Nome, @Idade, @Sexo, @Rua, @Numero, @Bairro. Estas variáveis, tem que ser na mesma quantidade e tipo do “Select” declarado dentro do “Cursor”.

Depois fazemos um “WHILE” enquanto o “@@FETCH_STATUS” seja igual a 0, o que significa que o “WHILE” vai executar enquanto houver dados, quando terminarem todos os registros o “@@FETCH_STATUS” fica -1 e o laço termina.

Dentro do “WHILE” executamos a função que junta todos dados na tabela “Completo”, passando como parâmetro as variáveis do “FETCH”.

No final do “WHILE”, usamos o “FETCH” novamente para pulara para o próximo registro do “Cursor”, e é nesse momento, quando não houver mais registros que o “@@FETCH_STATUS” vai mudar para -1.

Por fim, fechamos o “Cursor” com o comando “CLOSE” e liberamos a memória ocupada por ele com o comando “DEALLOCATE”.

Dessa forma nossa tabela “Completo” ficará assim:

Completo:
Nome           Idade   Sexo   Endereco
Juca Pimenta   33      M      Rua Feliz, 115, Alegria
Joao Silverio  25      M      Av do Balão, 25, Centro
Bruna Beleza   18      F      Tv Bambú, 70, Jardim da Lagoa

Dúvidas pessoal, é só escrever aqui nos comentários.

Abraço.

Deixe um comentário

O seu endereço de e-mail não será publicado.