[oracle_br] Re: MTMA -- Cursor para Update dentro de proc
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
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
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
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
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
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] >