Re: [oracle_br] Re: Problema para gerar código ANO + Sequencial
Bom, para o DBMS_JOB afaik seria algo do tipo : declare jobno number; begin dbms_job.submit( jobno, 'BEGIN tuarotina; END;', to_date('01/01/2015', 'DD/MM/'), 'add_months(trunc(sysdate),12)'); end; / commit; ou seja, um ano depois data data inicial é somar 12 meses... Porém, já que vc tá na versão 10g iirc, nada te impede de usar o novo JOB SCHEDULER ao invés do velho JOB tradicional, ficaria tipo assim : BEGIN DBMS_SCHEDULER.CREATE_JOB(job_name=> 'nomedojob', job_type=> 'PLSQL_BLOCK', JOB_ACTION => 'BEGIN tua rotina; END;', repeat_interval => 'FREQ=YEARLY; BYMONTH=JAN; BYDAY=1', end_date=> NULL, enabled => TRUE); END; / Blz ??? Só plz ** teste antes ** e Pesquise na Documentação as SINTAXES exatas, pois os trechinhos aí de cima eu escrevi de cabeça, sem testar, okdoc ?? []s Chiappa
Re: [oracle_br] Ajuda Criar Função com Pragma
Eduardo, só uma obs em cima : o que o Alessandro falou é *** muito ***, mas MUITO Sério, mesmo : a questão é que no RDBMS Oracle automagicamente um SELECT enxerga os dados *** exatamente *** como eles estavam no instante X em que o SELECT começou a ser executado - mesmo que posteriormente em x+y vc faça o que fizer (UPDATE, DELETE, o que quiser!!! : e comite vc ou não os DMLs !!) , o SELECT vai mostrar os dados como estavam em X Exemplificando : imagine que a tua procedure disparou e startou o SELECT principal do report na tabela T às 10:00h, e esse SELECT é longo e demora uns bons minutos para executar... Aí, ainda com o SELECT sendo executado, as 10h01m (digamos) vc fez (via AUTONOMOUS TRANSACTION, que basicamente abre uma outra sessão independente da atual) um UPDATE nessa mesma tabela T - comite ou não vc esse UPDATE, a query que começou ás 1-h e está rodando ainda NÃO vai enxergar essa alteração, aí se ela faz digamos um COUNT, vc VAI SIM ter resultado diferente do real... Sim ??? Perigoso o bastante pra vc ??? Vc TEM que se assegurar que o UPDATE não interfere em nenhuma coluna sendo lida pela query, justamente sob pena da query em execução NÂO ver essas alterações... E veja que eu nem estou falando de acesso multi-usuário : veja vc, se vc deixar ** É CLARO ** que esse report que faz alterações VAI cedo ou tarde ser disparado 2x ao mesmo tempo por dois usuários diferentes da Aplicação, e aí, como faz ?? Lost update mais que provável, né não ?? ==> São esses tipos de coisa que temos que ter em mente antes de sair gambiarrando sem conhecer o mecanismo de transações e consistência de leitura do RDBMS Oracle, yep yep ??? Pelo que entendi, o que vc quer é que, cfrme os dados vão sendo lidos e impressos, faça-se um UPDATE para cada registro lido, certo ?? Normalmente, para evitar lost update o que se faz é SERIALIZAR o acesso, com SELECT FOR UPDATE ou com LOCK TABLE, e para permitir DMLs na procedure se vc dizer exatamente qual tool de report vc está usando quem usa a mesma pode dar a dica de como se faz isso na tool.. Praticamente todas as tools de Report realmente proíbem DMLs na procedure que alimenta a query mas Permitem triggers PRE/POST report e quetais... []s Chiappa
Re: [oracle_br] Re: Problema para gerar código ANO + Sequencial
Chiappa, o pessoal aqui optou pela sua sugestão. *A trigger de geração do código ficou assim:* DECLARE P_ANO NUMBER(4); P_CODIGO NUMBER(11); BEGIN --recupera o ano da data do cadastro da manifestação P_ANO := to_number(to_char(:NEW.DT_CADASTRO_MANIFESTACAO,'')); --forma o código P_CODIGO := TO_NUMBER(P_ANO || LPAD(seq_codigo.NEXTVAL,7,0)); :NEW.CODIGO := P_CODIGO; END; *Criamos uma procedure para dropar e recriar a sequence:* create or replace procedure recriar_seq_codigo as stmt varchar2(400) := ''; begin stmt := 'drop SEQUENCE ouvidoria.seq_codigo'; execute immediate stmt; stmt := 'CREATE SEQUENCE ouvidoria.seq_codigo INCREMENT BY 1 START WITH 1 MINVALUE 1 MAXVALUE 999 NOCYCLE NOORDER NOCACHE'; execute immediate stmt; end; *E criamos o job para chamar a procedure acima:* declare job_num integer; begin dbms_job.submit(job_num,'recriar_seq_codigo;',to_date('01/01/2015, 00:00:01', 'dd/mm/ hh24:mi:ss'),'sysdate + 1'); end; *No job acima, o parâmetro da periodicidade (último parâmetro) está como 'sysdate + 1', apenas para fins de teste. Vocês sabem a melhor forma de colocar o valor desse parâmetro para que ele seja executado anualmente, ou seja, todo dia 01 de janeiro, às 00:00:01?* Obrigado pela ajuda! Att, Aroldo Rique Em 22 de outubro de 2014 15:05, jlchia...@yahoo.com.br [oracle_br] < oracle_br@yahoogrupos.com.br> escreveu: > > > Vc até poderia dropar & recriar : é a opção mais direta mas muita gente > não gosta disso, especialmente por causa de consequências como invalidar > objetos dependentes da sequence. > Assim, embora o drop & create seja possível, se preferir optar por não o > fazer é SIM totalmente POSSÍVEL se obter o mesmo efeito sem drop : o que > ocorre é que, muito embora não haja um comando específico para se alterar o > valor corrente da sequence, é ** SIM ** possível se fazer outros tipos de > alteração na sequence que dão o mesmo efeito... > Aqui mesmo no fórum já demos alguns exemplos em threads anteriores, dá > uma pesquisada mas basicamente é temporariamente alterar a sequence para > ter um valor máximo E zerar quando esse valor é atingido, além de também > alterar o incremento para um valor bem alto : com isso feito, vc faz alguns > select nextval para ultrapassar o valor máximo que aí a sequence volta pra > zero Zerada a sequence, aí vc volta os settings dela para como estavam > antes... > > []s > >Chiappa > >
Re: [oracle_br] Ajuda Criar Função com Pragma
Vitor...já está assim. Alessandro, concordo..é gambiarra mesmo...solução de contorno emergencial... Em 28/10/2014 15:53, "Alessandro Lúcio Cordeiro da Silva alecordeirosi...@yahoo.com.br [oracle_br]" escreveu: > > > > > Boa tarde Eduardo, > > Eu no geral não vejo com bons olhos o uso do Pragma > Autonomuos_transaction, há situações sim que elas podem ser usadas, mas > geralmente uma exceção. > > O que ainda mais me preocura é você querer usar dentro de uma consulta, > olhe tecnicamente falando isso vaifuncionar, todavia isso beira a uma > gambiarra. Imagine a dificuldade que novos desenvolvedores/progamadores > terão de entender a "lógica" disso, sendo que esta logica quebra todo > conceito de consistência de leitura, ( a cada linha da consulta um commit, > então imagine a bagunça de outras consultas feitas durante a execução da 1º > consulta) e ainda que consultas SQL's não abrem transação. > > Eu fortemente recomendo que você reveja a sua lógica, e tente usar os > padrões de desenvolvimento para aumentar a coesão e diminuir o acoplamento, > senão você acaba tendo um sistema que parece uma linguiça. > > Alessandro Lúcio Cordeiro da Silva > Analista de Sistema > þ http://alecordeirosilva.blogspot.com/ > Porque esta é a vontade de Deus, a saber, a vossa > santificação: que vos abstenhais da prostituição. > (1º Tessalonicenses 4:3) > > > > Em Terça-feira, 28 de Outubro de 2014 13:13, "Eduardo Perdomo > panc...@gmail.com [oracle_br]" escreveu: > > > > Boa tarde. > > Tenho as seguintes tabelas: > > carregamentos > numcar data posicao etc > > pedidositens > codprod qtd valor numcar conferente > > O relacionamento entre as duas é numcar > > Preciso fazer uma função que quando eu passe o numero do carregamento o > conferente seja atualizado para todos os itens que estão nessa carga. > > Vários pedidositens podem estar no mesmo carregamento. Talvez tenha que > fazer um FOR EACH > > Vou usar esse função dentro de uma consulta em um relatorio, por isso o > pragma. > > Segue abaixo minha tentativa: > > CREATE OR REPLACE > FUNCTION liberacarregamento( yNUMCAR pedidositens.numcar%TYPE) RETURN > VARCHAR2 > IS > PRAGMA AUTONOMOUS_TRANSACTION; -- PARA PERMITIR DAR UPDATE EM UM SELECT > XNUMCAR pedidositens.numcar%TYPE; > BEGIN > BEGIN > UPDATE pedidositens SET conferente = 1 WHERE NUMCAR = yNUMCAR; > COMMIT; > > EXCEPTION > WHEN OTHERS THEN > RAISE_APPLICATION_ERROR(-20001, ('ERRO AO ATUALIZAR O > CARREGAMENTO: ' + to_char(XNUMCAR) ) ); > END; > RETURN xnumcar ; > END; > / > > > > > > > > > -- > > Eduardo Perdomo > Consultor de Implantação > Grupo PC Sistemas - www.grupopc.com.br > (21) 6845-8592 > panc...@gmail.com > eduardo.perd...@pcinformatica.com.br > Blog: eduardo.perdomo.nom.br > > > >
Re: [oracle_br] Ajuda Criar Função com Pragma
Olá, Desculpe, eu não encontrei a dúvida.Mas, interpretrei dessa forma:Você tem o número do carregamento em ambas as tabelas(o mesmo número).Você quer atualizar só o conferente na tabela pedidositens quando você passar o número do carregamento.Se for isso mesmo, porque não fazer só um update direto?Update pedidositens set conferente = n_conferente where carregamento = n_carregamento.Isso ai vai atualizar para todos os pedidositens daquele carregamento o número do conferente.Se não tem nada a ver com isso, desculpe a má interpretração. Em Terça-feira, 28 de Outubro de 2014 14:13, "Eduardo Perdomo panc...@gmail.com [oracle_br]" escreveu: Boa tarde. Tenho as seguintes tabelas: carregamentosnumcar data posicao etc pedidositenscodprod qtd valor numcar conferente O relacionamento entre as duas é numcar Preciso fazer uma função que quando eu passe o numero do carregamento o conferente seja atualizado para todos os itens que estão nessa carga. Vários pedidositens podem estar no mesmo carregamento. Talvez tenha que fazer um FOR EACH Vou usar esse função dentro de uma consulta em um relatorio, por isso o pragma. Segue abaixo minha tentativa: CREATE OR REPLACE FUNCTION liberacarregamento( yNUMCAR pedidositens.numcar%TYPE) RETURN VARCHAR2IS PRAGMA AUTONOMOUS_TRANSACTION; -- PARA PERMITIR DAR UPDATE EM UM SELECTXNUMCAR pedidositens.numcar%TYPE;BEGIN BEGIN UPDATE pedidositens SET conferente = 1 WHERE NUMCAR = yNUMCAR; COMMIT; EXCEPTION WHEN OTHERS THEN RAISE_APPLICATION_ERROR(-20001, ('ERRO AO ATUALIZAR O CARREGAMENTO: ' + to_char(XNUMCAR) ) ); END; RETURN xnumcar ;END;/ -- Eduardo PerdomoConsultor de ImplantaçãoGrupo PC Sistemas - www.grupopc.com.br (21) 6845-8592pancary@gmail.comeduardo.perd...@pcinformatica.com.brBlog: eduardo.perdomo.nom.br
Re: [oracle_br] Ajuda Criar Função com Pragma
Boa tarde Eduardo, Eu no geral não vejo com bons olhos o uso do Pragma Autonomuos_transaction, há situações sim que elas podem ser usadas, mas geralmente uma exceção. O que ainda mais me preocura é você querer usar dentro de uma consulta, olhe tecnicamente falando isso vaifuncionar, todavia isso beira a uma gambiarra. Imagine a dificuldade que novos desenvolvedores/progamadores terão de entender a "lógica" disso, sendo que esta logica quebra todo conceito de consistência de leitura, ( a cada linha da consulta um commit, então imagine a bagunça de outras consultas feitas durante a execução da 1º consulta) e ainda que consultas SQL's não abrem transação. Eu fortemente recomendo que você reveja a sua lógica, e tente usar os padrões de desenvolvimento para aumentar a coesão e diminuir o acoplamento, senão você acaba tendo um sistema que parece uma linguiça. Alessandro Lúcio Cordeiro da Silva Analista de Sistema þ http://alecordeirosilva.blogspot.com/ Porque esta é a vontade de Deus, a saber, a vossa santificação: que vos abstenhais da prostituição. (1º Tessalonicenses 4:3) Em Terça-feira, 28 de Outubro de 2014 13:13, "Eduardo Perdomo panc...@gmail.com [oracle_br]" escreveu: Boa tarde. Tenho as seguintes tabelas: carregamentos numcar data posicao etc pedidositens codprod qtd valor numcar conferente O relacionamento entre as duas é numcar Preciso fazer uma função que quando eu passe o numero do carregamento o conferente seja atualizado para todos os itens que estão nessa carga. Vários pedidositens podem estar no mesmo carregamento. Talvez tenha que fazer um FOR EACH Vou usar esse função dentro de uma consulta em um relatorio, por isso o pragma. Segue abaixo minha tentativa: CREATE OR REPLACE FUNCTION liberacarregamento( yNUMCAR pedidositens.numcar%TYPE) RETURN VARCHAR2 IS PRAGMA AUTONOMOUS_TRANSACTION; -- PARA PERMITIR DAR UPDATE EM UM SELECT XNUMCAR pedidositens.numcar%TYPE; BEGIN BEGIN UPDATE pedidositens SET conferente = 1 WHERE NUMCAR = yNUMCAR; COMMIT; EXCEPTION WHEN OTHERS THEN RAISE_APPLICATION_ERROR(-20001, ('ERRO AO ATUALIZAR O CARREGAMENTO: ' + to_char(XNUMCAR) ) ); END; RETURN xnumcar ; END; / -- Eduardo Perdomo Consultor de Implantação Grupo PC Sistemas - www.grupopc.com.br (21) 6845-8592 panc...@gmail.com eduardo.perd...@pcinformatica.com.br Blog: eduardo.perdomo.nom.br
[oracle_br] Ajuda Criar Função com Pragma
Boa tarde. Tenho as seguintes tabelas: carregamentos numcar data posicao etc pedidositens codprod qtd valor numcar conferente O relacionamento entre as duas é numcar Preciso fazer uma função que quando eu passe o numero do carregamento o conferente seja atualizado para todos os itens que estão nessa carga. Vários pedidositens podem estar no mesmo carregamento. Talvez tenha que fazer um FOR EACH Vou usar esse função dentro de uma consulta em um relatorio, por isso o pragma. Segue abaixo minha tentativa: CREATE OR REPLACE FUNCTION liberacarregamento( yNUMCAR pedidositens.numcar%TYPE) RETURN VARCHAR2 IS PRAGMA AUTONOMOUS_TRANSACTION; -- PARA PERMITIR DAR UPDATE EM UM SELECT XNUMCAR pedidositens.numcar%TYPE; BEGIN BEGIN UPDATE pedidositens SET conferente = 1 WHERE NUMCAR = yNUMCAR; COMMIT; EXCEPTION WHEN OTHERS THEN RAISE_APPLICATION_ERROR(-20001, ('ERRO AO ATUALIZAR O CARREGAMENTO: ' + to_char(XNUMCAR) ) ); END; RETURN xnumcar ; END; / -- Eduardo Perdomo Consultor de Implantação Grupo PC Sistemas - www.grupopc.com.br (21) 6845-8592 panc...@gmail.com eduardo.perd...@pcinformatica.com.br Blog: eduardo.perdomo.nom.br
[oracle_br] Re: Compilar report
Colega, na verdade ** de forma alguma ** 1000 linhas é um tamanho pequeno de rotina PL/SQL : veja por exemplo em https://asktom.oracle.com/pls/apex/f?p=100:11:0P11_QUESTION_ID:571023051648 que até a versão 8.1.x do PL/SQL (sendo que o Developer 6i iirc usa uma versão 8.0.x ainda anterior), vc tinha limites na qtdade de módulos DIANA de 32k que podia ter : ora, SE essas tais 1000 linhas tivessem uma média de 30 caracteres por linha (uma pela outra, não é um número tão incomum), se a minha matemática não falha só aí vc já tem quase 30kb, perigosamente próximo do limite Assim, para mim o que acontece aí é que esaas procs já eram grandes, estavam próximas dos limites do PL/SQL 8.0.x, mas casualmente não os tinham ultrapassado, mas numa manutenção recente os limites foram ultrapassados O fato de compilar & executar bem no banco de dados 11g (cuja versão de interpretador/"compilador" PL/SQL já não tem limites de 32kb por unidade, cfrme o link mostra) pra mim é uma pista Confirmando essa minha análise Então torno a repetir : sorry, mas 1000 linhas é SIM algo a ser conisderado "grande" em termos de PL/SQL (principalmente em se usando um interpretador/compilador de PL/SQL não tão recente), portanto cabe SIM otimização no sentido de reduzir ao máximo o tamanho total, E depois disso feito considere seriamente a possibilidade de transportar as procedures para o database, pois os limites PL/SQL do database são muito maiores, aí muito maior vai ser a sua margem de segurança []s Chiappa
[oracle_br] Re: Compilar report
A procedure está nas program units do report e o tamanho não é extraordinário. algo em torno de 1000 linhas. Se passo para o Banco e faço uma chamada no report funciona, mas o estranho é que sempre funcionou no report e parou de repente, acredito que esteja relacionado a memória. vou seguir investigando.
[oracle_br] Re: Compilar report
Opa, então, colega, a informação ** crucial ** para que a gente possa responder vc Não Deu, qual seja : as tais procedures grandes estão salvas/são executadas NO DATABASE ou NO REPORTS ??? Pois o Developer 6i possui um interpretador PL/SQL próprio, e assim sendo permite essa distinção, de se ter stored PL/SQLs tanto salvos/executados no database quanto no próprio Forms e/ou Reports De qquer maneira : se for procedure local, salva no próprio Reports, veja na Documentação que não temos Rigorosamente Nenhum parâmetro que afete o interpretador local, E além disso lembremos que o Developer 6i é um software de 32-bits, portanto só podendo acessar uma qtdade máxima fixa de memória e assim extremamente sujeito á erros de falta de memória por disputas com o Windows por posições baixas de RAM... Já SE a tal procedure for salva no database e executada pelo Reports a partir do database, aí TALVEZ aumentar PGA possa ajudar, mas garantia vc não tem... Sendo assim, a minha Recomendação é que : a) vc faça um tuning ** sério ** nessas procedures, otimizando-as o mais possível e enxugando a lógica das mesmas, de forma a lhes diminuir o tamanho ao máximo e b) após isso, quebre as maiores em varias sub-procedures : os limites do "compilador" de PL/SQL são no sentido de tamanho máximo de um stored program (seja procedure, function, etc) , e não na qtdade total de stored programs []s Chiappa
[oracle_br] Compilar report
Bom dia, Não consigo compilar alguns reports. Uso report 6i no banco 11g e reports com procedures muito grandes ele parou de compilar trancado no meio da compilação sem dar mensagem de erro. Se diminuo o tamanho da procedure ele compila. Sabem algum parâmetro que posso verificar? Att, Eduardo