Ir para conteúdo
Fórum Script Brasil
  • 0

cursor não funciona executando a mesma proc 2 vezes


Zephyrus

Pergunta

Boa noite a Todos,

Esta é minha primeira postagem no forum.

Estou tentando criar uma procedure simples, que apenas lê registros de algumas tabelas e grava em uma tabela temporária que utilizo em seguida.

Porêm, tem acontecido um problema. Eu só consigo executar a procedure uma vez no programa que desenvolvi, quando executo a segunda vez, não escreve nenhum registro na tabela temporária.

Acredito ser algum problema com o @@Fetch_status que não está zerando após a execução da proc.

Já tentei fazer de tudo e nada funciona.

Segue o código que utilizo na minha procedure:

USE [Garma]
GO
/****** Object: StoredProcedure [dbo].[SPED_Layout_19] Script Date: 07/11/2012 22:19:54 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER Procedure [dbo].[SPED_Layout_19](@Tipo_Arquivo as varchar(255), @Data_Inicial varchar(255), @Data_Final varchar(255) )
as
begin

if object_id('tempdb.dbo.##TMPLayout19') is not null drop table ##TMPLayout19
create table ##TMPLayout19(linha varchar(MAX))

DECLARE @numnota varchar(10);
DECLARE @sequencial int;

set @numnota = 0;
set @sequencial = 1;

-- NOTAS
IF @Tipo_Arquivo = 'E' BEGIN

DECLARE _cur CURSOR FOR
SELECT N.Numnf FROM NFC N WHERE N.Datarec BETWEEN CONVERT(DATETIME,@Data_Inicial,103) AND CONVERT(DATETIME,@Data_Final,103)
OPEN _cur
WHILE @@FETCH_STATUS = 0 BEGIN
FETCH NEXT FROM _cur into @numnota
insert into ##TMPLayout19(linha)
(SELECT GIGANTE QUE FUNCIONA RSRS)
set @sequencial += 1;
END
close _cur;
DEALLOCATE _cur;
END

IF @Tipo_Arquivo = 'S' BEGIN

DECLARE _cur CURSOR FOR
SELECT N.Nota FROM Notas N WHERE N.Emissao BETWEEN CONVERT(DATETIME,@Data_Inicial,103) AND CONVERT(DATETIME,@Data_Final,103)
OPEN _cur
WHILE @@FETCH_STATUS = 0 BEGIN
FETCH NEXT FROM _cur into @numnota
insert into ##TMPLayout19(linha)
(SELECT GIGANTE QUE FUNCIONA RSRS)
set @sequencial += 1;
END
close _cur;
DEALLOCATE _cur;
END

end [/codebox]

Muito Obrigado a todos

Link para o comentário
Compartilhar em outros sites

3 respostass a esta questão

Posts Recomendados

  • 0

Bom dia Zephyrus,

Seja bem vindo ao Fórum!!

Olhei por alto a sua procedure. O que me chamou a atenção foi a criação da temporária com duas tralhas (##). Qual o significado:

# - temporária criada e existente apenas na instância criada. Ela existirá enquanto a instância estiver ativa.

## - temporária criada e existente / ativa nas instâncias. Ela existirá enquanto a instância em que foi criada estiver ativa.

Creio que o mais aconselhável seria a utilização de 1 tralha somente.

Outra forma de implementação mais comum é o teste da existência da tabela com a função IF EXISTS (ao invés da if object_id).

Vi também que o script poderá ser otimizado, excluindo as partes que estão duplicadas. Ficaria:

USE [Garma]
GO
/****** Object: StoredProcedure [dbo].[SPED_Layout_19] Script Date: 07/11/2012 22:19:54 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER Procedure [dbo].[SPED_Layout_19](@Tipo_Arquivo as varchar(255), @Data_Inicial varchar(255), @Data_Final varchar(255) )
as
begin

if object_id('tempdb.dbo.##TMPLayout19') is not null drop table ##TMPLayout19
create table ##TMPLayout19(linha varchar(MAX))

DECLARE @numnota varchar(10);
DECLARE @sequencial int;

set @numnota = 0;
set @sequencial = 1;

DECLARE _cur CURSOR FOR

-- NOTAS
IF @Tipo_Arquivo = 'E' BEGIN
SELECT N.Numnf FROM NFC N WHERE N.Datarec BETWEEN CONVERT(DATETIME,@Data_Inicial,103) 
AND CONVERT(DATETIME,@Data_Final,103)
END

IF @Tipo_Arquivo = 'S' BEGIN
SELECT N.Nota FROM Notas N WHERE N.Emissao BETWEEN CONVERT(DATETIME,@Data_Inicial,103) 
AND CONVERT(DATETIME,@Data_Final,103)
END 

OPEN _cur
WHILE @@FETCH_STATUS = 0 BEGIN
FETCH NEXT FROM _cur into @numnota
insert into ##TMPLayout19(linha)
(SELECT GIGANTE QUE FUNCIONA RSRS)
set @sequencial += 1;
END
close _cur;
DEALLOCATE _cur;
END

end

Link para o comentário
Compartilhar em outros sites

  • 0

Bom dia,

Obrigado pela rápida resposta.

Quanto a primeira pergunta, eu utilizo a tabela temporaria com 2 cerquilhas '##', pois após o término da procedure eu faço um select nesta tabela, e utilizando apenas uma cerquilha '#' tenho retorno de que a tabela não existe na base de dados.

Quanto a sua sugestão de remover um dos cursores, não pe possível pois o select que não copiei devido ao tamanho, caso a proc receba o parametro de tipo_arquivo = 'E' é feito em uma tabela e campos. Caso receba 'S' o select é em outra tabela, com outros campos.

esta procedure é responsável por retornar para um programa que desenvolvi em C# uma tabela de apenas uma coluna, contendo linhas que serão exportadas para um txt pelo programa, talvez esta não seja a melhor solução, mas foi a que imaginei ser a mais possível de ser feita com meu conhecimento.

Att.

Link para o comentário
Compartilhar em outros sites

  • 0

Ok, entendido. Desta forma a sua implementação está correta. A única estrutura que pode ser retirada dos 2 IF´s seria a declaração do cursor, seu fechamento e desalocação. O resto ficaria da mesma forma...

Não entendi ao certo o motivo da implementação do cursor. Após a criação, você dá um insert / select. você terá que passar em cada linha do cursor para realizar o insert?

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,3k
×
×
  • Criar Novo...