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 jlchia...@yahoo.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 oracle_br%40yahoogrupos.com.br,
 Matheus Malta de Aguiar maltamath...@... 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 evandrogiache...@...
 
  
  
   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...@... evandro%40clickinterativa.com.br
  
   2009/10/14 Evandro Giachetto evandrogiache...@...evandrogiachetto%
 

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 maltamath...@gmail.com



 Obrigado Evandro...Valew mesmo...

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

 Mesmo assim... Valew!

 Matheus

 2009/10/14 jlchiappa jlchia...@yahoo.com.br 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 
  oracle_br%40yahoogrupos.com.broracle_br%
 40yahoogrupos.com.br,
  Matheus Malta de Aguiar maltamath...@... 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 

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 evandrogiache...@gmail.com



 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 evandro%40clickinterativa.com.br

 2009/10/14 Matheus Malta de Aguiar 
 maltamath...@gmail.commaltamatheus%40gmail.com
 

 
 
  Obrigado Evandro...Valew mesmo...
 
  Vou testar essas dicas e te falo caso haja alguma outra novidade...
 
  Mesmo assim... Valew!
 
  Matheus
 
  2009/10/14 jlchiappa jlchia...@yahoo.com.br 
  jlchiappa%40yahoo.com.brjlchiappa%
 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 
   oracle_br%40yahoogrupos.com.broracle_br%
 40yahoogrupos.com.broracle_br%
  40yahoogrupos.com.br,

   Matheus Malta de Aguiar maltamath...@... 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