Usuário com melhor resposta
Ajuda a constuir cursor

Pergunta
-
Oi estou a precisar fazer um select mas com uma pequena particularidade
O select em causa é o seguinte :
Select PrecoUnidade,Quantidades From tblEntradas
Agora eu queria era durante a execuçao do Select poder calcular a soma da Coluna Quantidades e parar o select quando esta soma for <=7
Acho que isto so sera possivel com um cursor mas estou aberto a sugestoes
Eu nunca criei um cursor precisava de uma ajuda pra construir algo do genero que refiro em cima....
tks
Respostas
-
Olá Collito,
Este exemplo deve resolver seu problema:
Code SnippetDECLARE
@Soma INT, @Preco NUMERIC (9,2), @Quant INTDECLARE
@Tbl (PrecoUnidade NUMERIC (9,2), Quantidades INT)DECLARE
Cur CURSOR FOR Select PrecoUnidade,Quantidades From tblEntradasOPEN
CurFETCH
NEXT FROM Cur INTO @Preco, @QuantSET
@Soma = @QuantWHILE
@@FETCH_STATUS = 0 AND @Quant <= 7BEGIN
INSERT INTO @Tbl VALUES (@Preco, @Quant) FETCH NEXT FROM Cur INTO @Preco, @Quant SET @Soma = @Soma + @QuantEND
SELECT * FROM @tbl
CLOSE
CurDEALLOCATE
CurQualquer dúvida, retorne.
Abraço
Todas as Respostas
-
Olá Collito,
Este exemplo deve resolver seu problema:
Code SnippetDECLARE
@Soma INT, @Preco NUMERIC (9,2), @Quant INTDECLARE
@Tbl (PrecoUnidade NUMERIC (9,2), Quantidades INT)DECLARE
Cur CURSOR FOR Select PrecoUnidade,Quantidades From tblEntradasOPEN
CurFETCH
NEXT FROM Cur INTO @Preco, @QuantSET
@Soma = @QuantWHILE
@@FETCH_STATUS = 0 AND @Quant <= 7BEGIN
INSERT INTO @Tbl VALUES (@Preco, @Quant) FETCH NEXT FROM Cur INTO @Preco, @Quant SET @Soma = @Soma + @QuantEND
SELECT * FROM @tbl
CLOSE
CurDEALLOCATE
CurQualquer dúvida, retorne.
Abraço
-
-
-
-
João,
O cursor é um recurso do SQL SERVER para processo que tenham de ser "loopados". É um implementação de loop teoricamente bem mais simples do que um While por exemplo, porém em termos de desempenho é um processio pesado e que a maioria dos DBA's evitam por ser danoso ao desempenho do banco. Sabe-se que o acesso a banco é feito por diversos programas , usuários simultaneamente então todo o processo pesado deve ser evitado. Entretanto existem casos que pode ser inevitável o uso do cursor. Pois bem, abaixo vou tentar explicar de maneira sussinta o uso do cursor:
DECLARANDO UM CURSOR - Perceba que ao declarar um cursor vc usa a seguinte sintáxe e nomeia o cursor com um nome a escolha. Ao se declarar um cursor vc automaticamente carrega um cursor com os dados. Essa "carregamento" nada mais é do um select com quantos campos vc achar necessário. NO caso do exemplo apenas um campo para facilitar as coisa
DECLARE
Cursor_Select CURSOR FOR SELECT vl_mascara_retorno + ' AS [' + CAST(id_atributo_versao_estrut_corp AS VARCHAR) + ']' FROM tb_atributo_versao_estrut_corp (NOLOCK) WHERE id_versao_estrut_corp_fk = @id_versao_estrut_corp_fk ORDER BY nu_ordem_disposicaoPRÓXIMO PASSO É ABRIR O CURSOR PARA O USO. Nada mais nada menos do que essa síntaxe:
OPEN
Cursor_SelectAGORA VAMOS ATRIBUIR VARIÁVEIS AO CURSOR. Perceba que quantos campos vc tiver declarado no select que carrega o cursor será a quantidade de variáveis atribuidas no cursor. Nesse exemplo como existe apenas um campo então haverá apenas uma variável. Lembrando que na declaração das variáveis o tipo deve ser idêntico ao campo da tabela. Caso seja diferente não esquecer de converter o valor.
--ATRIBUINDO VARIÁVEIS AOS CAMPOS DO CURSOR
FETCH
NEXT FROM Cursor_Select INTO @NomeCampoSelectAGORA VAMO COMEÇAR A TRABALHAR COM O CURSOR. Trabalhar com ele é simples. Basta iniciar o loop com uma variável global usada no cursor iniciar seu processo..
WHILE
@@FETCH_STATUS = 0BEGIN
.
. PROCESSO COMPLETO
.
END
Essa forma de usar o cursor é a mesma para todos os cursores. Se existe alguma outra forma não conheço. Repare que o processo está dentro de um BEGIN/END e a chamada da próxima linha é idêntica a chamada da primeira. Isso ocorre pois existe um processo que quem controla é justamente a variável @@FETCH_STATUS . Enquanto o resultado dela for 0 então existe processo. Sinceramente não sei o tipo de processo dela, vou ficar te devendo essa.. rsrsr
POR FIM QUANDO ACABAR O PROCESSO DO LOOP BASTA FECHAR O CURSOR E DESLOCAR DA MEMORIA. Esse processo é muito importante, pois eveita mais perda de desempenho por ter centenas de cursores abertos
-- FECHANDO E EXCLUINDO DA MEMÓRIA O CURSOR
CLOSE
Cursor_SelectDEALLOCATE
Cursor_SelectBem João, essa é uma explicação da minha mente e bem resumida, espero ter ajudado. Qualquer dúvida posta aí que respondemos.
Aos outros participantes se esqueci algum detalhes favor postem até mesmo para conhecimento.
Abraço a todos,
-
João Paulo,
Vou comentar o exemplo que postei.
Code Block-- Variáveis que irão receber os dados de cada registro
DECLARE
@Soma INT, @Preco NUMERIC (9,2), @Quant INT-- Tabela usada pro exemplo do colega, sem relação com cursor
DECLARE
@Tbl (PrecoUnidade NUMERIC (9,2), Quantidades INT)-- Criação do cursor
DECLARE
Cur CURSOR FOR-- Dados que vão para o cursor
Select
PrecoUnidade,Quantidades From tblEntradas-- Abertura do cursor
OPEN
Cur-- Joga os dados do primeiro registro nas variáveis
FETCH
NEXT FROM Cur INTO @Preco, @Quant-- só para o exemplo
SET
@Soma = @Quant-- laço, que irá passar registro por registro
WHILE
@@FETCH_STATUS = 0 AND @Quant <= 7BEGIN
END
SELECT
* FROM @tbl-- Fecha o cursor
CLOSE
Cur-- Libera memória
DEALLOCATE
CurQualquer coisa estamos aí.
Abraço
-
O que eu não estou entendo é que...
Quando eu entro com os parametros para executar a procedure ela vai me retornar um valor, certo? Onde este valor de retorno esta definido no código, esta é a questao que eu não estou entendo.
É nesta tabela temporaria ou tem outra forma de fazer?
Obrigado.