Usuário com melhor resposta
bloco begin try não executa rotina

Pergunta
-
tenho a seguinte estrutura:
create table #temp
(
ind int identity(1,1) primary key,
campo varchar(100)
)insert into #temp
(
campo
)
select valor from ##temp_unica where campo = 1set @id = 0;
select @id = id, @campo = campo from #temp where @id > id
ponto1:
begin tryWHILE @@ROWCOUNT > 0
BEGIN
--executa processosend
end trybegin CATCH
--executa rotina de erro
end CATCH
acontece que não está sendo executdo nada o bloco que está entre o begin try e end try. verifiquei também que a rotina não esta com erro.
tirei o bloco no begin try/end try e begin catch/end catch e roda tudo perfeitamente.
eu faço esse goto ponto1, porque como leio muitos registros, caso dê problema em algum deles eu gravo numa tabela de log e contiuo o processamento.
Respostas
-
na verdade fiz de outra forma. é bem mais rápido e não para o processamento caso ocorram erros. caso seja util o código está abaixo:
declare @Rows INT, @IdCol INT create table #temp ( id int identity(1,1) primary key, campo varchar(100) ) insert into #temp ( campo ) select campo from tabela SET @Rows = 1 SET @IdCol = 0 begin try WHILE @Rows > 0 begin select top 1 @IdCol = id, @campo = campo from #temp where id >= @IdCol order by id sET @Rows = @@ROWCOUNT --executa processo SET @IdCol += 1 end end begin CATCH --executa rotina de erro delete from #temp goto ponto1 end CATCH
- Marcado como Resposta rafa-martin quarta-feira, 12 de setembro de 2012 13:16
Todas as Respostas
-
Rafa, acredito que o problema esta no WHILE @@ROWCOUNT > 0, quando o begin try inicia o @@rowcount fica como 0, faça o teste e coloque um select @@rowcount antes do WHILE @@ROWCOUNT > 0 e voce verá que retornará 0, sendo que a condição é somente > 0, o bloco de codigo esta correto somente esta condição é que não esta deixando o bloco do codigo acontecer.
Alexandre Matayosi Conde Mauricio. Se esta sugestão for útil, por favor, classifique-a como útil. Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.
- Sugerido como Resposta Alexandre Matayosi terça-feira, 11 de setembro de 2012 15:58
-
Pra resolver isso você pode declarar uma variável inteira e atribuir a ela o @@RowCount, antes do GoTo. E usar esta variável no bloco Try.
Exemplo:
Update Top (1) Pessoa Set NmPessoa = NmPessoa Declare @LinhasAfetadas int = @@RowCount goto Ponto1 Print 'C' ponto1: begin try WHILE @LinhasAfetadas > 0 BEGIN Print 'A' --executa processos end end try begin CATCH Print 'B' --executa rotina de erro end CATCH
Roberson Ferreira - Database Developer
Acesse: www.robersonferreira.com.br
Email: contato@robersonferreira.com.brSe esta sugestão for útil, por favor, classifique-a como útil.
Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.- Sugerido como Resposta Roberson Ferreira _Moderator terça-feira, 11 de setembro de 2012 16:38
-
roberson fiz o que você sugeriu... mais parece que fica em loop infinito. pq tá executando o processo, só que a query continua executando.
declare @cont int
create table #temp
(
ind int identity(1,1) primary key,
campo varchar(100)
)insert into #temp
(
campo
)
select valor from ##temp_unica where campo = 1set @id = 0;
select @id = id, @campo = campo from #temp where @id > id
set @cont = @@rowcountponto1:
begin tryWHILE @cont > 0
BEGIN
--executa processosend
end trybegin CATCH
--executa rotina de erro
end CATCH
-
Sim, ficará em loop infinito mesmo, pois a variável @cont recebeu um determinado valor (exemplo, 10) e depois disso nunca mais foi alterada.
Roberson Ferreira - Database Developer
Acesse: www.robersonferreira.com.br
Email: contato@robersonferreira.com.brSe esta sugestão for útil, por favor, classifique-a como útil.
Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta. -
Ou você muda o valor desta variável dentro do While ou você muda o While para um If.
Exemplo:
While @cont > 0 Begin ... Seu código -- Aqui a gnt decrementa a variável. Qdo chegar a zero sairá do While Set @cont = @cont - 1 End
Com If:
If @cont > 0 Begin ... Seu código End
Roberson Ferreira - Database Developer
Acesse: www.robersonferreira.com.br
Email: contato@robersonferreira.com.brSe esta sugestão for útil, por favor, classifique-a como útil.
Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta. -
então eu vi que era isso. só que ela não deveria assumir o papel do @@rowcount já que foi atribuida o valor da mesma? porque o valor do @@rowcount também nunca irá mudar.
até porque a minha variável @cont sempre terá o valor igual 1, já que eu sempre pego 1 registro (e assim procesando as outras linhas)
ah uma coisa!!! o problema que se eu decrementar vai exeuctar apenas uma vez meu bloco dentro do while. porque a variável @cont sempre será 1. veja que faço p select top 1. dessa forma é mais ráppido ler todos os registros.
e como faria agora para ler todos os registros e sair do while quando terminar de ler.
quando uso @@rowcount sem o bloco begin try e begin catch processa todas as linhas que tenho sem problemas. e assim que termina de ler as linhas, sai do while.
- Editado rafa-martin terça-feira, 11 de setembro de 2012 17:32 r
-
Ela não assume o papel do @@RowCount: ela assume o valor do @@RowCount.
E o @@RowCount vai mudar dependendo da sintaxe que está no While. Se no While tiver um Update ou um Delete, @@RowCount irá mudar. Diferentemente do conteúdo da @cont, que só mudará se você alterar explicitamente.
Talvez você não precise de nada disso: a questão é: o que você quer fazer dentro do Try/Catch?
Por que você entende que precisa recuperar o @@RowCount pra fazer alguma coisa no Try/Catch?
Roberson Ferreira - Database Developer
Acesse: www.robersonferreira.com.br
Email: contato@robersonferreira.com.brSe esta sugestão for útil, por favor, classifique-a como útil.
Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta. -
veja meu código completo:
declare @cont int create table #temp ( ind int identity(1,1) primary key, campo varchar(100) ) insert into #temp ( campo ) select valor from ##temp_unica where campo = 1 set @id = 0; select @id = id, @campo = campo from #temp where @id > id set @cont = @@rowcount ponto1: begin try WHILE @cont > 0 BEGIN --executa processos select @id = id, @campo = campo from #temp where @id > id end end try begin CATCH --executa rotina de erro delete from #temp goto ponto1 end CATCH
na verdade meu while estava de outra forma, com o bloco begin try. acontece que vi que dava para melhorar a performance desse bloco (e realmente dá). coloquei esse bloco do begin try porque, caso ocorra algum erro durante a leitura das linhas (dentro do while), no bloco begin catch faço o tratamento do erro e volto para o bloco do while (veja que no begin catch tenho um goto ponto1). e assim vou lendo as linhas.
nesse while que mostrei é bem mais rápido o processamento das linhas (consideravelmente). o problema é que preciso gravar as linhas que irão dar problemas sem para o processamento. ou seja, processa tudo e as linhas com problema eu jogo num log (exatamente como eu estava fazendo).
tem alguma outra idéia de como posso fazer essa rotina (de guardar as linhas com erros e continuar o lendo as outras sem para o processamento)?
-
Não estou conseguindo entender o objetivo do seu código.
Exemplo:
Dentro do While você tem:
select @id = id, @campo = campo from #temp where @id > id
Você joga os campos para algumas variáveis, mas depois não faz nada com elas.
Me explica o porque do While. O que você quer selecionar na tabela?
Roberson Ferreira - Database Developer
Acesse: www.robersonferreira.com.br
Email: contato@robersonferreira.com.brSe esta sugestão for útil, por favor, classifique-a como útil.
Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta. -
na verdade eu uso sim. as variáveis, uso em inserts e updates que tem dentro no meu while.
o que preciso é processar todas as linhas. caso de algum erro eu jogo as mesmas num log e continuo o processamento. Ou seja, não pode parar o processamento se durante essa leitura ocorrem erros. por isso tinha feito o begin try. só que com esse while que postei não está sendo possível.
entendeu?
-
Entendi.
Mas o que você considera como erro? O que seria, na prática, um erro?
Roberson Ferreira - Database Developer
Acesse: www.robersonferreira.com.br
Email: contato@robersonferreira.com.brSe esta sugestão for útil, por favor, classifique-a como útil.
Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta. -
na verdade fiz de outra forma. é bem mais rápido e não para o processamento caso ocorram erros. caso seja util o código está abaixo:
declare @Rows INT, @IdCol INT create table #temp ( id int identity(1,1) primary key, campo varchar(100) ) insert into #temp ( campo ) select campo from tabela SET @Rows = 1 SET @IdCol = 0 begin try WHILE @Rows > 0 begin select top 1 @IdCol = id, @campo = campo from #temp where id >= @IdCol order by id sET @Rows = @@ROWCOUNT --executa processo SET @IdCol += 1 end end begin CATCH --executa rotina de erro delete from #temp goto ponto1 end CATCH
- Marcado como Resposta rafa-martin quarta-feira, 12 de setembro de 2012 13:16
-
Rafa, favor classificar as respostas.
Roberson Ferreira - Database Developer
Acesse: www.robersonferreira.com.br
Email: contato@robersonferreira.com.brSe esta sugestão for útil, por favor, classifique-a como útil.
Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.