<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Valter Zanchetti Filho</title>
    <description>The latest articles on DEV Community by Valter Zanchetti Filho (@valter_filho_24448308265f).</description>
    <link>https://dev.to/valter_filho_24448308265f</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3155751%2F96fb71e8-29f6-4fa7-b62d-c18eecc7be82.jpg</url>
      <title>DEV Community: Valter Zanchetti Filho</title>
      <link>https://dev.to/valter_filho_24448308265f</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/valter_filho_24448308265f"/>
    <language>en</language>
    <item>
      <title>Reativar automations específicas após update da aplicação no Oracle APEX</title>
      <dc:creator>Valter Zanchetti Filho</dc:creator>
      <pubDate>Mon, 20 Oct 2025 01:05:30 +0000</pubDate>
      <link>https://dev.to/valter_filho_24448308265f/reativar-automations-especificas-apos-update-da-aplicacao-no-oracle-apex-2cnj</link>
      <guid>https://dev.to/valter_filho_24448308265f/reativar-automations-especificas-apos-update-da-aplicacao-no-oracle-apex-2cnj</guid>
      <description>&lt;p&gt;Uma coisa que as vezes é um pouco irritante é o fato de que o APEX desativa todas as automations depois que a aplicação é sobrescrita por uma nova versão.&lt;/p&gt;

&lt;p&gt;Eu costumo automatizar boa parte do pipeline de geração e aplicação de release de objetos de bancos de dados e apps em outros servidores e percebi que, por padrão, as automations são sempre desativadas após o update do app.&lt;/p&gt;

&lt;p&gt;Para contornar esse problema, fiz o script abaixo, que é rodado após o update bem sucedido de cada aplicação. Você pode modificar para as suas necessidades colocando cada uma das automations que você tem interesse em reativar. Você também pode modificar o script a seu critério.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;SERVEROUTPUT&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt;

&lt;span class="k"&gt;BEGIN&lt;/span&gt;
    &lt;span class="n"&gt;apex_util&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_workspace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'YOUR_WORKSPACE_NAME'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;apex_session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_session&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;p_app_id&lt;/span&gt;   &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;117&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="c1"&gt;--App ID &lt;/span&gt;
        &lt;span class="n"&gt;p_page_id&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="c1"&gt;--Any Page in the App&lt;/span&gt;
        &lt;span class="n"&gt;p_username&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'VALTER'&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;-- Any valid APEX User&lt;/span&gt;

    &lt;span class="c1"&gt;--Enable specific automation&lt;/span&gt;
    &lt;span class="n"&gt;apex_automation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;p_application_id&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;117&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;--App Id&lt;/span&gt;
        &lt;span class="n"&gt;p_static_id&lt;/span&gt;       &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'emitir-espelho-retorno-nf'&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;-- Static id&lt;/span&gt;

     &lt;span class="c1"&gt;--Destroying the session&lt;/span&gt;
    &lt;span class="n"&gt;apex_session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delete_session&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você também pode fazer um loop simples para rodar em todas as suas automations ou criar alguma outra lógica se baseando no select dessa view:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;APEX_APPL_AUTOMATION&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fontes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.oracle.com/en/database/oracle/apex/24.1/aeapi/APEX_AUTOMATION_ENABLE-Procedure.html" rel="noopener noreferrer"&gt;https://docs.oracle.com/en/database/oracle/apex/24.1/aeapi/APEX_AUTOMATION_ENABLE-Procedure.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>oracleapex</category>
    </item>
    <item>
      <title>Recuperando dados no Oracle (sem envolver o DBA) com FlashBack Query</title>
      <dc:creator>Valter Zanchetti Filho</dc:creator>
      <pubDate>Tue, 14 Oct 2025 15:14:51 +0000</pubDate>
      <link>https://dev.to/valter_filho_24448308265f/recuperando-dados-no-oracle-com-flashback-query-o44</link>
      <guid>https://dev.to/valter_filho_24448308265f/recuperando-dados-no-oracle-com-flashback-query-o44</guid>
      <description>&lt;p&gt;Sabe quando você faz aquela &lt;strong&gt;trapalhada épica&lt;/strong&gt;, dá um &lt;code&gt;UPDATE&lt;/code&gt; na tabela sem &lt;code&gt;WHERE&lt;/code&gt; e ainda estava tão confiante que mandou um &lt;code&gt;COMMIT&lt;/code&gt; logo em seguida? Pois é. Acontece. E quando o usuário altera ou apaga um monte de registros que não deveria? A primeira reação é ligar pro DBA, pedir pra restaurar o último backup, rezar pro RMAN... Mas nem sempre precisa chegar a tanto.&lt;/p&gt;

&lt;p&gt;Existe um caminho mais simples — em muitos casos, &lt;strong&gt;muito mais fácil&lt;/strong&gt;: o &lt;strong&gt;Flashback Query&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Mesmo sendo um recurso já bastante conhecido, vale a pena relembrar. Com ele, o Oracle consegue &lt;strong&gt;reconstruir o estado anterior das linhas&lt;/strong&gt; usando os dados armazenados no &lt;strong&gt;UNDO&lt;/strong&gt;. Em outras palavras, ele “volta no tempo” aplicando as mudanças inversas registradas ali.&lt;/p&gt;

&lt;p&gt;E o melhor: até onde sei, esse recurso &lt;strong&gt;vem habilitado por padrão&lt;/strong&gt; e é coisa antiga, então dificilmente você vai ter complicações para utilizá-lo.&lt;/p&gt;

&lt;p&gt;Vamos direto ao ponto. Abaixo estão duas queries para comparação:&lt;br&gt;&lt;br&gt;
Uma consulta &lt;strong&gt;normal&lt;/strong&gt;, com os &lt;strong&gt;resultados atuais&lt;/strong&gt;, e outra usando &lt;strong&gt;Flashback Query&lt;/strong&gt; para pegar os &lt;strong&gt;dados de 30 minutos atrás&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Você pode testar isso no seu próprio banco criando uma tabela, inserindo alguns registros, anotando o horário em que removeu os dados e depois executando o &lt;code&gt;SELECT&lt;/code&gt; com o intervalo anterior.&lt;/p&gt;
&lt;h3&gt;
  
  
  Exemplo do uso
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;--Normal query with current results&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;PEDIDO&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;ID_PEDIDO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3487&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;--Flashback query retrieving results from 30 minutes ago&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;PEDIDO&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;OF&lt;/span&gt; &lt;span class="nb"&gt;TIMESTAMP&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SYSTIMESTAMP&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="s1"&gt;'30'&lt;/span&gt; &lt;span class="k"&gt;MINUTE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;ID_PEDIDO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3487&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Ótimo. Agora quero recuperar os registros que eu apaguei. Também é fácil.&lt;/p&gt;
&lt;h3&gt;
  
  
  Fazendo um insert com base nos dados de 30 minutos atrás
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;PEDIDO&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;PEDIDO&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;OF&lt;/span&gt; &lt;span class="nb"&gt;TIMESTAMP&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SYSTIMESTAMP&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="s1"&gt;'30'&lt;/span&gt; &lt;span class="k"&gt;MINUTE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;ID_PEDIDO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3487&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;COMMIT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;É SÓ ISSO MESMO.&lt;/p&gt;

&lt;p&gt;O artigo poderia acabar aqui. Caso você esteja um pouco mais curioso, pode continuar lendo o conteúdo abaixo. Você só vai conseguir seguir na parte abaixo se tiver privilégios de DBA.&lt;/p&gt;


&lt;h3&gt;
  
  
  Ver os parâmetros
&lt;/h3&gt;

&lt;p&gt;Ah, legal. Agora quero saber qual o tempo de retenção (teórico) que eu tenho configurado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SHOW&lt;/span&gt; &lt;span class="k"&gt;PARAMETER&lt;/span&gt; &lt;span class="n"&gt;undo_retention&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ele vai te mostrar o valor em segundos. No meu caso está em 86.400 segundos, que significa 1.440 minutos ou 24 horas. É importante lembrar que esse valor é teorico. Por padrão, sempre que o banco precisar de espaço de undo, ele não vai respeitar o tempo de retenção informado, exceto se você tiver informado que ele deve garantir esse tempo. Para saber, vamos a seguinte query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;tablespace_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;retention&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;dba_tablespaces&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;contents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'UNDO'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ Se estiver &lt;code&gt;GUARANTEE&lt;/code&gt;, o tempo de retenção é respeitado obrigatoriamente.&lt;br&gt;&lt;br&gt;
⚠️ Se estiver &lt;code&gt;NOGUARANTEE&lt;/code&gt;, o Oracle pode sobrescrever os dados de undo antes do tempo, se precisar de espaço.&lt;/p&gt;
&lt;h3&gt;
  
  
  Garantir a retenção
&lt;/h3&gt;

&lt;p&gt;Se quiser garantir que o Flashback Query funcione sempre até o limite configurado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ALTER TABLESPACE undotbs1 RETENTION GUARANTEE;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Eu não recomendaria fazer isso, porque se ele precisar respeitar o tempo de retenção e precisar de espaço de undo ao mesmo tempo e não encontrar, o banco vai estourar erro.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ajustar o tempo de retenção
&lt;/h3&gt;

&lt;p&gt;Aqui neste exemplo estamos colocando um tempo de retenção de 3600 segundos, ou seja, 60 minutos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ALTER SYSTEM SET undo_retention = 3600;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;É isso, pessoal. Não recomendo mexer nesses parâmetros, mas recomendo aproveitar a possibilidade do flashback query sempre que tiver uma situação simples para resolver. O Flashback Query é rápido e prático, mas não substitui uma estratégia de backup e recovery completa. Ele é mais útil para ‘pequenos acidentes’.”&lt;/p&gt;

&lt;h3&gt;
  
  
  Referências:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://oracle-base.com/articles/10g/flashback-query-10g" rel="noopener noreferrer"&gt;https://oracle-base.com/articles/10g/flashback-query-10g&lt;/a&gt;&lt;/p&gt;

</description>
      <category>database</category>
      <category>oracle</category>
      <category>sql</category>
    </item>
    <item>
      <title>Algo entre o VARCHAR2 e o CLOB: VARCHAR2 com esteróides [MAX_STRING_SIZE]</title>
      <dc:creator>Valter Zanchetti Filho</dc:creator>
      <pubDate>Sun, 12 Oct 2025 13:52:50 +0000</pubDate>
      <link>https://dev.to/valter_filho_24448308265f/algo-entre-o-varchar2-e-o-clob-varchar2-com-esteroides-maxstringsize-266j</link>
      <guid>https://dev.to/valter_filho_24448308265f/algo-entre-o-varchar2-e-o-clob-varchar2-com-esteroides-maxstringsize-266j</guid>
      <description>&lt;p&gt;Há aproximadamente 5 anos, quando estava desenvolvendo um módulo de CRM, precisei implementar um campo em que o vendedor pudesse descrever toda a conversa que teve com o cliente.&lt;/p&gt;

&lt;p&gt;Inicialmente, fui no caminho óbvio e criei uma coluna VARCHAR2(4000). Depois de algum tempo utilizando, por incrível que pareça, uma das vendedoras começou a reclamar que este limite era muito pequeno para o nível de detalhe que ela queria colocar dessa conversa. Pediu para aumentar o limite.&lt;/p&gt;

&lt;p&gt;No Oracle, temos a limitação de 4000 caracteres no VARCHAR2 e normalmente teríamos como upgrade o caminho mais óbvio, mudar para CLOB. Isso envolveria mexer na tela já criada e alterar algumas coisas a nível de sessão e integração. Mudar para CLOB implica na forma em que o banco de dados armazena os esses registros e também na forma em que várias aplicações acessam essas colunas. Decidi pesquisar um pouco e logo me deparei com uma solução que já existe desde o Oracle 12C. Um simples parâmetro chamado MAX_STRING_SIZE;&lt;/p&gt;

&lt;p&gt;Se este parâmetro for alterado de &lt;code&gt;STANDARD&lt;/code&gt; para &lt;code&gt;EXTENDED&lt;/code&gt; você conseguirá trabalhar com um VARCHAR2(32000), para ser mais preciso, VARCHAR2(32767), o que não te dá a mesma capacidade que um CLOB, mas já é um ótimo upgrade do VARCHAR2(4000). É perfeito para os casos em que precisamos de um meio termo.&lt;/p&gt;

&lt;p&gt;Antes de qualquer coisa, recomendo ler &lt;a href="https://docs.oracle.com/en/database/oracle/oracle-database/23/refrn/MAX_STRING_SIZE.html" rel="noopener noreferrer"&gt;esse&lt;/a&gt; conteúdo da Oracle para saber se essa será uma boa escolha.&lt;/p&gt;

&lt;p&gt;Para saber se seu banco já está com o esse parâmetro basta rodar o comando abaixo se tiver permissão na v$parameter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="k"&gt;parameter&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'max_string_size'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui vou explicar apenas como alterar na Autonomous Database para exemplificar, mas no link acima você consegue ver como rodar em CDB Padrão, PDB, etc.&lt;/p&gt;

&lt;p&gt;Logado com ADMIN, execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt; &lt;span class="k"&gt;BEGIN&lt;/span&gt;
     &lt;span class="n"&gt;DBMS_MAX_STRING_SIZE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MODIFY_MAX_STRING_SIZE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'EXTENDED'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pronto, resolvido. Daqui pra frente é só alegria.&lt;/p&gt;

&lt;p&gt;Vale a pena alertar que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A alteração é &lt;strong&gt;irreversível&lt;/strong&gt; (uma vez &lt;code&gt;EXTENDED&lt;/code&gt;, não volta para &lt;code&gt;STANDARD&lt;/code&gt; sem recriar o banco).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pode afetar &lt;strong&gt;compatibilidade com clientes antigos&lt;/strong&gt; (SQL Developer, drivers JDBC etc.).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pode &lt;strong&gt;afetar backups ou replicações&lt;/strong&gt; se houver sistemas legados.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nunca tinha pensado em fazer um post sobre isso antes porque pensava que esse parâmetro já era algo bem difundido, mas vi que várias pessoas com quem tenho conversado neste último ano, inclusive DBAs ainda não conheciam, então achei relevante publicar.&lt;/p&gt;

&lt;p&gt;Comente aqui. Você já tinha ouvido falar? Já tinha usado? Achou útil?&lt;/p&gt;

&lt;p&gt;Referências:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.oracle.com/en/database/oracle/oracle-database/19/refrn/MAX_STRING_SIZE.html" rel="noopener noreferrer"&gt;https://docs.oracle.com/en/database/oracle/oracle-database/19/refrn/MAX_STRING_SIZE.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.oracle.com/en-us/iaas/autonomous-database-serverless/doc/dbms-max-string-size.html" rel="noopener noreferrer"&gt;https://docs.oracle.com/en-us/iaas/autonomous-database-serverless/doc/dbms-max-string-size.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>database</category>
      <category>oracle</category>
      <category>sql</category>
    </item>
    <item>
      <title>Passando valores com vírgulas entre páginas usando o Link Builder no Oracle APEX</title>
      <dc:creator>Valter Zanchetti Filho</dc:creator>
      <pubDate>Sun, 03 Aug 2025 13:56:53 +0000</pubDate>
      <link>https://dev.to/valter_filho_24448308265f/passando-valores-com-virgulas-entre-paginas-usando-o-link-builder-no-oracle-apex-58f8</link>
      <guid>https://dev.to/valter_filho_24448308265f/passando-valores-com-virgulas-entre-paginas-usando-o-link-builder-no-oracle-apex-58f8</guid>
      <description>&lt;p&gt;No primeiro ano de carreira, um problema que me rendeu um pouco de dor de cabeça foi o fato de que eu precisava passar vários valores de itens de uma página para outra através de um link. Isso sempre havia funcionado de forma bem consistente, até que certo dia começou se comportar de forma estranha numa página específica. A única diferença entre essa página e as páginas que funcionavam era o fato de que essa página estava passando valores com vírgula. Comecei a pesquisar e vi várias opções que na época pareciam um pouco complexas. Continuei a pesquisa até encontrar algo fácil. Vamos direto ao resultado para salvar o seu tempo.&lt;/p&gt;

&lt;h2&gt;
  
  
  O problema:
&lt;/h2&gt;

&lt;p&gt;Exemplo:&lt;/p&gt;

&lt;p&gt;Tenho essa content row abaixo (que poderia ser também uma linha de um Interactive Report, Grid ou qualquer outro compontente).&lt;/p&gt;

&lt;p&gt;Veja que o título dela contem palavras separadas com vírgula. O mesmo ocorre na barra de progresso, que também tem um valor com vírgula.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh3ki7vhfwi3hto1l7bq6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh3ki7vhfwi3hto1l7bq6.png" width="800" height="83"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No botão de ações tenho um link criar uma nova linha baseada nesta. Esse link leva para a página de cadastro com os campos pré-preenchidos baseados no conteúdo da atual linha. O que seria normal fazermos neste caso é exatamente o que está no screenshot abaixo, informando o destino e o valor correspondente:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc4opc275jl553tifeuuu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc4opc275jl553tifeuuu.png" width="539" height="580"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Porém, se fizermos assim, quando clicarmos no link gerado pelo LINK BUILDER termos um dos seguintes comportamentos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Erro ao renderizar a página porque um dos itens está retornando um valor inválido&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A página vai renderizar mas os valores estarão sendo passados para os campos errados, de forma embaralhada.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A página vai renderizar mas os valores que tinham vírgula irão perder o conteúdo após a vírgula.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  A solução:
&lt;/h2&gt;

&lt;p&gt;O caminho mais rápido e prático para fazer isso é utilizar a contrabarra (\) antes e depois do item que estamos passando através do link builder, assim como mostrado no exemplo abaixo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6qwrx3qaqsiyw8lu99rf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6qwrx3qaqsiyw8lu99rf.png" width="584" height="555"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Isso acontece porque quando passamos os valores dos itens através do link builder, o APEX irá separar eles por vírgula para passar para a próxima página. É por isso que ele se perde quando passamos um valor com vírgula.&lt;/p&gt;

&lt;p&gt;A “\” serve justamente como se fosse colocar o valor entre aspas no Link Builder, mostrando que a vírgula faz parte da expressão.&lt;/p&gt;

&lt;p&gt;É, fácil assim. Pode testar que vai funcionar e a dor de cabeça vai acabar.&lt;/p&gt;

&lt;p&gt;Depois de testar, lembre de comentar aqui embaixo a sua experiência.&lt;/p&gt;

</description>
      <category>oracleapex</category>
    </item>
    <item>
      <title>Oracle APEX: Transcrevendo audio em texto sem uso de REST direto no navegador em 5 minutos</title>
      <dc:creator>Valter Zanchetti Filho</dc:creator>
      <pubDate>Sun, 03 Aug 2025 02:08:34 +0000</pubDate>
      <link>https://dev.to/valter_filho_24448308265f/oracle-apex-transcrevendo-audio-em-texto-sem-uso-de-rest-direto-no-navegador-em-5-minutos-3eip</link>
      <guid>https://dev.to/valter_filho_24448308265f/oracle-apex-transcrevendo-audio-em-texto-sem-uso-de-rest-direto-no-navegador-em-5-minutos-3eip</guid>
      <description>&lt;p&gt;Sempre que faço uma pesquisa devido a alguma necessidade específica, costumo explorar o Google e o Github , fazendo o download de aplicações que outros devs publicam para tentar aprender novas técnicas. Despretensiosamente, buscando formas de fazer drag and drop num interactive grid, me deparo com um teste de transcrição de audio para texto do Paulo Kunzel neste &lt;a href="https://github.com/pkunzel/custom-apex" rel="noopener noreferrer"&gt;link&lt;/a&gt;. Aproveitei que já tinha instalado o app e decidi testar.&lt;/p&gt;

&lt;p&gt;Aqui vai meu parecer: Achei o funcionamento dessa abordagem fantástico pelo fato de ser tão rápido e rodar diretamente no navegador e sem necessidade de contratação de qualquer plano de empresa externa, chamada REST ou AI para processar essa transcrição. Pedi para o ChatGPT explicar sobre o funcionamento disso e aqui vai a resposta:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;“O reconhecimento de voz no navegador usando SpeechRecognition funciona de forma nativa, sem a necessidade de enviar manualmente o áudio para um servidor. No entanto, o áudio é processado na nuvem — normalmente pelos servidores do Google — de forma automática e transparente. O navegador capta o som do microfone, envia para os servidores de reconhecimento de fala e retorna o texto convertido via eventos JavaScript, tudo isso sem exigir chamadas manuais a APIs ou bibliotecas externas.”&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Explorando um pouco a aplicação fiz alguns pequenos ajustes para aceitar audios mais longos e decidi compartilhar a técnica, que é bem simples, por aqui.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Criar um botão com um nome e static id de sua preferência. Este botão deve ter ação definida como dynamic action. Neste caso vamos chamar o botão de &lt;strong&gt;DITAR&lt;/strong&gt; e vamos colocar o static-id como &lt;strong&gt;st_ditar&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Criar um campo de texto onde o texto ditado será transcrito em tempo real. Neste caso o campo será o &lt;strong&gt;P31_TEXTO_RAPIDO&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cadastrar o código abaixo no Execute when Page Loads da sua página, trocando os nomes e static ids por outros de sua preferência:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;recognition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SpeechRecognition&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;recognition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;grammars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SpeechGrammarList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="nx"&gt;recognition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;continuous&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="nx"&gt;recognition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lang&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pt-BR&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="nx"&gt;recognition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;interimResults&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="nx"&gt;recognition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;maxAlternatives&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

&lt;span class="cm"&gt;/* recognition.addEventListener('speechend', () =&amp;gt;{ recognition.stop(); }); */&lt;/span&gt;

&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#st_ditar&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mousedown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;recognition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#st_ditar&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mouseup&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;recognition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;recognition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Erro no reconhecimento do texto: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;recognition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onresult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;-----------------------------&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;last&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;texto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;last&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;transcript&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

&lt;span class="nx"&gt;apex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;P31_TEXTO_RAPIDO&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;texto&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explicação rápida:&lt;/p&gt;

&lt;p&gt;Este código ativa o reconhecimento de voz no navegador usando a API &lt;code&gt;SpeechRecognition&lt;/code&gt;. Ao clicar e segurar o botão com &lt;code&gt;id="st_ditar"&lt;/code&gt;, o reconhecimento começa (&lt;code&gt;mousedown&lt;/code&gt;), e ao soltar (&lt;code&gt;mouseup&lt;/code&gt;), ele é encerrado. O áudio capturado é enviado automaticamente para os servidores de reconhecimento de fala do navegador (Google ou Microsoft, dependendo do navegador), que retornam o texto. O resultado final é atribuído ao item &lt;code&gt;P31_TEXTO_RAPIDO&lt;/code&gt; do Oracle APEX. A configuração define o idioma como português do Brasil (&lt;code&gt;pt-BR&lt;/code&gt;), ativa resultados parciais (&lt;code&gt;interimResults&lt;/code&gt;) e limita as alternativas de texto a uma (&lt;code&gt;maxAlternatives = 1&lt;/code&gt;). Erros são tratados e exibidos no console com &lt;code&gt;console.error&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Quanto aos dois parâmetros:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;interimResults&lt;/code&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;true&lt;/code&gt; :&lt;br&gt;&lt;br&gt;
O reconhecimento retorna &lt;strong&gt;resultados parciais enquanto a fala ainda está acontecendo&lt;/strong&gt;. Isso é útil para mostrar texto "ao vivo", em tempo real.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;false&lt;/code&gt;:&lt;br&gt;&lt;br&gt;
O navegador só retorna o &lt;strong&gt;texto final&lt;/strong&gt;, após detectar uma pausa na fala. Isso reduz a quantidade de eventos disparados, mas não mostra nada durante a fala.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;maxAlternatives&lt;/code&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;1&lt;/code&gt;:&lt;br&gt;&lt;br&gt;
Retorna &lt;strong&gt;apenas a melhor interpretação&lt;/strong&gt; da fala.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;&amp;gt;1&lt;/code&gt; (ex: 3):&lt;br&gt;&lt;br&gt;
Retorna &lt;strong&gt;várias alternativas&lt;/strong&gt; para a mesma fala, ordenadas por confiança. Isso pode ser útil se você quiser deixar o usuário escolher entre diferentes opções ou fazer validações com maior tolerância.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No meu exemplo a tela ficou assim:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjuiaxj4jri50izky57pk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjuiaxj4jri50izky57pk.png" width="674" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Em 5 minutos você consegue replicar isso na sua aplicação. Tente e depois comente aqui o que achou disso.&lt;/p&gt;

</description>
      <category>oracleapex</category>
    </item>
    <item>
      <title>Começando com CI/CD no Oracle Database/APEX usando SQLcl</title>
      <dc:creator>Valter Zanchetti Filho</dc:creator>
      <pubDate>Mon, 28 Jul 2025 02:51:09 +0000</pubDate>
      <link>https://dev.to/valter_filho_24448308265f/comecando-com-cicd-no-oracle-databaseapex-usando-sqlcl-3b9f</link>
      <guid>https://dev.to/valter_filho_24448308265f/comecando-com-cicd-no-oracle-databaseapex-usando-sqlcl-3b9f</guid>
      <description>&lt;p&gt;Depois de muito ler, tentar compreender, testar e apanhar da ferramenta, consegui fazer funcionar um processo simples de CI/CD entre desenvolvimento e produção. Consigo gerar releases da base de desenvolvimento que podem ser aplicados da mesma forma em outras bases de produção. Neste artigo, pretendo mostrar um pouco da minha abordagem.&lt;/p&gt;

&lt;p&gt;Antes de iniciar, vamos alinhar as expectativas:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A. Nem tudo é perfeito&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Se você espera um script perfeito, que vai fazer absolutamente tudo por você, já pode deixar essa expectativa de lado. SQLcl não é perfeito nem tão bem documentado. Você ainda vai precisar fazer alguns ajustes manuais.&lt;/p&gt;

&lt;p&gt;Percebo que em cada versão existe um bug diferente, mas sempre é possível contornar de alguma forma;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;B. Objetos java são ignorados&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Objetos JAVA no banco de dados são esquecidos pela ferramenta. Você vai precisar encontrar uma forma de contornar isso, caso utilize.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C. Atenção se as duas bases rodam no mesmo PDB&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Se você tem as bases de produção e desenvolvimento no mesmo PDB, sugiro fazer o CI/CD do APEX/ORDS num projeto separado, porque tem algumas particularidades que podem te trazer problemas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;D. Essa abordagem sugere que você está gerando os artefatos pela primeira vez&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Estamos considerando aqui neste artigo que você está gerando os artefatos pela primeira vez para rodar numa base limpa. Se quiser rodar numa base que já está com os objetos atualizados, vai precisar rodar um comando para que elas se entendam. Vou dar a dica deste comando no final do artigo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Requisitos:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Para seguir o passo a passo desse artigo você vai precisar de Oracle Database, é claro. Além disso, para replicar o tutorial você precisará de:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Windows (pode utilizar Linux, mas vai precisar adaptar alguns comandos/abordagens)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://download.oracle.com/otn_software/java/sqldeveloper/sqlcl-25.2.1.195.1751.zip" rel="noopener noreferrer"&gt;SQLcl&lt;/a&gt; (neste artigo utilizei a versão 25.2.1.195)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.oracle.com/br/java/technologies/downloads/#java21" rel="noopener noreferrer"&gt;Java&lt;/a&gt; (neste artigo jdk-21.0.8)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.oracle.com/database/technologies/instant-client/downloads.html" rel="noopener noreferrer"&gt;Oracle Instant Client&lt;/a&gt; (neste caso 23.8)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://git-scm.com/downloads" rel="noopener noreferrer"&gt;GIT&lt;/a&gt; (qualquer versão recente. Precisa ser instalado, não vale o portátil.)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Depois de tudo isso instalado, vamos iniciar abrindo o CMD no windows e setar algumas variáveis manualmente para não ter risco de ele se perder. Abaixo temos apenas um exemplo, mas você vai precisar definer os paths conforme a sua instalação. Recomendo digitar linha por linha para ter certeza que o Windows entendeu o que foi passado. Abaixo, o meu exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rem O Comando CHCP 650001 vai fazer com que o seu CMD trate melhor caracteres como acentos, entre outros.
chcp 65001 
rem Se houver estouro de memória pode setar manualmente a memória do Java.
rem set JAVA_TOOL_OPTIONS=-Xms512m -Xmx6G 
rem Aqui iremos definir o diretório do seu Java Home, assim teremos certeza que ele irá buscar no local correto.
set "JAVA_HOME=C:\Oracle\jdk-21.0.8"
rem Vamos também definir o diretório do seu SQLcl
set "SQLCL_HOME=C:\Oracle\sqlcl-25.2.1.195.1751\sqlcl"
rem Caso necessário, temos aqui também o caminho do instant client
rem SET INSTANT_CLIENT_HOME=C:\Util\instantclient\instantclient_23_4 
rem Com este comando, incluímos tudo isso junto com o PATH padrão.
set PATH=%SQLCL_HOME%\bin;%JAVA_HOME%\bin;%INSTANT_CLIENT_HOME%;%PATH%
rem Se quiser, pode chamar diretamente os dados do DB via TNSADMIN. O comando abaixo so se torna necessário se você fizer questão de usar o TNSADMIN
set TNS_ADMIN=C:\Oracle\instantclient_23_4\network\admin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você configurou o ambiente para iniciar os próximos passos. Não feche esta janela pois nela foram passados todos os parâmetros que precisamos. O nome do meu projeto exemplo será PMT.&lt;/p&gt;

&lt;p&gt;Pode deixar o CMD minimizado e criar uma pasta vazia para o seu projeto. No meu caso, a pasta será:&lt;br&gt;&lt;br&gt;
C:\Oracle\projetos\PMT. No CMD vamos navegar até a pasta criada&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd C:\Oracle\projetos\PMT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;É importante garantir que você está na pasta certa. Agora podemos conectar o SQLcl:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CONECTANDO NO SQLCL&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Para conectar no SQLcl, você tem mais de uma opção. Escolha apenas uma delas&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Conectar diretamente sem passar inicialmente a conexão com o banco, deixando para passar os dados da conexão após abrir o SQLcl.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sql -thin /nolog

conn PMT/pass@dbpessoal
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Conexão passando o caminho diretamente
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sql -thin PMT/pass@//databasehostnameorip:1521/servicename
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Conexão via TNSNAMES.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sql -thin PMT/pass@dbpessoal
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;PREPARANDO SEU PRIMEIRO RELEASE&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Depois de conectado no banco de dados via SQLcl, já na pasta do seu projeto, você vai precisar iniciar e definir algumas configurações do projeto. Isso só precisará ser feito uma única vez.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;project&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;PMT&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;schemas&lt;/span&gt; &lt;span class="n"&gt;PMT&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configurando o projeto
&lt;/h3&gt;

&lt;p&gt;Assim que o projeto é iniciado, você pode simplesmente ignorar configurações adicionais ou personalizar de acordo com a sua preferência. Para verificar as configurações disponíveis, pode usar o comando abaixo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;project&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;verbose&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Abaixo, vou listar os comandos de minha preferência, que podem ser utilizados como exemplo ou não. Para entender o que cada um dos comandos faz, você pode rodar o comando acima, que está tudo bem explicado.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;project&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;export&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enable&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;verbose&lt;/span&gt; 
&lt;span class="n"&gt;project&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;export&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setTransform&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;emitSchema&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;verbose&lt;/span&gt;
&lt;span class="n"&gt;project&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;export&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;apex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;expComments&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;verbose&lt;/span&gt; 
&lt;span class="n"&gt;project&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;export&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;apex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;expOriginalIds&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;verbose&lt;/span&gt; 
&lt;span class="n"&gt;project&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;export&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;apex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;expSavedReports&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;verbose&lt;/span&gt; 
&lt;span class="n"&gt;project&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;export&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;apex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;expPubReports&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;verbose&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essa configurações ficam gravadas num arquivo dentro da pasta .dbtools.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configurando filtros
&lt;/h3&gt;

&lt;p&gt;Dentro da mesma pasta .dbtools, existe um subpasta de nome filters com um único arquivo project.filters. Se abrir o arquivo, verá outras configurações adicionais, como por exemplo, opções de ignorar objetos no projeto, exportar somente aplicações APEX específicas. Neste caso, não iremos fazer nenhuma mudança no arquivo. Vamos direto aos comandos GIT. De qualquer forma, recomendo que você analise os objetos APEX, ORDS e grants.&lt;/p&gt;

&lt;p&gt;Considerando que você já tem o GIT instalado, iremos criar o main branch através deste comando. Como você ainda está dentro do SQLcl, teremos que adicionar um ! na frente dos comandos git. Isso vale para qualquer outro comando de sistema operacional dentro do SQLcl.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;--com este comando você irá criar seu branch inicial e se posicionar nele. É importante colocar mesmo aqui que vem depois dos dois traços: -- nesse primeiro comando:&lt;/span&gt;
&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt; &lt;span class="c1"&gt;--initial-branch=main&lt;/span&gt;

&lt;span class="c1"&gt;--com este comando iremos adicionar os arquivos no git&lt;/span&gt;
&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="k"&gt;add&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="c1"&gt;--após adicionar precisamos fazer o commit e podemos cadastrar uma mensagem para identificar esse commit.&lt;/span&gt;
&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="k"&gt;commit&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="nv"&gt;"Inicialização do projeto"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora vamos fazer nosso primeiro release, chamaremos de 1.0.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;--esse comando vai criar o branch e nos colocar dentro dele&lt;/span&gt;
&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;checkout&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="n"&gt;release&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Estamos dentro do branch 1.0, então é hora de exportar nosso banco de de dados. Para isso iremos rodar os comandos abaixo. Não deixe seus desenvolvedores fazerem modificações na sua base enquanto o export não termina.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Você pode escolher o número de threads utilizadas. Neste caso, escolhi 5 threads, que é o padrão.&lt;/span&gt;
&lt;span class="n"&gt;project&lt;/span&gt; &lt;span class="n"&gt;export&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;threads&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;verbose&lt;/span&gt;

&lt;span class="c1"&gt;--adiciona e faz o commit no git.&lt;/span&gt;
&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="k"&gt;add&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="k"&gt;commit&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="nv"&gt;"release-1.0"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apenas para conhecimento, todos os objetos exportados ficam na pasta /scr.&lt;/p&gt;

&lt;p&gt;Depois disso, colocaremos o projeto em stage, que irá comparar o export atual com os branches anteriores. Abaixo, a lista de comandos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;--a primeira coisa a fazer é rodar o project stage, que irá compar os objetos exportados na versão atual com as versões anteriores.&lt;/span&gt;
&lt;span class="n"&gt;project&lt;/span&gt; &lt;span class="n"&gt;stage&lt;/span&gt;

&lt;span class="c1"&gt;--se você quiser adicionar uma lista de comandos dml, deve acrescentar com este comando, nessa etapa.&lt;/span&gt;
&lt;span class="c1"&gt;--project stage add-custom -file-name dml_file_name&lt;/span&gt;

&lt;span class="c1"&gt;--caso queira verificar se está tudo certo com o projeto pode rodar o project verify, mas não é obrigatório.&lt;/span&gt;
&lt;span class="c1"&gt;--project verify -verbose &lt;/span&gt;

&lt;span class="c1"&gt;--vamos informar a versão do release&lt;/span&gt;
&lt;span class="n"&gt;project&lt;/span&gt; &lt;span class="n"&gt;release&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;version&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;verbose&lt;/span&gt;
&lt;span class="c1"&gt;--com o comando abaixo, iremos gerar o artefato. Um .zip com toda a instrução de deploy e todos os objetos, já listados na ordem em que devem ser executados.&lt;/span&gt;
&lt;span class="n"&gt;project&lt;/span&gt; &lt;span class="n"&gt;gen&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;artifact&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;version&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;verbose&lt;/span&gt;

&lt;span class="c1"&gt;--adicionamos e commitamos.&lt;/span&gt;
&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="k"&gt;add&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt; 
&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="k"&gt;commit&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="nv"&gt;"Commit Version 1.0"&lt;/span&gt;

&lt;span class="c1"&gt;--depois de resultado de sucesso em todas as etapas acima precisamos voltar para o branch main e fazer um merge com o release atual.&lt;/span&gt;
&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;checkout&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt; 
&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;merge&lt;/span&gt; &lt;span class="n"&gt;release&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nesta etapa você concluiu a geração do seu primeiro release e está pronto para aplica-lo em outras bases.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAZENDO O DEPLOY DO SEU PRIMEIRO RELEASE NA BASE DE DESTINO
&lt;/h2&gt;

&lt;p&gt;Depois que o seu release estiver pronto, você verá que o objeto .zip estará na sua pasta artifacts, dentro da pasta principal do seu projeto. Agora iremos repetir alguns comandos e acessar a base de destino. Lembrando que estamos considerando uma base de destino limpa, onde os objetos ainda não existem. Se a outra base já contiver os objetos isso não vai funcionar, precisa rodar primeiro um outro comando para isso, que será abordado no final desse artigo.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Caso ainda esteja com o cmd aberto, basta rodar o comando quit para sair do SQLcl e reconectar na base que irá receber os objetos. Caso tenha fechado o cmd, basta rodar novamente os comandos de setar as variáveis de ambiente, voltar para a pasta do projeto e iniciar o SQLcl (dessa vez você irá conectar na base de destino, aquela que vai receber os objetos. Isso é muito importante.)
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;project&lt;/span&gt; &lt;span class="n"&gt;deploy&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="n"&gt;artifact&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;PMT&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zip&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;verbose&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como escolhemos o modo verbose ele irá mostrar cada objeto que está sendo incluído no banco de dados de destino, até você receber a mensagem de sucesso. Além dos seus objetos, ele vai criar 3 tabelas na sua base de destino: DATABASECHANGELOG, DATABASECHANGELOG_ACTIONS e DATABASECHANGELOGLOCK, que são as tabelas de controle do liquibase.&lt;/p&gt;

&lt;h2&gt;
  
  
  PREPARANDO SEUS PRÓXIMOS RELEASES
&lt;/h2&gt;

&lt;p&gt;Considerando que você já gerou seu primeiro release e agora precisa gerar outros, recomendo fazer um backup da pasta do projeto. Não tente usar o comando de compactar do windows, pq ele desconsidera tudo o que tem relação com o git naquela pasta. Você pode copiar a pasta ou gerar um .zip com o 7Zip.&lt;/p&gt;

&lt;p&gt;Vamos ao trabalho. O primeiro passo é voltar para o SQLcl, na pasta do projeto e conectar na base de origem novamente. Para isso vamos executar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;--exportando o projeto novamente&lt;/span&gt;
&lt;span class="n"&gt;project&lt;/span&gt; &lt;span class="n"&gt;export&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;verbose&lt;/span&gt;
&lt;span class="c1"&gt;--criando novo branch&lt;/span&gt;
&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;checkout&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="n"&gt;release&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="k"&gt;add&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt; 
&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="k"&gt;commit&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="nv"&gt;"Novos arquivos exportados da base de desenvolvimento na ver. 1.1"&lt;/span&gt;
&lt;span class="c1"&gt;-- colocando em stage para comparar nosso branch atual com o main&lt;/span&gt;
&lt;span class="n"&gt;project&lt;/span&gt; &lt;span class="n"&gt;stage&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;verbose&lt;/span&gt;
&lt;span class="c1"&gt;--criando o release&lt;/span&gt;
&lt;span class="n"&gt;project&lt;/span&gt; &lt;span class="n"&gt;release&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;version&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;verbose&lt;/span&gt;
&lt;span class="c1"&gt;--gerando o novo artefato&lt;/span&gt;
&lt;span class="n"&gt;project&lt;/span&gt; &lt;span class="n"&gt;gen&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;artifact&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;version&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;verbose&lt;/span&gt;
&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="k"&gt;add&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt; 
&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="k"&gt;commit&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="nv"&gt;"Commit dos novos arquivos da versão 1.1"&lt;/span&gt;
&lt;span class="c1"&gt;--fazendo o checkout e voltando para o main branch&lt;/span&gt;
&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;checkout&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;
&lt;span class="c1"&gt;--fazendo o merge do último release na main&lt;/span&gt;
&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;merge&lt;/span&gt; &lt;span class="n"&gt;release&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tudo pronto. Você verá agora mais um artefato .zip incrementado com todos os objetos do release anterior + os objetos do release atual. Na hora de aplicar, ele irá confirmar no liquibase que todos os objetos do release anterior foram aplicados e logo irá começar a aplicar as mudanças do release atual. Caso você já tenha certeza que os anteriores estão aplicados com sucesso, pode descompactar o artefato e remover as referências dos releases anteriores do xml main.changelog que fica em /releases.&lt;/p&gt;

&lt;p&gt;Após modificado precisará recompactar o arquivo com as alterações para poder fazer o deploy.&lt;/p&gt;

&lt;h2&gt;
  
  
  OUTRAS CONSIDERAÇÕES
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A. Caso você esteja querendo iniciar quando sua base de dados de destino já contém os objetos:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Neste caso você irá criar os objetos normalmente, porém, antes de fazer o deploy do primeiro release na base de destino, precisará rodar o comando abaixo [na base de destino]:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;liquibase&lt;/span&gt; &lt;span class="n"&gt;changelog&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;sync&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;chf&lt;/span&gt; &lt;span class="n"&gt;dist&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;releases&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;changelog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse comando irá criar as tabelas do liquibase na sua base de destino e marcar os objetos como já aplicados. A partir daqui os próximos releases irão funcionar, visto que ele entenderá que o primeiro já foi aplicado.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;B. Se estiver tentando aplicar tudo isso no mesmo PDB, porém em schemas diferentes:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Faça com que o ORDS e APEX sejam um processo a parte, porque ele pode acabar tentando substituir o que já existe. Para isso em .dbtools/filters marque para não exportar APEX nem ORDS, você pode fazer isso depois de forma separada.&lt;/p&gt;

&lt;h2&gt;
  
  
  OBSERVAÇÕES FINAIS:
&lt;/h2&gt;

&lt;p&gt;Algumas observações pessoais sobre este processo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Cada artefato de release novo carrega todos os releases antigos junto com ele. Ele sempre vai se comportar assim, porém, na hora de aplicar, para tudo funcionar você não deve mais por a mão na base de destino, principalmente no que diz respeito a criação de objetos e alterações de tabelas. Todo o processo deve ser feito somente através da ferramenta.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No windows, percebi que as permissões ficam bem vinculadas com o usuário, então se você tem um servidor TS e mais de uma pessoa vai mexer, recomendo criar um usuário devops.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As vezes a tela congela e você precisa apenas apertar ENTER para continuar. Em alguns casos a tela congela e não tem enter que resolva, só esperar. É normal.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Recomendo gerar os releases com certa frequência, não deixar acumular muitas mudanças para gerar o release. Digo isso, pois facilita bastante na hora de investigar o artefato em busca de erros.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Teste por sua conta e risco. Recomendo fazer backups do banco de dados antes de fazer os deploys.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Se tiver interesse em ver o tutorial adaptado para linux, basta comentar aqui, porque já comecei a trabalhar nisso.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bugs que eu percebi em algumas versões do SQLcl&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;25.2.1&lt;/strong&gt; - Percebo que a versão ainda tem problemas para lidar com chaves primários tipo IDENTIFIED BY. Precisei trocar várias tabelas do banco de dados para o modelo normal (sequence + trigger) para não apresentar erro. Ainda tenho problema para o liquibase reconhecer objetos que foram dropados ou renomeados. Também pode apresentar problemas para conectar via TNSNAMES.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;24.1&lt;/strong&gt; - As sequences já existentes são geradas toda vez e isso traz conflito.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Referências:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://rafal.hashnode.dev/part-51-oracle-sqlcl-project-the-only-cicd-tool-for-apex-you-will-ever-need" rel="noopener noreferrer"&gt;https://rafal.hashnode.dev/part-51-oracle-sqlcl-project-the-only-cicd-tool-for-apex-you-will-ever-need&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pretius.com/blog/oracle-sqlcl-project-command" rel="noopener noreferrer"&gt;https://pretius.com/blog/oracle-sqlcl-project-command&lt;/a&gt;&lt;/p&gt;

</description>
      <category>oracle</category>
      <category>database</category>
      <category>oracleapex</category>
    </item>
    <item>
      <title>Desconsiderando maiúsculas, minúsculas e acentos com collations no Oracle</title>
      <dc:creator>Valter Zanchetti Filho</dc:creator>
      <pubDate>Thu, 24 Jul 2025 16:32:35 +0000</pubDate>
      <link>https://dev.to/valter_filho_24448308265f/desconsiderando-maiusculas-minusculas-e-acentos-com-collations-no-oracle-51p0</link>
      <guid>https://dev.to/valter_filho_24448308265f/desconsiderando-maiusculas-minusculas-e-acentos-com-collations-no-oracle-51p0</guid>
      <description>&lt;p&gt;Às vezes, precisamos fazer comparações no Oracle nas quais queremos desconsiderar se o texto está em maiúsculas, minúsculas ou se contém acentos. Para isso, existe uma solução chamada &lt;strong&gt;COLLATE&lt;/strong&gt;, que pode ser utilizada a nível de &lt;strong&gt;tabela&lt;/strong&gt;, &lt;strong&gt;sessão&lt;/strong&gt; ou diretamente na &lt;strong&gt;query&lt;/strong&gt;. Neste artigo, trataremos das &lt;em&gt;collations&lt;/em&gt; aplicadas a nível de &lt;strong&gt;query&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exemplo prático:
&lt;/h3&gt;

&lt;p&gt;Você precisa consultar uma pessoa na base de dados chamada &lt;strong&gt;José&lt;/strong&gt;, porém, no banco de dados ela está registrada como &lt;strong&gt;Jose&lt;/strong&gt; — ou vice-versa. Nesse caso, a comparação padrão seria:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;DUAL&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="s1"&gt;'JOSÉ'&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'JOSE'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Resultado: nenhuma linha selecionada&lt;/p&gt;

&lt;p&gt;Isso acontece porque, no padrão do banco de dados Oracle, &lt;strong&gt;'JOSÉ'&lt;/strong&gt; não é igual a &lt;strong&gt;'JOSE'&lt;/strong&gt;. No entanto, se utilizarmos uma &lt;em&gt;collation&lt;/em&gt; específica, o Oracle poderá desconsiderar os acentos no momento da comparação.&lt;/p&gt;

&lt;p&gt;Veja este exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;DUAL&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="s1"&gt;'JOSÉ'&lt;/span&gt; &lt;span class="k"&gt;COLLATE&lt;/span&gt; &lt;span class="n"&gt;BINARY_AI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'JOSE'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;DUAL&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="s1"&gt;'JOSÉ'&lt;/span&gt; &lt;span class="k"&gt;COLLATE&lt;/span&gt; &lt;span class="n"&gt;BINARY_AI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Jose'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se executarmos essas queries, obteremos &lt;strong&gt;uma linha de resultado para cada uma&lt;/strong&gt;. Por quê?&lt;/p&gt;

&lt;p&gt;Quando utilizamos o &lt;strong&gt;COLLATE BINARY_CI&lt;/strong&gt; ou &lt;strong&gt;BINARY_AI&lt;/strong&gt;, estamos informando ao banco que ele deve considerar os textos da seguinte forma:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;_CI&lt;/strong&gt; (&lt;em&gt;Case Insensitive&lt;/em&gt;): &lt;strong&gt;Ignora diferenças entre maiúsculas e minúsculas&lt;/strong&gt;, mas &lt;strong&gt;considera acentos&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;_AI&lt;/strong&gt; (&lt;em&gt;Accent Insensitive&lt;/em&gt;): &lt;strong&gt;Ignora acentos, maiúsculas e minúsculas&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Simples e prático!&lt;/p&gt;

&lt;p&gt;Você também pode definir uma &lt;em&gt;collation&lt;/em&gt; a nível de &lt;strong&gt;tabela&lt;/strong&gt; ou até mesmo de &lt;strong&gt;coluna&lt;/strong&gt;, permitindo que todas as queries feitas sobre esse dado ignorem automaticamente as diferenças de acentuação e CASE.&lt;/p&gt;

&lt;p&gt;Fontes:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://binovarghese.com/notes/2022/10/column-level-collation-and-case-insensitive-database-in-oracle/" rel="noopener noreferrer"&gt;https://docs.oracle.com/en/database/oracle/oracle-database/12.2/nlspg/linguistic-sorting-and-matching.html#GUID-68633595-DC95-4393-A6B8-146AD05F5FDF&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://binovarghese.com/notes/2022/10/column-level-collation-and-case-insensitive-database-in-oracle/" rel="noopener noreferrer"&gt;https://binovarghese.com/notes/2022/10/column-level-collation-and-case-insensitive-database-in-oracle/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>oracle</category>
      <category>oracledatabase</category>
      <category>database</category>
    </item>
    <item>
      <title>Rastreando as modificações DDL: Criando logs para modificações do seu schema Oracle</title>
      <dc:creator>Valter Zanchetti Filho</dc:creator>
      <pubDate>Sun, 20 Jul 2025 21:42:37 +0000</pubDate>
      <link>https://dev.to/valter_filho_24448308265f/rastreando-as-modificacoes-ddl-criando-logs-para-modificacoes-do-seu-schema-oracle-1c21</link>
      <guid>https://dev.to/valter_filho_24448308265f/rastreando-as-modificacoes-ddl-criando-logs-para-modificacoes-do-seu-schema-oracle-1c21</guid>
      <description>&lt;p&gt;Algumas vezes aqui no trabalho, dois desenvolvedores resolveram alterar a mesma package quase ao mesmo tempo. Um deles estava alterando desde o início da tarde e foi compilando no decorrer dessa mesma tarde. O outro abriu o corpo da package para alterar durante a manhã, fez umas alterações no final do dia e compilou à noite. Não existia processo de CI/CD e obviamente um deles perdeu as modificações que tinha feito. Adivinha quem foi o desenvolvedor que perdeu as alterações? Eu.&lt;/p&gt;

&lt;p&gt;Para não passar mais por isso, uma abordagem simples que resolvemos adotar foi a criação de uma trigger que audita todas as modificações feitas no schema do banco e grava numa tabela. Assim, temos bastante controle de alteração e autonomia, sem precisar depender do DBA para restaurar versões anteriores. Outra vantagem, foi o fato de que fica bem fácil de ver quem fez as alterações nos objetos e nos traz uma forma fácil de acompanhar cada alteração no código ou estrutura do schema.&lt;/p&gt;

&lt;p&gt;Esse método descrito abaixo foi testado na versão 19c do Oracle Database Standard Edition e os comendos devem ser executados com o próprio OWNER do SCHEMA que você quer auditar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;
  &lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;DDL_LOG&lt;/span&gt;
       &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;"DDL_LOG_ID"&lt;/span&gt; &lt;span class="n"&gt;NUMBER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="nv"&gt;"DDL_OPERATION"&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="nb"&gt;BYTE&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
        &lt;span class="nv"&gt;"OBJECT_TYPE"&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="nb"&gt;BYTE&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
        &lt;span class="nv"&gt;"OBJECT_NAME"&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt; &lt;span class="nb"&gt;BYTE&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
        &lt;span class="nv"&gt;"APP_USER_NAME"&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="nb"&gt;BYTE&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
        &lt;span class="nv"&gt;"EVENT_TIMESTAMP"&lt;/span&gt; &lt;span class="nb"&gt;TIMESTAMP&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="k"&gt;CURRENT_TIMESTAMP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="nv"&gt;"DDL_SQL_TEXT"&lt;/span&gt; &lt;span class="k"&gt;CLOB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="nv"&gt;"DDL_SQL_TEXT_2"&lt;/span&gt; &lt;span class="k"&gt;CLOB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nv"&gt;"CLIENT_IP_ADDRESS"&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;150&lt;/span&gt; &lt;span class="nb"&gt;BYTE&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
        &lt;span class="nv"&gt;"OBJECT_OWNER"&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="nb"&gt;BYTE&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
        &lt;span class="nv"&gt;"DB_USER_NAME"&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="nb"&gt;BYTE&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
        &lt;span class="nv"&gt;"OS_USER_NAME"&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="nb"&gt;BYTE&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
        &lt;span class="nv"&gt;"CLIENT_HOST_NAME"&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="nb"&gt;BYTE&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
        &lt;span class="nv"&gt;"NOTES"&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4000&lt;/span&gt; &lt;span class="nb"&gt;BYTE&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
         &lt;span class="k"&gt;CONSTRAINT&lt;/span&gt; &lt;span class="nv"&gt;"DDL_LOG_PK"&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;"DDL_LOG_ID"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;/&lt;/span&gt;

&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;SEQUENCE&lt;/span&gt; &lt;span class="n"&gt;SEQ_DDL_LOG_ID&lt;/span&gt;
   &lt;span class="k"&gt;START&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
   &lt;span class="k"&gt;INCREMENT&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
   &lt;span class="n"&gt;NOCACHE&lt;/span&gt;
   &lt;span class="n"&gt;NOCYCLE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;/&lt;/span&gt;

&lt;span class="c1"&gt;--Se este trecho não rodar quando for inserir via navegador, pode passar via EXECUTE IMMEDIATE, já que não tem como colocar DEFINE OFF no APEX&lt;/span&gt;
  &lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="k"&gt;REPLACE&lt;/span&gt; &lt;span class="n"&gt;EDITIONABLE&lt;/span&gt; &lt;span class="k"&gt;TRIGGER&lt;/span&gt; &lt;span class="n"&gt;TRG_DDL_LOG_SEQ&lt;/span&gt;
&lt;span class="k"&gt;BEFORE&lt;/span&gt; &lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;DDL_LOG&lt;/span&gt; &lt;span class="k"&gt;FOR&lt;/span&gt; &lt;span class="k"&gt;EACH&lt;/span&gt; &lt;span class="k"&gt;ROW&lt;/span&gt; 
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
  &lt;span class="k"&gt;BEGIN&lt;/span&gt;
    &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="n"&gt;INSERTING&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;NEW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DDL_LOG_ID&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt;
      &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;SEQ_DDL_LOG_ID&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NEXTVAL&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="k"&gt;NEW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DDL_LOG_ID&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;SYS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DUAL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;END&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;END&lt;/span&gt; &lt;span class="n"&gt;COLUMN_SEQUENCES&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TRIGGER&lt;/span&gt; &lt;span class="n"&gt;TRG_DDL_LOG_SEQ&lt;/span&gt; &lt;span class="n"&gt;ENABLE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora você deve criar o trigger que irá fazer a auditoria. Lembre-se de utilizar o OWNER do SCHEMA que você pretende auditar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;or&lt;/span&gt; &lt;span class="k"&gt;replace&lt;/span&gt; &lt;span class="k"&gt;TRIGGER&lt;/span&gt; &lt;span class="n"&gt;ddl_audit_trigger&lt;/span&gt; &lt;span class="k"&gt;AFTER&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="k"&gt;DROP&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;SCHEMA&lt;/span&gt;

&lt;span class="k"&gt;DECLARE&lt;/span&gt;
  &lt;span class="n"&gt;v_sql_text&lt;/span&gt;  &lt;span class="k"&gt;CLOB&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;v_text_item&lt;/span&gt; &lt;span class="n"&gt;ora_name_list_t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;BEGIN&lt;/span&gt;

&lt;span class="c1"&gt;--TRATA A FORMA QUE O DDL SERÁ SALVO NO BLOB&lt;/span&gt;
&lt;span class="n"&gt;DBMS_METADATA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_transform_param&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DBMS_METADATA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session_transform&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'SQLTERMINATOR'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;TRUE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;DBMS_METADATA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_transform_param&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DBMS_METADATA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session_transform&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'PRETTY'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;TRUE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;DBMS_METADATA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_transform_param&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DBMS_METADATA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session_transform&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'SEGMENT_ATTRIBUTES'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;FALSE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;DBMS_METADATA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_transform_param&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DBMS_METADATA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session_transform&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'STORAGE'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;FALSE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;      
&lt;span class="n"&gt;DBMS_METADATA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;set_transform_param&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DBMS_METADATA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session_transform&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'EMIT_SCHEMA'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;FALSE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;



&lt;span class="c1"&gt;-- Captura o SQL executado (DDL real)&lt;/span&gt;
  &lt;span class="n"&gt;v_sql_text&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;FOR&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;..&lt;/span&gt; &lt;span class="n"&gt;ora_sql_txt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v_text_item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;LOOP&lt;/span&gt;
    &lt;span class="n"&gt;v_sql_text&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;v_sql_text&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;v_text_item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;END&lt;/span&gt; &lt;span class="n"&gt;LOOP&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;span class="c1"&gt;-- Desconsidera as mudanças feitas nos próprios objetos relacionados a auditoria&lt;/span&gt;
        &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="n"&gt;ora_dict_obj_name&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'DDL_LOG'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'DDL_AUDIT_TRIGGER'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; 
            &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;RETURN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;ELSE&lt;/span&gt;

            &lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;ddl_log&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ddl_operation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                     
                                 &lt;span class="n"&gt;object_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                 &lt;span class="n"&gt;object_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                 &lt;span class="n"&gt;app_user_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          
                                 &lt;span class="n"&gt;ddl_sql_text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                 &lt;span class="n"&gt;ddl_sql_text_2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                 &lt;span class="n"&gt;client_ip_address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                 &lt;span class="n"&gt;db_user_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                 &lt;span class="n"&gt;object_owner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;              
                                 &lt;span class="n"&gt;os_user_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                 &lt;span class="n"&gt;client_host_name&lt;/span&gt;
                                &lt;span class="p"&gt;)&lt;/span&gt;    
            &lt;span class="k"&gt;VALUES&lt;/span&gt;              &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ora_sysevent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                 &lt;span class="k"&gt;REPLACE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ora_dict_obj_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'_'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                                 &lt;span class="n"&gt;ora_dict_obj_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                 &lt;span class="n"&gt;NVL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;V&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'APP_USER'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;SYS_CONTEXT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'USERENV'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'CURRENT_USER'&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
                                 &lt;span class="n"&gt;dbms_metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_ddl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;REPLACE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;UPPER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ora_dict_obj_type&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'_'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;UPPER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ora_dict_obj_name&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
                                 &lt;span class="n"&gt;v_sql_text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                &lt;span class="n"&gt;SYS_CONTEXT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'USERENV'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'IP_ADDRESS'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;   
                                &lt;span class="n"&gt;ora_login_user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                &lt;span class="n"&gt;ora_dict_obj_owner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                                &lt;span class="n"&gt;SYS_CONTEXT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'USERENV'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'OS_USER'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;  
                                &lt;span class="n"&gt;SYS_CONTEXT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'USERENV'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'HOST'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;             
            &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;END&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;EXCEPTION&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;OTHERS&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt;
      &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;--Não disparar erro, apenas ignorar. Criar rotina de log de erro.&lt;/span&gt;
      &lt;span class="k"&gt;RETURN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora cada vez que modificar tabela ou outros objetos, o comando será salvo na tabela DDL_LOG, conforme demonstrado abaixo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpcehvfysvd0ragp2u8jv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpcehvfysvd0ragp2u8jv.png" width="800" height="64"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Existem outras soluções para isso, porém, essa foi a solução mais prática que encontrei sem depender do DBA. Se tiver sugestões de melhoria, fique a vontade para comentar.&lt;/p&gt;

</description>
      <category>oracle</category>
      <category>oracledatabase</category>
      <category>database</category>
    </item>
    <item>
      <title>Alturas Iguais em Regiões Lado a Lado no Oracle APEX: A Solução Simples com u-flex</title>
      <dc:creator>Valter Zanchetti Filho</dc:creator>
      <pubDate>Wed, 09 Jul 2025 16:45:24 +0000</pubDate>
      <link>https://dev.to/valter_filho_24448308265f/alturas-iguais-em-regioes-lado-a-lado-no-oracle-apex-a-solucao-simples-com-u-flex-1946</link>
      <guid>https://dev.to/valter_filho_24448308265f/alturas-iguais-em-regioes-lado-a-lado-no-oracle-apex-a-solucao-simples-com-u-flex-1946</guid>
      <description>&lt;p&gt;Você já se deparou com regiões lado a lado no Oracle APEX que têm alturas diferentes? Esse desnível visual pode deixar sua aplicação com um aspecto desalinhado e pouco profissional — especialmente quando temos várias regiões exibidas em conjunto.&lt;/p&gt;

&lt;p&gt;Passei por isso algumas vezes e, por ser algo aparentemente simples, fui perguntar para colegas mais experientes. A resposta foi quase sempre a mesma: "tem que usar um misto de JavaScript e CSS, não dá só com CSS puro". Isso me incomodou, porque parecia uma solução complicada para um problema pequeno. Pesquisando um pouco mais, descobri o que o que precisava ser feito e vou compartilhar como fazer neste post.&lt;/p&gt;

&lt;p&gt;Quando criamos duas regiões lado a lado com conteúdos de tamanhos verticais diferentes, o resultado pode ser como este:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd6ehmgxa9e9tcmjnqgrn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd6ehmgxa9e9tcmjnqgrn.png" width="800" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Veja que existe uma diferença de tamanho entre um e outro, destacado com as setas vermelhas A diferença de altura pode causar uma quebra de harmonia visual na interface. Dependendo do layout da página, isso pode comprometer a experiência do usuário.&lt;/p&gt;

&lt;p&gt;A solução é mais simples do que parece, e você pode aplicá-la sem precisar inspecionar elementos e inventar gambiarras.&lt;/p&gt;

&lt;p&gt;Basta usar duas classes do Universal Theme:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Na &lt;strong&gt;propriedade "Column CSS Classes"&lt;/strong&gt; da região: adicione &lt;code&gt;u-flex&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Na &lt;strong&gt;propriedade "CSS Classes"&lt;/strong&gt; da região (Appearance): adicione &lt;code&gt;u-flex-grow-1&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Essas classes utilizam o poder do Flexbox para garantir que as regiões &lt;strong&gt;cresçam proporcionalmente&lt;/strong&gt; e se ajustem à mesma altura, mesmo com conteúdos diferentes. Deixei esse screenshot aqui para mostrar onde foram aplicadas.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb3dtx4hbwq47bdh4l6c7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb3dtx4hbwq47bdh4l6c7.png" width="800" height="290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Isso garante que as regiões cresçam igualmente, mantendo a altura simétrica mesmo com conteúdos de tamanhos diferentes.&lt;/p&gt;

&lt;p&gt;Exemplo:&lt;br&gt;&lt;br&gt;
Com &lt;code&gt;u-flex&lt;/code&gt; e &lt;code&gt;u-flex-grow-1&lt;/code&gt; (abaixo): altura uniforme e layout mais equilibrado.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fenhb7umz8zv52oj8ea6t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fenhb7umz8zv52oj8ea6t.png" width="800" height="306"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Experimente esse pequeno ajuste e veja a diferença que faz na apresentação da sua aplicação Oracle APEX!&lt;/p&gt;

&lt;p&gt;Fonte:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://apex.oracle.com/pls/apex/r/apex_pm/ut/layout-modifiers" rel="noopener noreferrer"&gt;https://apex.oracle.com/pls/apex/r/apex_pm/ut/layout-modifiers&lt;/a&gt;`&lt;/p&gt;

</description>
      <category>oracleapex</category>
    </item>
    <item>
      <title>Adicionando um certificado cliente em uma wallet Oracle</title>
      <dc:creator>Valter Zanchetti Filho</dc:creator>
      <pubDate>Tue, 24 Jun 2025 16:56:17 +0000</pubDate>
      <link>https://dev.to/valter_filho_24448308265f/adicionando-um-certificado-cliente-em-uma-wallet-oracle-4286</link>
      <guid>https://dev.to/valter_filho_24448308265f/adicionando-um-certificado-cliente-em-uma-wallet-oracle-4286</guid>
      <description>&lt;p&gt;Alguns bancos brasileiros como Santander e Itaú exigem um certificado digital de cliente na hora de chamar suas APIs REST. Fazer isso diretamente via Oracle isso é um pouco irritante, visto que exige a criação de uma wallet específica para poder chamar esses serviços via MAKE_REST_REQUEST. Por isso, muita gente desiste e acabar fazendo as chamadas através de aplicações intermediárias. Neste artigo vamos abordar como fazer essas conexões REST diretamente via banco de dados com o MAKE_REST_REQUEST do APEX.&lt;/p&gt;

&lt;p&gt;Para criar a wallet você precisa ter um Oracle Client versão full instalado, já que precisaremos do &lt;strong&gt;orapki&lt;/strong&gt;. Não adianta ter o Instant Client. Ele também vem incluso nas versões do Oracle Database. Na minha opinião, não vale a pena baixar e instalar o cliente full ou banco de dados completo quando queremos apenas utilizar o &lt;strong&gt;OraPK&lt;/strong&gt;I, mas isso fica a seu critério.&lt;/p&gt;

&lt;p&gt;Você consegue saber um pouco mais sobre como usar o orapki sem precisar baixar o Full Cliente neste meu artigo aqui:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tomeofapex.hashnode.dev/creating-and-configuring-wallets-with-orapki-without-needing-the-full-oracle-client" rel="noopener noreferrer"&gt;Creating and Configuring Wallets with OraPKI (Without Needing the Full Oracle Client)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A partir daqui você já precisa ter acesso ao orapki.&lt;/p&gt;

&lt;p&gt;A primeira coisa que você precisa fazer, caso ainda não tenha uma wallet é criar uma. Para criar pode rodar o comando abaixo, substituindo a pasta por uma pasta de sua escolha:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;orapki&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;wallet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-wallet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"C:\Users\valter\Downloads\adu"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-pwd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;123456xx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após executar este comando você irá ver que ele gerou a wallet no seu sistema operacional, conforme demonstrado abaixo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbv1tn04tza99aqs1tkjc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbv1tn04tza99aqs1tkjc.png" width="670" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Depois disso, você vai começar importando o certificado do cliente com o comando abaixo. Primeiro o diretório onde fica a carteira e depois o difetório onde fica o .pfx do certificado do cliente e a senha do certificado de cliente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;orapki&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;wallet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;import_pkcs12&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-wallet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"C:\Users\valter\Downloads\adu"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-pwd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;123456xx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-pkcs12file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"C:\Users\valter\OneDrive\Desktop\certificado_a_importar\user_cert.pfx"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-pkcs12pwd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;123456&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após executar você deverá receber essa mensagem de sucesso:&lt;/p&gt;

&lt;p&gt;orapki command import_pkcs12 executed successfully.&lt;/p&gt;

&lt;p&gt;Normalmente, você também precisará adicionar os certificados dos servidores do serviço no qual você quer conectar na parte dos certificados confiáveis da wallet&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;orapki&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;wallet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-wallet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"C:\Users\valter\Downloads\adu"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-trusted_cert&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-cert&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"G:\Meu Drive\Aplicativos\OraPKI\certs\ICP-BR\AC_VALID_RFB_v5.crt"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-pwd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;123456xx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você consegue verificar agora todo o conteúdo da sua wallet com este compando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;orapki&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;wallet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-wallet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"C:\Users\valter\Downloads\adu"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-pwd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;123456xx&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deverá mostrar os certificados de cliente e os certificados confiáveis como na tela abaixo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbwgoi4vlw2s6xafqhakv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbwgoi4vlw2s6xafqhakv.png" width="800" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora você precisa fazer o upload dessa wallet para algum diretório acessível pelo seu banco de dados. No meu exemplo, 'file:/opt/oracle/wallets/adu/'. Em alguns testes precisei colocar uma / no final e em outros não foi necessário. Testei em duas bases diferentes. Comece tentando sem a / no final do nome da wallet, deve funcionar.&lt;/p&gt;

&lt;p&gt;Devemos adicionar os privilégios para os owners solicitados com SYS ou ADMIN. Segue abaixo o comando utilizado para atribuir os privilégios. Lembre de substituir YOUR_OWNER pelo nome do seu owner e APEX_230200 para a versão do seu banco&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;BEGIN&lt;/span&gt;

&lt;span class="c1"&gt;-- APEX&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="n"&gt;DBMS_NETWORK_ACL_ADMIN&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;APPEND_WALLET_ACE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;wallet_path&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'file:/opt/oracle/wallets/adu/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;ace&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;xs&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;ace_type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt;&lt;span class="n"&gt;privilege_list&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;xs&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;name_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'use_client_certificates'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'use_passwords'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt;&lt;span class="n"&gt;principal_name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'APEX_230200'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt;&lt;span class="n"&gt;principal_type&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;xs_acl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ptype_db&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- OWNER&lt;/span&gt;
&lt;span class="n"&gt;DBMS_NETWORK_ACL_ADMIN&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;APPEND_WALLET_ACE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;wallet_path&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'file:/opt/oracle/wallets/adu/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="n"&gt;ace&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;xs&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;ace_type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt;&lt;span class="n"&gt;privilege_list&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;xs&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;name_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'use_client_certificates'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'use_passwords'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt;&lt;span class="n"&gt;principal_name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'YOUR_OWNER'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt;&lt;span class="n"&gt;principal_type&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;xs_acl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ptype_db&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Daqui pra frente é sua apontar a wallet na hora de chamar o serviço via MAKE_REST_REQUEST.&lt;/p&gt;

</description>
      <category>oracle</category>
      <category>database</category>
    </item>
    <item>
      <title>Criação e configuração de wallets com OraPKI (sem precisar do Oracle Client Full)</title>
      <dc:creator>Valter Zanchetti Filho</dc:creator>
      <pubDate>Tue, 24 Jun 2025 16:45:21 +0000</pubDate>
      <link>https://dev.to/valter_filho_24448308265f/criacao-e-configuracao-de-wallets-com-orapki-sem-precisar-do-oracle-client-full-2ikf</link>
      <guid>https://dev.to/valter_filho_24448308265f/criacao-e-configuracao-de-wallets-com-orapki-sem-precisar-do-oracle-client-full-2ikf</guid>
      <description>&lt;p&gt;Já faz algum tempo que tenho precisado lidar com wallets no banco de dados sem ter acesso ao SSH. Por isso, para utilizar o mkstore ou orapki localmente, tinha duas opções mais comuns: baixar uma versão do banco de dados e instalar numa VM ou na máquina local ou então baixar e instalar um full client, que para mim, não estava sendo necessário para nenhuma outra atividade além dessa. Eu queria encontrar uma forma mais prática e acessível, em que eu pudesse colocar o orapki no meu Google Drive e utilizar do PC do trabalho, do pc de casa e do laptop.&lt;/p&gt;

&lt;p&gt;Depois de alguma pesquisa na web, encontrei esses dois artigos que explicam como utilizar os arquivos .jar do SQLcl para rodar o orapki sem precisar baixar e instalar o client full.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ogobrecht.com/posts/2020-07-29-how-to-use-mkstore-and-orapki-with-oracle-instant-client/" rel="noopener noreferrer"&gt;https://ogobrecht.com/posts/2020-07-29-how-to-use-mkstore-and-orapki-with-oracle-instant-client/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://andriydmytrenko.wordpress.com/2013/07/01/using-the-secure-external-password-store-with-instant-client/" rel="noopener noreferrer"&gt;https://andriydmytrenko.wordpress.com/2013/07/01/using-the-secure-external-password-store-with-instant-client/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vamos seguir esses passos.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://download.oracle.com/otn_software/java/sqldeveloper/sqlcl-latest.zip" rel="noopener noreferrer"&gt;Baixar o SQLcl&lt;/a&gt; (a ferramenta mais leve da Oracle que encontrei que possui os .jar do orapki).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Descompactar em alguma pasta da sua preferência&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Criar um arquivo orapki.bat, que deve ter o conteúdo abaixo.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;echo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;off&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;rem&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;inspiration:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;https://andriydmytrenko.wordpress.com/2013/07/01/using-the-secure-external-password-store-with-instant-client/&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;setlocal&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;rem&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;command&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nx"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!%&lt;/span&gt;&lt;span class="nx"&gt;1&lt;/span&gt;&lt;span class="o"&gt;==!&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;goto&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="o"&gt;=%&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;1&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="n"&gt;shift&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nx"&gt;goto&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;loop&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;done&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;rem&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;classpath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;orapki&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;align&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;this&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;your&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;SQLcl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;installation&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;sqlcl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"G:\Meu Drive\Aplicativos\SQLcl\25.1.0.101.2353\lib"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;classpath&lt;/span&gt;&lt;span class="o"&gt;=%&lt;/span&gt;&lt;span class="n"&gt;sqlcl&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;\oraclepki.jar&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;classpath&lt;/span&gt;&lt;span class="o"&gt;=%&lt;/span&gt;&lt;span class="n"&gt;classpath&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;sqlcl&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;\osdt_core.jar&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;classpath&lt;/span&gt;&lt;span class="o"&gt;=%&lt;/span&gt;&lt;span class="n"&gt;classpath&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;sqlcl&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;\osdt_cert.jar&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;rem&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;simulate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;orapki&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;command&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;java&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-classpath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;classpath&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;oracle.security.pki.textui.OraclePKITextUI&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="n"&gt;endlocal&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Substitua a linha set sqlcl="G:\Meu Drive\Aplicativos\SQLcl\25.1.0.101.2353\lib" pelo diretório onde está seu SQLcl.&lt;/p&gt;

&lt;p&gt;Pronto! Pode usar o orapki agora sem ter que baixar e instalar o client completo.&lt;/p&gt;

&lt;p&gt;Nota: Se quiser user no MacOS ou Linux, pode fazer os arquivos assim:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;mkstore:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash
# set classpath for mkstore - align this to your local SQLcl installation
SQLCL=$(dirname $(which sql))/../lib
CLASSPATH=${SQLCL}/oraclepki.jar:${SQLCL}/osdt_core.jar:${SQLCL}/osdt_cert.jar
# simulate mkstore command
java -classpath ${CLASSPATH} oracle.security.pki.OracleSecretStoreTextUI  "$@"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;orapki&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash
# set classpath for orapki - align this to your local SQLcl installation
SQLCL=$(dirname $(which sql))/../lib
CLASSPATH=${SQLCL}/oraclepki.jar:${SQLCL}/osdt_core.jar:${SQLCL}/osdt_cert.jar
# simulate orapki command
java -cl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Acessando uma instância Oracle Autonomous Database na OCI utilizando o PLSQL Developer</title>
      <dc:creator>Valter Zanchetti Filho</dc:creator>
      <pubDate>Tue, 24 Jun 2025 16:23:09 +0000</pubDate>
      <link>https://dev.to/valter_filho_24448308265f/acessando-uma-instancia-na-oracle-autonomous-database-utilizando-o-plsql-developer-6io</link>
      <guid>https://dev.to/valter_filho_24448308265f/acessando-uma-instancia-na-oracle-autonomous-database-utilizando-o-plsql-developer-6io</guid>
      <description>&lt;p&gt;Geralmente quem utiliza o PLSQL Developer já está na estrada Oracle há bastante tempo. Estamos acostumados a configurar os TNSNAMES para acessar nossas bases de dados On Premise até com uma das mãos atadas, porém, quando nos deparamos pela primeira vez com a Autonomous Database, vemos que o caminho para conectar é um pouco diferente. Este tópico vai abordar a forma mais prática de fazer login na sua Autonomous Database com o PLSQL Developer. Para isso, você deve acessar a instância na OCI.&lt;/p&gt;

&lt;p&gt;No console da OCI, no menu Autonomous Database, você deve clicar na database que você tem interesse em se conectar.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj2vpdwgshjx941myei7w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj2vpdwgshjx941myei7w.png" width="800" height="89"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clicar em database connections&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3kvws9luikyar8jyt940.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3kvws9luikyar8jyt940.png" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Você deve baixar a sua wallet da instância em download wallet. Irá trazer sua wallet em .zip&lt;/p&gt;

&lt;p&gt;A partir daqui temos três opções:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Opção A - Você extrai o ZIP numa pasta separada e manda o PLSQL Developer ler nessa pasta.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A mais prática de todas. Você cria uma pasta com o nome que você quiser [exemplo: my_plsql_wallet]. Dentro dela, cria outra pasta chamada network. Dentro de network cria uma pasta chamada admin.&lt;/p&gt;

&lt;p&gt;No exemplo, ficaria assim: C:\my_plsql_wallet\network\admin. Coloque o conteúdo extraido da wallet na pasta admin. Dentro da pasta admin deve ver os arquivos abaixo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F98svero9ky4twrohvu3m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F98svero9ky4twrohvu3m.png" width="764" height="290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aponte o caminho aponte o caminho da pasta mãe no PLSQL Developer. [Exemplo: C:\my_plsql_wallet]&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjpdzx8rjub9cs5pjg7qr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjpdzx8rjub9cs5pjg7qr.png" width="800" height="241"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Opção B - Você extrai e adiciona as entradas no TNSNAMES e SQLNET.ORA [Caso queira manter as conexões que você já possui e tenha apenas uma conexão ativa na Autonomous Database]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Neste caso, você vai procurar na sua máquina o seu arquivo TNSNAMES (supondo que você já tenha um Oracle Client instalado) e adicionar as entradas que estão dentro do TNS_NAMES da wallet.&lt;/p&gt;

&lt;p&gt;No arquivo SQLNET.ORA, você vai adicionar a seguinte entrada:&lt;/p&gt;

&lt;p&gt;WALLET_LOCATION = (SOURCE = (METHOD = file) (METHOD_DATA = (DIRECTORY="?/network/admin"))) SSL_SERVER_DN_MATCH=yes&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Opção C - Você extrai, adiciona as entradas e modifica o TNSNAMES indicando o caminho da wallet. [A mais trabalhosa e útil se você quer trabalhar com mais de uma instância na Autonomous Database]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Lembre de fazer um backup antes de qualquer coisa. Primeiro você irá limpar do SQLNET.ORA tudo o que tiver relação com wallet. Você vai extrair a wallet numa pasta com o nome que você quiser [exemplo: my_plsql_wallet].&lt;/p&gt;

&lt;p&gt;Você vai adicionar a entrada no seu TNSNAMES, e modificar a parte que se refere a wallet, modificando a parte de apontamento de wallet em security como no exemplo abaixo:&lt;/p&gt;

&lt;p&gt;dbtest_high = (description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1522)(host=&lt;a href="http://adb.sa-saopaulo-1.oraclecloud.com" rel="noopener noreferrer"&gt;adb.sa-saopaulo-1.oraclecloud.com&lt;/a&gt;))(connect_data=(service_name=exampleservice_high.adb.oraclecloud.com))&lt;em&gt;(SECURITY =(MY_WALLET_DIRECTORY = &lt;/em&gt; C:\my_plsql_wallet&lt;em&gt;)(SSL_VERSION = 1.2)(SSL_CLIENT_AUTHENTICATION = FALSE))&lt;/em&gt;))&lt;/p&gt;

&lt;p&gt;IMPORTANTE: A partir do Oracle 23ai, o MY_WALLET_DIRECTORY foi substituído por WALLET_LOCATION.&lt;/p&gt;

&lt;p&gt;Referências:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.bar-solutions.com/?p=954" rel="noopener noreferrer"&gt;https://blog.bar-solutions.com/?p=954&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://forums.oracle.com/ords/apexds/post/one-client-needing-multiple-wallets-and-or-multiple-sqlnet-6227" rel="noopener noreferrer"&gt;https://forums.oracle.com/ords/apexds/post/one-client-needing-multiple-wallets-and-or-multiple-sqlnet-6227&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.oracle.com/en/database/oracle/oracle-database/23/netrf/local-naming-parameters-in-tns-ora-file.html#GUID-E48103F6-8B8B-457C-9374-695C7CCAD816" rel="noopener noreferrer"&gt;https://docs.oracle.com/en/database/oracle/oracle-database/23/netrf/local-naming-parameters-in-tns-ora-file.html#GUID-E48103F6-8B8B-457C-9374-695C7CCAD816&lt;/a&gt;&lt;/p&gt;

</description>
      <category>oracle</category>
      <category>autonomousdatabase</category>
    </item>
  </channel>
</rss>
