[oracle_br] Re: MTMA -- Cursor para Update dentro de proc

2009-10-14 Por tôpico jlchiappa
Via de regra isso indica que OU o rowid da tabela mudou (por exemplo, foi feito 
algum tipo de MOVE nela), OU há um índice inválido/inusável apontando pra um 
ROWID que não existe mais, OU um cursor FOR UPDATE (que faz LOCKs) foi 
interrompido por um COMMIT enquanto aberto, coisas assim... Mostra aí o seu 
código e dá um exemplo (incluindo CREATE TABLEs e uns INSERTs pra preencher de 
dados) que a gente pode tentar reproduzir e dizer mais...

 []s

  Chiappa 

--- Em oracle_br@yahoogrupos.com.br, Matheus Malta de Aguiar  
escreveu
>
> Tô ligado... Mas acho que era esse o principal motivo.. pq ele tava
> atualizando somente e tão somente a primeira linha da tabela mesmo...
> 
> o objetivo do exercício era entender mais sobre um cursor e seu
> funcionamento...
> 
> Mesmo assim... valeu a dica em geral do pessoALL...
> 
> E valeu aí também Chiappa...
> 
> Agora... a PROC rodou mas ela retorna um erro.. ORA-01410 - INVALID ROWID
> 
> Se alguém souber mais sobre esse erro e quiser comentar, agradeço
> bastante...
> 
> Falows!
> 
> Matheus Malta
> 
> 2009/10/14 Evandro Giachetto 
> 
> >
> >
> > Eita.
> > Só falei do Fetch fora do laço Loop...
> > Agradeça ao Chiapa por todas essas dicas...
> >
> > =]
> >
> >
> > Att.
> > Evandro Giachetto
> > Oracle Certified Associate
> > evan...@... 
> >
> > 2009/10/14 Matheus Malta de Aguiar 
> > 
> > >
> >
> > >
> > >
> > > Obrigado Evandro...Valew mesmo...
> > >
> > > Vou testar essas dicas e te falo caso haja alguma outra novidade...
> > >
> > > Mesmo assim... Valew!
> > >
> > > Matheus
> > >
> > > 2009/10/14 jlchiappa  > 40yahoo.com.br>>
> >
> > >
> > > >
> > > >
> > > > Segue coments :
> > > >
> > > > >> ... posteriormente, a instrução WHERE CURRENT OF para q o valor a
> > ser
> > > > aplicado NÃO SEJA somente o do último ponteiro...
> > > >
> > > > reveja o código que vc nos enviou, pois nele ** NÃO ** está o WHERE
> > > CURRENT
> > > > OF, ok ??
> > > >
> > > >
> > > > > - A ausência do WHERE se dá pelo fato de que todas as linhas da
> > tabela
> > > > > deverão ser atualizadas.
> > > >
> > > > não, colega, não, pelo jeito vc não entendeu, vamos tentar de novo :
> > SEM
> > > um
> > > > WHERE qquer no UPDATE (poderia sim ser o WHERE CURRENT OF), o valor
> > > > lido/calculado na primeira linha do resultset do seu cursor vai ser
> > > gravado
> > > > EM TODOS OS REGISTROS da sua tabela, de uma vez só, é DUVIDOSO que seja
> > > isso
> > > > que vc quer A dedução que faço da sua lógica é que vc quer ler
> > dados
> > > da
> > > > linha 1 do cursor , fazer um cálculo e atualizar ESSA MESMA LINHA 1
> > > apenas
> > > > com o resultado, depois ler a linha 2 e atualizar APENAS ESSA LINHA 2
> > com
> > > o
> > > > novo valor, assim por diante, e rigorosamente NÂO É isso que o seu
> > UPDATE
> > > > sem WHERE faz, yes ??
> > > >
> > > > > - Repassei a instrução de FETCH para dentro do laço de LOOP e a proc
> > > > > recompilou normalmente... O problema é que, na hora de rodar, ele
> > > informa
> > > > > erro e indica q o cursor já está aberto... Como devo proceder nesses
> > > > casos?
> > > >
> > > > Ao vc fazer um cursor explícito (cursor 'manual'), com
> > OPEN/FETCH/CLOSE,
> > > >  necessariamente  a lógica é : abra UMA VEZ SÓ, repita o FETCH
> > > até
> > > > não haver mais registros (portanto apenas ELE está dentro do laço), e
> > só
> > > > quando todos foram lidos feche o cursor (portanto o CLOS está FORA do
> > > laço,
> > > > também... Ficaria + ou - assim :
> > > >
> > > > create or replace procedure aux.prc_teste_matheus
> > > > (v_erro out varchar2)
> > > >
> > > > is
> > > > v_rqr number;
> > > > v_dtf date;
> > > > --Criando o cursor para atualização da tabela
> > > > cursor mma_update is
> > > > select (date_key - rt_qtde_retorno) dt_final
> > > > from aux.teste_matheus
> > > > for update;
> > > > BEGIN
> > > > --Abrindo o cursor
> > > > open mma_update;
> > > > loop
> > > > --Obtendo os dados do cursor
> > > > fetch mma_update into v_dtf; --sair quando não houver informações
> > > > exit when mma_update%notfound;
> > > > --Atualizando a Tabela a partir dos valores obtidos
> > > > update aux.teste_matheus set dt_final = v_dtf WHERE CURRENT OF
> > > mma_update;
> > > > end loop;
> > > > --Fechando cursor
> > > > close mma_update;
> > > > --Salvando as informações
> > > > commit;
> > > > END;
> > > >
> > > > >> ululantemente óbvio, já que vc quis (para testes, ok) trabalhar
> > > com
> > > > Cursor, sempre há a figura do cursor IMPLÍCITO (cursor 'automático'),
> > > aonde
> > > > o OPEN/FETCH/CLOSE são feitos pra vc transparentemente, a VARIÁVEL DE
> > > > RETORNO é criada transparentemente, veja como realmente ficaria mais
> > > simples
> > > > :
> > > >
> > > > create or replace procedure aux.prc_teste_matheus_auto
> > > > (v_erro out varchar2)
> > > > is
> > > > BEGIN
> > > > --Abrindo o cursor
> > > > for v_dtf in ( select (date_key - rt_qtde_retorno) dt_final, rowid
> > > v_row_id
> > > > from aux.teste_matheus
> > > > )
> > > > loop
> > > > 

Re: [oracle_br] Re: MTMA -- Cursor para Update dentro de proc

2009-10-14 Por tôpico Matheus Malta de Aguiar
Tô ligado... Mas acho que era esse o principal motivo.. pq ele tava
atualizando somente e tão somente a primeira linha da tabela mesmo...

o objetivo do exercício era entender mais sobre um cursor e seu
funcionamento...

Mesmo assim... valeu a dica em geral do pessoALL...

E valeu aí também Chiappa...

Agora... a PROC rodou mas ela retorna um erro.. ORA-01410 - INVALID ROWID

Se alguém souber mais sobre esse erro e quiser comentar, agradeço
bastante...

Falows!

Matheus Malta

2009/10/14 Evandro Giachetto 

>
>
> Eita.
> Só falei do Fetch fora do laço Loop...
> Agradeça ao Chiapa por todas essas dicas...
>
> =]
>
>
> Att.
> Evandro Giachetto
> Oracle Certified Associate
> evan...@clickinterativa.com.br 
>
> 2009/10/14 Matheus Malta de Aguiar 
> 
> >
>
> >
> >
> > Obrigado Evandro...Valew mesmo...
> >
> > Vou testar essas dicas e te falo caso haja alguma outra novidade...
> >
> > Mesmo assim... Valew!
> >
> > Matheus
> >
> > 2009/10/14 jlchiappa  >  40yahoo.com.br>>
>
> >
> > >
> > >
> > > Segue coments :
> > >
> > > >> ... posteriormente, a instrução WHERE CURRENT OF para q o valor a
> ser
> > > aplicado NÃO SEJA somente o do último ponteiro...
> > >
> > > reveja o código que vc nos enviou, pois nele ** NÃO ** está o WHERE
> > CURRENT
> > > OF, ok ??
> > >
> > >
> > > > - A ausência do WHERE se dá pelo fato de que todas as linhas da
> tabela
> > > > deverão ser atualizadas.
> > >
> > > não, colega, não, pelo jeito vc não entendeu, vamos tentar de novo :
> SEM
> > um
> > > WHERE qquer no UPDATE (poderia sim ser o WHERE CURRENT OF), o valor
> > > lido/calculado na primeira linha do resultset do seu cursor vai ser
> > gravado
> > > EM TODOS OS REGISTROS da sua tabela, de uma vez só, é DUVIDOSO que seja
> > isso
> > > que vc quer A dedução que faço da sua lógica é que vc quer ler
> dados
> > da
> > > linha 1 do cursor , fazer um cálculo e atualizar ESSA MESMA LINHA 1
> > apenas
> > > com o resultado, depois ler a linha 2 e atualizar APENAS ESSA LINHA 2
> com
> > o
> > > novo valor, assim por diante, e rigorosamente NÂO É isso que o seu
> UPDATE
> > > sem WHERE faz, yes ??
> > >
> > > > - Repassei a instrução de FETCH para dentro do laço de LOOP e a proc
> > > > recompilou normalmente... O problema é que, na hora de rodar, ele
> > informa
> > > > erro e indica q o cursor já está aberto... Como devo proceder nesses
> > > casos?
> > >
> > > Ao vc fazer um cursor explícito (cursor 'manual'), com
> OPEN/FETCH/CLOSE,
> > >  necessariamente  a lógica é : abra UMA VEZ SÓ, repita o FETCH
> > até
> > > não haver mais registros (portanto apenas ELE está dentro do laço), e
> só
> > > quando todos foram lidos feche o cursor (portanto o CLOS está FORA do
> > laço,
> > > também... Ficaria + ou - assim :
> > >
> > > create or replace procedure aux.prc_teste_matheus
> > > (v_erro out varchar2)
> > >
> > > is
> > > v_rqr number;
> > > v_dtf date;
> > > --Criando o cursor para atualização da tabela
> > > cursor mma_update is
> > > select (date_key - rt_qtde_retorno) dt_final
> > > from aux.teste_matheus
> > > for update;
> > > BEGIN
> > > --Abrindo o cursor
> > > open mma_update;
> > > loop
> > > --Obtendo os dados do cursor
> > > fetch mma_update into v_dtf; --sair quando não houver informações
> > > exit when mma_update%notfound;
> > > --Atualizando a Tabela a partir dos valores obtidos
> > > update aux.teste_matheus set dt_final = v_dtf WHERE CURRENT OF
> > mma_update;
> > > end loop;
> > > --Fechando cursor
> > > close mma_update;
> > > --Salvando as informações
> > > commit;
> > > END;
> > >
> > > >> ululantemente óbvio, já que vc quis (para testes, ok) trabalhar
> > com
> > > Cursor, sempre há a figura do cursor IMPLÍCITO (cursor 'automático'),
> > aonde
> > > o OPEN/FETCH/CLOSE são feitos pra vc transparentemente, a VARIÁVEL DE
> > > RETORNO é criada transparentemente, veja como realmente ficaria mais
> > simples
> > > :
> > >
> > > create or replace procedure aux.prc_teste_matheus_auto
> > > (v_erro out varchar2)
> > > is
> > > BEGIN
> > > --Abrindo o cursor
> > > for v_dtf in ( select (date_key - rt_qtde_retorno) dt_final, rowid
> > v_row_id
> > > from aux.teste_matheus
> > > )
> > > loop
> > > --Obtendo os dados do cursor
> > > --Atualizando a Tabela a partir dos valores obtidos
> > > update aux.teste_matheus set dt_final = v_dtf.dt_final WHERE rowid =
> > > v_dtf.v_row_id;
> > > end loop;
> > > commit;
> > > END;
> > >
> > > Os conceitos TODOS que comentei/usei aqui estão muito bem definidos no
> > > manual Oracle de PL/SQL, ele deveria ser se já não é a tua fonte
> > > principal...
> > >
> > > []s
> > >
> > > Chiappa
> > >
> > >
> > > --- Em oracle_br@yahoogrupos.com.br 
> > >  40yahoogrupos.com.br> > 40yahoogrupos.com.br>,
>
> > > Matheus Malta de Aguiar  escreveu
> > > >
> > > > Obrigado pessoal pelas dicas...
> > > >
> > > > Gostaria de comentar algumas sugestões que talvez esclareçam melhor a
> > > > pergunta que eu fiz:
> > > >
> > > > - SIM, o select (que denomina o cursor) retorna dados;
> > > 

Re: [oracle_br] Re: MTMA -- Cursor para Update dentro de proc

2009-10-14 Por tôpico Evandro Giachetto
Eita.
Só falei do Fetch fora do laço Loop...
Agradeça ao Chiapa por todas essas dicas...

=]

Att.
Evandro Giachetto
Oracle Certified Associate
evan...@clickinterativa.com.br


2009/10/14 Matheus Malta de Aguiar 

>
>
> Obrigado Evandro...Valew mesmo...
>
> Vou testar essas dicas e te falo caso haja alguma outra novidade...
>
> Mesmo assim... Valew!
>
> Matheus
>
> 2009/10/14 jlchiappa >
>
> >
> >
> > Segue coments :
> >
> > >> ... posteriormente, a instrução WHERE CURRENT OF para q o valor a ser
> > aplicado NÃO SEJA somente o do último ponteiro...
> >
> > reveja o código que vc nos enviou, pois nele ** NÃO ** está o WHERE
> CURRENT
> > OF, ok ??
> >
> >
> > > - A ausência do WHERE se dá pelo fato de que todas as linhas da tabela
> > > deverão ser atualizadas.
> >
> > não, colega, não, pelo jeito vc não entendeu, vamos tentar de novo : SEM
> um
> > WHERE qquer no UPDATE (poderia sim ser o WHERE CURRENT OF), o valor
> > lido/calculado na primeira linha do resultset do seu cursor vai ser
> gravado
> > EM TODOS OS REGISTROS da sua tabela, de uma vez só, é DUVIDOSO que seja
> isso
> > que vc quer A dedução que faço da sua lógica é que vc quer ler dados
> da
> > linha 1 do cursor , fazer um cálculo e atualizar ESSA MESMA LINHA 1
> apenas
> > com o resultado, depois ler a linha 2 e atualizar APENAS ESSA LINHA 2 com
> o
> > novo valor, assim por diante, e rigorosamente NÂO É isso que o seu UPDATE
> > sem WHERE faz, yes ??
> >
> > > - Repassei a instrução de FETCH para dentro do laço de LOOP e a proc
> > > recompilou normalmente... O problema é que, na hora de rodar, ele
> informa
> > > erro e indica q o cursor já está aberto... Como devo proceder nesses
> > casos?
> >
> > Ao vc fazer um cursor explícito (cursor 'manual'), com OPEN/FETCH/CLOSE,
> >  necessariamente  a lógica é : abra UMA VEZ SÓ, repita o FETCH
> até
> > não haver mais registros (portanto apenas ELE está dentro do laço), e só
> > quando todos foram lidos feche o cursor (portanto o CLOS está FORA do
> laço,
> > também... Ficaria + ou - assim :
> >
> > create or replace procedure aux.prc_teste_matheus
> > (v_erro out varchar2)
> >
> > is
> > v_rqr number;
> > v_dtf date;
> > --Criando o cursor para atualização da tabela
> > cursor mma_update is
> > select (date_key - rt_qtde_retorno) dt_final
> > from aux.teste_matheus
> > for update;
> > BEGIN
> > --Abrindo o cursor
> > open mma_update;
> > loop
> > --Obtendo os dados do cursor
> > fetch mma_update into v_dtf; --sair quando não houver informações
> > exit when mma_update%notfound;
> > --Atualizando a Tabela a partir dos valores obtidos
> > update aux.teste_matheus set dt_final = v_dtf WHERE CURRENT OF
> mma_update;
> > end loop;
> > --Fechando cursor
> > close mma_update;
> > --Salvando as informações
> > commit;
> > END;
> >
> > >> ululantemente óbvio, já que vc quis (para testes, ok) trabalhar
> com
> > Cursor, sempre há a figura do cursor IMPLÍCITO (cursor 'automático'),
> aonde
> > o OPEN/FETCH/CLOSE são feitos pra vc transparentemente, a VARIÁVEL DE
> > RETORNO é criada transparentemente, veja como realmente ficaria mais
> simples
> > :
> >
> > create or replace procedure aux.prc_teste_matheus_auto
> > (v_erro out varchar2)
> > is
> > BEGIN
> > --Abrindo o cursor
> > for v_dtf in ( select (date_key - rt_qtde_retorno) dt_final, rowid
> v_row_id
> > from aux.teste_matheus
> > )
> > loop
> > --Obtendo os dados do cursor
> > --Atualizando a Tabela a partir dos valores obtidos
> > update aux.teste_matheus set dt_final = v_dtf.dt_final WHERE rowid =
> > v_dtf.v_row_id;
> > end loop;
> > commit;
> > END;
> >
> > Os conceitos TODOS que comentei/usei aqui estão muito bem definidos no
> > manual Oracle de PL/SQL, ele deveria ser se já não é a tua fonte
> > principal...
> >
> > []s
> >
> > Chiappa
> >
> >
> > --- Em oracle_br@yahoogrupos.com.br 
> >  40yahoogrupos.com.br>,
> > Matheus Malta de Aguiar  escreveu
> > >
> > > Obrigado pessoal pelas dicas...
> > >
> > > Gostaria de comentar algumas sugestões que talvez esclareçam melhor a
> > > pergunta que eu fiz:
> > >
> > > - SIM, o select (que denomina o cursor) retorna dados;
> > > - Eu já realizei o comando UPDATE direto, sem a utilização do cursor...
> e
> > vi
> > > que realmente ele dava certo.. Quis utilizar o cursor mais para fins
> > > didáticos (treinamento mesmo);
> > > - A ausência do WHERE se dá pelo fato de que todas as linhas da tabela
> > > deverão ser atualizadas. A coluna DT_FINAL foi inserida na tabela após
> a
> > sua
> > > criação e população. Esse comando eu estou fazendo apenas para fazer um
> > > UPDATE geral utilizando para isso um cursor, com comando FOR UPDATE (na
> > > declaração do cursor) e, posteriormente, a instrução WHERE CURRENT OF
> > para q
> > > o valor a ser aplicado NÃO SEJA somente o do último ponteiro.
> > > - Repassei a instrução de FETCH para dentro do laço de LOOP e a proc
> > > recompilou normalmente... O problema é que, na hora de rodar, ele
> informa
> > > erro e indica q o cursor já está abert

Re: [oracle_br] Re: MTMA -- Cursor para Update dentro de proc

2009-10-14 Por tôpico Matheus Malta de Aguiar
Obrigado Evandro...Valew mesmo...

Vou testar essas dicas e te falo caso haja alguma outra novidade...

Mesmo assim... Valew!

Matheus

2009/10/14 jlchiappa 

>
>
> Segue coments :
>
> >> ... posteriormente, a instrução WHERE CURRENT OF para q o valor a ser
> aplicado NÃO SEJA somente o do último ponteiro...
>
> reveja o código que vc nos enviou, pois nele ** NÃO ** está o WHERE CURRENT
> OF, ok ??
>
>
> > - A ausência do WHERE se dá pelo fato de que todas as linhas da tabela
> > deverão ser atualizadas.
>
> não, colega, não, pelo jeito vc não entendeu, vamos tentar de novo : SEM um
> WHERE qquer no UPDATE (poderia sim ser o WHERE CURRENT OF), o valor
> lido/calculado na primeira linha do resultset do seu cursor vai ser gravado
> EM TODOS OS REGISTROS da sua tabela, de uma vez só, é DUVIDOSO que seja isso
> que vc quer A dedução que faço da sua lógica é que vc quer ler dados da
> linha 1 do cursor , fazer um cálculo e atualizar ESSA MESMA LINHA 1 apenas
> com o resultado, depois ler a linha 2 e atualizar APENAS ESSA LINHA 2 com o
> novo valor, assim por diante, e rigorosamente NÂO É isso que o seu UPDATE
> sem WHERE faz, yes ??
>
> > - Repassei a instrução de FETCH para dentro do laço de LOOP e a proc
> > recompilou normalmente... O problema é que, na hora de rodar, ele informa
> > erro e indica q o cursor já está aberto... Como devo proceder nesses
> casos?
>
> Ao vc fazer um cursor explícito (cursor 'manual'), com OPEN/FETCH/CLOSE,
>  necessariamente  a lógica é : abra UMA VEZ SÓ, repita o FETCH até
> não haver mais registros (portanto apenas ELE está dentro do laço), e só
> quando todos foram lidos feche o cursor (portanto o CLOS está FORA do laço,
> também... Ficaria + ou - assim :
>
> create or replace procedure aux.prc_teste_matheus
> (v_erro out varchar2)
>
> is
> v_rqr number;
> v_dtf date;
> --Criando o cursor para atualização da tabela
> cursor mma_update is
> select (date_key - rt_qtde_retorno) dt_final
> from aux.teste_matheus
> for update;
> BEGIN
> --Abrindo o cursor
> open mma_update;
> loop
> --Obtendo os dados do cursor
> fetch mma_update into v_dtf; --sair quando não houver informações
> exit when mma_update%notfound;
> --Atualizando a Tabela a partir dos valores obtidos
> update aux.teste_matheus set dt_final = v_dtf WHERE CURRENT OF mma_update;
> end loop;
> --Fechando cursor
> close mma_update;
> --Salvando as informações
> commit;
> END;
>
> >> ululantemente óbvio, já que vc quis (para testes, ok) trabalhar com
> Cursor, sempre há a figura do cursor IMPLÍCITO (cursor 'automático'), aonde
> o OPEN/FETCH/CLOSE são feitos pra vc transparentemente, a VARIÁVEL DE
> RETORNO é criada transparentemente, veja como realmente ficaria mais simples
> :
>
> create or replace procedure aux.prc_teste_matheus_auto
> (v_erro out varchar2)
> is
> BEGIN
> --Abrindo o cursor
> for v_dtf in ( select (date_key - rt_qtde_retorno) dt_final, rowid v_row_id
> from aux.teste_matheus
> )
> loop
> --Obtendo os dados do cursor
> --Atualizando a Tabela a partir dos valores obtidos
> update aux.teste_matheus set dt_final = v_dtf.dt_final WHERE rowid =
> v_dtf.v_row_id;
> end loop;
> commit;
> END;
>
> Os conceitos TODOS que comentei/usei aqui estão muito bem definidos no
> manual Oracle de PL/SQL, ele deveria ser se já não é a tua fonte
> principal...
>
> []s
>
> Chiappa
>
>
> --- Em oracle_br@yahoogrupos.com.br ,
> Matheus Malta de Aguiar  escreveu
> >
> > Obrigado pessoal pelas dicas...
> >
> > Gostaria de comentar algumas sugestões que talvez esclareçam melhor a
> > pergunta que eu fiz:
> >
> > - SIM, o select (que denomina o cursor) retorna dados;
> > - Eu já realizei o comando UPDATE direto, sem a utilização do cursor... e
> vi
> > que realmente ele dava certo.. Quis utilizar o cursor mais para fins
> > didáticos (treinamento mesmo);
> > - A ausência do WHERE se dá pelo fato de que todas as linhas da tabela
> > deverão ser atualizadas. A coluna DT_FINAL foi inserida na tabela após a
> sua
> > criação e população. Esse comando eu estou fazendo apenas para fazer um
> > UPDATE geral utilizando para isso um cursor, com comando FOR UPDATE (na
> > declaração do cursor) e, posteriormente, a instrução WHERE CURRENT OF
> para q
> > o valor a ser aplicado NÃO SEJA somente o do último ponteiro.
> > - Repassei a instrução de FETCH para dentro do laço de LOOP e a proc
> > recompilou normalmente... O problema é que, na hora de rodar, ele informa
> > erro e indica q o cursor já está aberto... Como devo proceder nesses
> casos?
> >
> > O meu editor é o PL/SQL developer v 5.
> >
> > Grato!
> >
> > Matheus Malta
> >
> >
> > 2009/10/14 Evandro Giachetto 
> >
> > >
> > >
> > > E, achei desnecessário comentar alguns possíveis erros em seu código,
> como
> > > a
> > > falta de where na instrução update pois os colegas já os comentaram
> acima.
> > >
> > > De uma boa revisada na proc para ver se esses erros correspondem.
> > >
> > > Atenciosamente.
> > >
> > >
> > > Evandro Giachetto
> > > Oracle Certified Associate
> 

[oracle_br] Re: MTMA -- Cursor para Update dentro de proc

2009-10-14 Por tôpico jlchiappa
Segue coments :

>>  ... posteriormente, a instrução WHERE CURRENT OF para q o valor a ser 
>> aplicado NÃO SEJA somente o do último ponteiro...


reveja o código que vc nos enviou, pois nele ** NÃO ** está o WHERE CURRENT OF, 
ok ??

> - A ausência do WHERE se dá pelo fato de que todas as linhas da tabela
> deverão ser atualizadas. 

não, colega, não, pelo jeito vc não entendeu, vamos tentar de novo : SEM um 
WHERE qquer no UPDATE (poderia sim ser o WHERE CURRENT OF), o valor 
lido/calculado na primeira linha do resultset do seu cursor vai ser gravado EM 
TODOS OS REGISTROS da sua tabela, de uma vez só, é DUVIDOSO que seja isso que 
vc quer A dedução que faço da sua lógica é que vc quer ler dados da linha 1 
do cursor , fazer um cálculo e atualizar ESSA MESMA LINHA 1 apenas com o 
resultado, depois ler a linha 2 e atualizar APENAS ESSA LINHA 2 com o novo 
valor, assim por diante, e rigorosamente NÂO É isso que o seu UPDATE sem WHERE 
faz, yes ?? 

> - Repassei a instrução de FETCH para dentro do laço de LOOP e a proc
> recompilou normalmente... O problema é que, na hora de rodar,  ele informa
> erro e indica q o cursor já está aberto... Como devo proceder nesses casos?

Ao vc fazer um cursor explícito (cursor 'manual'), com OPEN/FETCH/CLOSE,  
necessariamente  a lógica é : abra UMA VEZ SÓ, repita o FETCH até não haver 
mais registros (portanto apenas ELE está dentro do laço), e só quando todos 
foram lidos feche o cursor (portanto o CLOS está FORA do laço, também... 
Ficaria + ou - assim :


create or replace procedure aux.prc_teste_matheus
(v_erro out varchar2)

is
   v_rqr number;
   v_dtf date;
--Criando o cursor para atualização da tabela
cursor mma_update is
  select (date_key - rt_qtde_retorno) dt_final
from aux.teste_matheus
 for update;
BEGIN
   --Abrindo o cursor
   open mma_update;
   loop
  --Obtendo os dados do cursor
  fetch mma_update into v_dtf;  --sair quando não houver informações
  exit when mma_update%notfound;
  --Atualizando a Tabela a partir dos valores obtidos
  update aux.teste_matheus set dt_final = v_dtf WHERE CURRENT OF mma_update;
   end loop;
   --Fechando cursor
   close mma_update;
   --Salvando as informações
   commit;
END;



>> ululantemente óbvio, já que vc quis (para testes, ok) trabalhar com 
Cursor, sempre há a figura do cursor IMPLÍCITO (cursor 'automático'), aonde o 
OPEN/FETCH/CLOSE são feitos pra vc transparentemente, a VARIÁVEL DE RETORNO é 
criada transparentemente, veja como realmente ficaria mais simples :

create or replace procedure aux.prc_teste_matheus_auto
(v_erro out varchar2)
is
BEGIN
   --Abrindo o cursor
   for v_dtf in (  select (date_key - rt_qtde_retorno) dt_final, rowid v_row_id
from aux.teste_matheus
 )
   loop
  --Obtendo os dados do cursor
  --Atualizando a Tabela a partir dos valores obtidos
  update aux.teste_matheus set dt_final = v_dtf.dt_final WHERE rowid = 
v_dtf.v_row_id;
   end loop;
   commit;
END;


 Os conceitos TODOS que comentei/usei aqui estão muito bem definidos no manual 
Oracle de PL/SQL, ele deveria ser se já não é a tua fonte principal...

 []s
 
   Chiappa
   

--- Em oracle_br@yahoogrupos.com.br, Matheus Malta de Aguiar  
escreveu
>
> Obrigado pessoal pelas dicas...
> 
> Gostaria de comentar algumas sugestões que talvez esclareçam melhor a
> pergunta que eu fiz:
> 
> - SIM, o select (que denomina o cursor) retorna dados;
> - Eu já realizei o comando UPDATE direto, sem a utilização do cursor... e vi
> que realmente ele dava certo.. Quis utilizar o cursor mais para fins
> didáticos (treinamento mesmo);
> - A ausência do WHERE se dá pelo fato de que todas as linhas da tabela
> deverão ser atualizadas. A coluna DT_FINAL foi inserida na tabela após a sua
> criação e população. Esse comando eu estou fazendo apenas para fazer um
> UPDATE geral utilizando para isso um cursor, com comando FOR UPDATE (na
> declaração do cursor) e, posteriormente, a instrução WHERE CURRENT OF para q
> o valor a ser aplicado NÃO SEJA somente o do último ponteiro.
> - Repassei a instrução de FETCH para dentro do laço de LOOP e a proc
> recompilou normalmente... O problema é que, na hora de rodar,  ele informa
> erro e indica q o cursor já está aberto... Como devo proceder nesses casos?
> 
> O meu editor é o PL/SQL developer v 5.
> 
> Grato!
> 
> Matheus Malta
> 
> 
> 2009/10/14 Evandro Giachetto 
> 
> >
> >
> > E, achei desnecessário comentar alguns possíveis erros em seu código, como
> > a
> > falta de where na instrução update pois os colegas já os comentaram acima.
> >
> > De uma boa revisada na proc para ver se esses erros correspondem.
> >
> > Atenciosamente.
> >
> >
> > Evandro Giachetto
> > Oracle Certified Associate
> > evan...@... 
> >
> > 2009/10/14 Evandro Giachetto 
> > 
> > >
> >
> >
> > > Você colocou o Fetch antes da instrução LOOP.
> > >
> > > Dessa forma, a variável v_dtf recebe apenas o primeiro registro do
> > cursor.
> > >
> > > Tente colocar o fetch dentro 

[oracle_br] Re: MTMA -- Cursor para Update dentro de proc

2009-10-14 Por tôpico jlchiappa
Colega, mesmo olhando só por cima, acho que a tua falha crítica está no trecho :

update aux.teste_matheus
set dt_final = v_dtf;

CADÊ O WHERE  Como nós sabemos, num UPDATE ou num DELETE se não filtrarmos 
os registros desejados o comando atual na tabela toda, e ** NÃO ** é isso que 
vc quer , vc quer fazer o update apenas no registro que acabou de ler, SEM um 
WHERE não haverá filtro algum a tabela toda vai ser atualizada 

E é claro, se não sabia fique sabendo que via de regra é  MUITO  mais 
performático em grandes volumes vc NÃO abrir loops, mas sim ter um único 
comando que já faça o que vc precisa :  em vc tendo recursos (tais como área de 
rollback suficiente), e a lógica o permitindo, não tem o que pensar...

 []s

  Chiappa

--- Em oracle_br@yahoogrupos.com.br, Matheus Malta de Aguiar  
escreveu
>
> Galera...
> 
> Estou tentando desenvolver uma proc que tem por objetivo atualizar uma
> coluna nova que acaba de ser acrescida na tabela, ou seja, ela (a coluna)
> econtra-se sem registros.
> 
> No entanto, quando do emprego do cursor (em tempo de execução) eu percebo
> que a proc está atualizando somente a primeira linha da tabela (ou seja,
> somente uma única célula).
> 
> Estou encaminhando a proc...
> 
> Quem puder ajudar, ficarei grato!
> 
> Valew pessoal!
> 
> Matheus Malta
> "O certo é certo mesmo q ninguém o faça.. e o errado é errado mesmo q todo
> mundo faça... Procure fazer o certo para não explicar porque resolveu fazer
> errado.. "
> 
> *PROC*
> 
> create or replace procedure aux.prc_teste_matheus
> (v_erro  out varchar2)
> 
> is
> --/*==*/
> --||  PROC DE TESTE   ||
> --||--||
> --|| AUTOR:   Matheus ||
> --|| MOTIVO:  Treino  ||
> --|| TABELA:  aux.teste_matheus   ||
> --/*==*/
> 
> 
> v_rqr   number;
> v_dtf   date;
> 
> --Criando o cursor para atualização da tabela
> cursor mma_update is
> select (date_key - rt_qtde_retorno) dt_final
> from aux.teste_matheus
> for update;
> 
> begin
> 
> --Abrindo o cursor
> open mma_update;
> 
> 
> --Obtendo os dados do cursor
> fetch mma_update into v_dtf;
> while mma_update%isopen loop
> --Atualizando a Tabela a partir dos valores obtidos
> update aux.teste_matheus
> set dt_final = v_dtf;
> 
> --sair quando não houver informações
> exit loop when mma_update%notfound;
> 
> --end loop;
> 
> --Fechando cursor
> close mma_update;
> --Salvando as informações
> commit;
> 
> -- Tratando os erros
> EXCEPTION
> 
> WHEN NO_DATA_FOUND  then
> v_erro := 'Parâmetro não encontrado!';
> dbms_output.put_line(v_erro);
> 
> WHEN OTHERS THEN
> v_erro := 'Procedimento não executado - Erro: '||SQLERRM;
> dbms_output.put_line(v_erro);
> end;
> 
> 
> [As partes desta mensagem que não continham texto foram removidas]
>