sexta-feira, 7 de fevereiro de 2020

Objetos de banco com tag vermelha no Browser de Objetos

Olá,

algumas pessoas ficam intrigadas com o fato de no "Browser de objetos" aparecer uma tag vermelha indicando que o objeto está inválido.

Veja na figura abaixo um exemplo:



Este é um comportamento padrão do Oracle. Quando modificamos um objeto, os objetos dependentes ficam inválidos, pois o Oracle espera que a gente os recompile.

Se você tem certeza que a modificação que você fez, não terá impacto nos objetos dependentes, não fique preocupado com isso!

Quando a aplicação precisar utilizar este objeto "inválido" (na verdade ainda não recompilado), a primeira coisa que o Oracle fará automaticamente é a recompilação do objeto e, caso realmente esteja tudo certo, o objeto será utilizado normalmente!

Caso prefira, para remover a tag vermelha, você precisa recompilar o objeto!


Mas se houver muitos objetos, rode o script abaixo no Comandos SQL para recompilar todos os objetos inválidos (A execução pode demorar alguns segundos dependendo da quantidade de objetos inválidos):

BEGIN
DBMS_UTILITY.compile_schema(schema => :NOME_ESQUEMA, compile_all => false);
END;

Repare na imagem abaixo que a minha execução demorou mais de 6 segundos, mas este tempo pode ser maior dependendo do seu ambiente.





Para conferir os objetos que ainda permanecem inválidos (agora sim com provável erro), execute a seguinte consulta no Comandos SQL:

SELECT object_type,

       object_name,
       status
FROM   user_objects
WHERE  status = 'INVALID'
ORDER BY object_type, object_name;

Espero que tenha gostado!

Até a próxima!


sexta-feira, 6 de setembro de 2019

Erro: ORA-00001: unique constraint (APEX_XXXXXX,WWV_FLOW_PAGE_PLUG_IDX2) violated

Olá pessoal,

fizemos recentemente upgrade de versão do Oracle Apex.

Recomendamos a nossos desenvolvedores que atualizassem o tema nas aplicações que foram criadas antes do upgrade.

Ao tentar fazer a atualização do tema, seguindo os passos:

Shared Components > Themes > Universal Theme - 42 > "Refresh Theme"

Observação: Não esqueça de fazer uma cópia da aplicação antes dessa operação!

Ocorre o erro título deste post:


Esse é uma constraint interna do Apex "APEX_XXXXXX.WWV_FLOW_PAGE_PLUG_IDX2" e utiliza uma nomenclatura que depende do conhecimento do histórico do Apex para poder decifrar.


  • APEX_XXXXXX é o owner que armazena os metadados do Apex. O XXXXXX é o número da versão. Se sua versão for Apex 19.1, então aparecerá APEX_190100.
  • WWV quer dizer que estará visível na internet (www). Há 20 anos não era comum aplicações disponibilizar informações na internet!
  • FLOW era o nome original da tecnologia que atualmente conhecemos como Apex. Veja que a ideia inicial era implementar "Fluxos de trabalho" (Flows).
  • PAGE_PLUG é como as regiões são conhecidas internamente.
Portanto, o erro está dizendo que há um problema de constraint única em alguma região do Tema.


Para descobrir o problema, vamos em "Shared Components" > "Templates" e filtrar pelo Type = "Region".

Além disso, vá em "Actions" do relatório e mova para a direita "Display in Report" todas as colunas.

Veja no relatório que há um template que está definido localmente, ou seja, não está inscritos no Tema (Coluna "Subscribed From" nula) e que possui o mesmo nome (Coluna "Name" = "Standard") de um template padrão do Apex.



A solução para o problema foi renomear o Template localmente definido "Standard" (que está com o mesmo nome de um template padrão do Apex) e o refresh do Tema funcionou bem!!!

Espero que tenha sido útil!

Até a próxima!

quarta-feira, 12 de junho de 2019

GUOB Tech Day - Oracle Groundbreakers Latin America Tour 2019


Estão abertas as inscrições para a 10ª edição do principal evento do Grupo de Usuários Oracle do Brasil: GUOB Tech Day. Este evento faz parte do Oracle Groundbreakers Latin America Tour que percorrerá diversos países da América Latina com palestrantes renomados da tecnologia Oracle.

A conferência ocorrerá no dia 10 de agosto na Universidade Nove de Julho - UNINOVE em São Paulo - SP.

Farei uma apresentação sobre Ações dinâmicas no Oracle Apex. A agenda completa pode ser vista no link: https://guobtechday2019.eventize.com.br/index.php?pagina=3

Inscrições pelo site: https://guobtechday2019.eventize.com.br/index.php?inscricao

sexta-feira, 8 de março de 2019

Busca ignorando acentuação em relatórios

Olá pessoal,

hoje vamos falar sobre como fazer para a busca no Apex ignorar a acentuação das palavras, o til e a cedilha.

Se criarmos uma aplicação utilizando a configuração padrão e buscarmos no relatório interativo pelo termo 'Jose' (sem acento!), não há dados encontrados conforme imagem abaixo.



Entretanto, se buscarmos pelo termo 'José' (com acento)  resultados são apresentados.



Isso é muito chato para o usuário, pois é difícil saber quando um nome foi escrito com ou sem acento. Não é mesmo?

Para resolver isto, basta seguir os seguintes passos:

Passo 1) Em Componentes Compartilhados,  clique em "Atributos de Globalização".

Globalizacao.png


Passo 2)  No campo "Comparação de Valor do Caractere" digite "BINARY_AI" e no campo "Procedimento de Comparação de Valor do Caractere" selecione "Linguístico".

Valores.png

Passo 3) Clique em "Aplicar Alterações"


Nota: a função não funciona para o item "Campo de Texto com preenchimento automático" (“Text Field with autocomplete”)

Agora ao pesquisar por "Jose" (sem acento), repare que aparecem resultados. 

Essa configuração resolve também o problema da cedilha e do til.

Espero que tenha gostado!
Até a próxima.

domingo, 30 de setembro de 2018

Criando colunas de auditoria em tabelas Oracle

Olá pessoal,

é comum a inclusão de colunas de auditoria quando se cria um sistema.

As colunas de auditoria são as que armazenam informações sobre a criação e alteração do registro que se encontra na tabela. Os nomes de coluna mais comuns em Português são: CRIADO_POR, CRIADO_EM, ALTERADO_POR e ALTERADO_EM.

Primeiramente temos que criar essas 4 colunas em todas as tabelas (Caso já não existam).

Calma! Você não precisará entrar em todas as suas dezenas (ou centenas) de tabelas e alterar.

Segue um script para fazer esta atividade de forma automática.

Copie e cole o script abaixo no Comandos SQL e pressione "Executar" (ou "Run")

--------------------INICIO SCRIPT---------------------
----------------Inclui colunas de auditoria-------------
BEGIN

FOR cur IN (select * from user_tables) LOOP

   EXECUTE IMMEDIATE 'alter table ' || cur.table_name || ' add (CRIADO_POR VARCHAR2(255))';
   EXECUTE IMMEDIATE 'alter table ' || cur.table_name || ' add (CRIADO_EM DATE)';
   EXECUTE IMMEDIATE 'alter table ' || cur.table_name || ' add (ALTERADO_POR VARCHAR2(255))';
   EXECUTE IMMEDIATE 'alter table ' || cur.table_name || ' add (ALTERADO_EM DATE)';

END LOOP;

END;
------------------------FIM SCRIPT-------------------------

Ao final da execução, aparecerá uma mensagem de sucesso, conforme imagem abaixo.



Para ter certeza de que deu certo, vá ao Browser de Objetos e confira se as colunas foram criadas.



A melhor maneira de garantir que suas colunas de auditoria serão preenchidas corretamente, é por meio de trigger no banco de dados.

Para facilitar o trabalho, segue um script que cria as triggers para as tabelas com tamanho menor que 26 (As tabelas com tamanho maior que 26 deverão ser criadas manualmente).

O script deve ser executado no Comandos SQL também.

Observação: O trecho que utiliza APEX$SESSION funciona apenas a partir do Apex 5, portanto deve ser alterado para versões anteriores do Apex.

--------------------INICIO SCRIPT---------------------
DECLARE
   v_comando VARCHAR2(4000);

BEGIN

FOR cur IN (select * from user_tables where length(table_name) <=26) LOOP 
   v_comando := 'create or replace trigger BIU_'||cur.table_name||' before insert or update on "'||cur.table_name||'" 
for each row 
begin
    if inserting then
        :new.criado_em := sysdate;
        :new.criado_por := nvl(sys_context(''APEX$SESSION'',''APP_USER''),user);
    end if;
    :new.alterado_em := sysdate;
    :new.alterado_por := nvl(sys_context(''APEX$SESSION'',''APP_USER''),user);
end;';
htp.p(v_comando);
EXECUTE IMMEDIATE v_comando;

END LOOP;

END;
------------------------FIM SCRIPT-------------------------

Verifique se o comando foi executado corretamente. Você pode ir também ao Browser de Objetos e conferir se as triggers foram criadas sem problemas.


Para verificar quais tabelas devem ter as triggers criadas  manualmente, execute o SELECT abaixo no Comandos SQL.

select * from user_tables where length(table_name) >26


Utilize o CREATE TRIGGER abaixo no Comandos SQL substituindo as tags <<nome_tabela_abreviada>> e <<nome_tabela>> pelo nome desejado.

create or replace trigger BIU_<<nome_tabela_abreviado>> before insert or update on <<nome_tabela>> 
for each row 
begin
    if inserting then
        :new.criado_em := sysdate;
        :new.criado_por := nvl(sys_context('APEX$SESSION','APP_USER'),user);
    end if;
    :new.alterado_em := sysdate;
    :new.alterado_por := nvl(sys_context('APEX$SESSION','APP_USER'),user);
end; 

Pronto! Agora basta inserir algum registro por algum formulário ou fazer algum comando DML diretamente no banco que as colunas serão preenchidas.

Espero que tenha gostado!

Até a próxima.

quinta-feira, 21 de junho de 2018

O que é essa tabela HTMLDB_PLAN_TABLE? Posso apagar?

Olá pessoal,

hoje vamos falar sobre a tabela HTMLDB_PLAN_TABLE que aparecem em esquemas Oracle associados a algum workspace do Apex.

Afinal, para que serve esta tabela? Posso apagá-la?

Ao realizar uma busca por HTMLDB_PLAN_TABLE na documentação da Oracle e do Apex: No results found.

Caso a tabela HTMLDB_PLAN_TABLE já exista, execute o comando de dropar e após isso faça uma consulta para confirmar a não existência.
Observe que o Comandos SQL informa que "a tabela ou view não existe", quando um comando de SELECT é executado.

Seguem os comandos executados:
DROP TABLE htmldb_plan_table;
SELECT * FROM htmldb_plan_table;

Após isso, digite um comando de SELECT qualquer. Utilizei o comando abaixo:

SELECT * 
FROM emp e
JOIN dept d ON e.deptno = d.deptno

Clique em "Explicação" e verifique que o Comandos SQL apresenta o resultado equivalente ao Explain Plan da Oracle.
Veja referência para o Explain Plan na documentação da Oracle: https://docs.oracle.com/database/121/SQLRF/statements_9010.htm#SQLRF01601
Caso prefira um artigo em português, segue o do colega Tércio Costa (Oracle ACE Associate):  https://oraclepress.wordpress.com/2017/01/16/explain-plan/


Após isso, veja que o Apex criou a tabela htmldb_plan_table com o resultado do explain plan.

Conclusão

A tabela HTMLDB_PLAN_TABLE é utilizada pelo Apex para armazenar os resultados da "Explicação" (Explain plan) de consultas e pode ser apagado sem medo.

quarta-feira, 9 de maio de 2018

Cursos de Oracle SQL grátis

Olá pessoal,
quando fiquei sabendo da notícia não pude deixar de compartilhar aqui no blog.
No Oracle Dev Gym há dois cursos de SQL gratuitos de excelente qualidade.
Só por curiosidade, repare na URL do Dev Gym e perceba que o site foi todo desenvolvido utilizando o Oracle Application Express... YAAA


Para dar uma ideia da qualidade, o curso é oferecido pela Oracle e ministrado pelo instrutor Chris Saxon (do site "Ask Tom" e do "Magic of SQL").
Para quem é desenvolvedor Apex, o conhecimento de SQL é fundamental! Sugiro investir um tempinho para realizá-los.
Para quem tem dificuldade com o inglês, infelizmente os cursos não estão disponíveis em português, mas pode ser adicionada uma legenda, pois os vídeos estão no YouTube.
O primeiro treinamento chamado de "Databases for Developers: Foundations" está disponível na forma "On Demand". Este curso é mais básico e pode ser encontrado no seguinte link: https://devgym.oracle.com/devgym/database-for-developers.html
Está sendo lançado agora o "Databases for Developers: Next Level" que iniciará no dia 14 de maio de 2018 e permite ajudar a melhorar as habilidades com Oracle SQL. Este curso possui certificado desde que você complete todos os exercícios de maneira satisfatória e está disponível no seguinte link: https://devgym.oracle.com/pls/apex/dg/class/databases-for-developers-next-level.html
Deixe seu comentário sobre o que achou dos cursos.

Bons estudos!