lunedì 22 settembre 2025

ODI 14c - Start e Stop Agent ODI Marketplace

Di seguito i comandi per effettuare lo start, stop e status di un agent ODI Marketplace in cloud oracle.

Il tutto è stato preso dalla nota del supporto oracle MOS_DOCUMENT_ID: 2921533.1

  • Start e stop utilizzando opc
    • Il servizio presente in cloud ha il seguente nome manageappsodi.service. Posizionato  in /usr/lib/systemd/system
      • sudo systemctl status manageappsodi.service
      • sudo systemctl stop manageodiapps.service
      • sudo systemctl start manageodiapps.service
  • Se invece utilizziamo l'utente oracle si possono utilizzare gli script posti in 
    • /u01/oracle/mwh/odi/common/scripts 
    • Per verificare lo stato:
      • python /u01/oracle/mwh/odi/common/scripts/manageOdiApps.py status
    • Per effettuare lo start invece possiamo utilizzare il seguente comandi ridirigendo l'output in un file manageappsodi.log file:
      • nohup python /u01/oracle/mwh/odi/common/scripts/manageOdiApps.py start > manageappsodi.log 2>&1 &
    • Lo stop / start dell'agent application lo possiamo effettuare con i seguenti comanti se jetty è up and running):
      • python /u01/oracle/mwh/odi/common/scripts/manageOdiApps.py stop -apps=APPODIAGENT
      • python /u01/oracle/mwh/odi/common/scripts/manageOdiApps.py start -apps=APPODIAGENT
    • Restart the agent:
      • python /u01/oracle/mwh/odi/common/scripts/manageOdiApps.py restart
    • Shutdown di  jetty and the agent:
      • python /u01/oracle/mwh/odi/common/scripts/manageOdiApps.py shutdown
    In alcuni casi si rende necessario effettuato uno stop forzato effettuando un kill -9 dei processi, per individuare i corretti processi si può effettuare il comando jps che indica gli ID Java in esecuzione di cui l'utente unix è proprietario.

    Di seguito alcuni esempi di status:






    Quanto indicato sopra si può applicare a:

    • All Users Oracle Data Integrator on Marketplace - Version 12.2.1.4.200618 and later

    martedì 16 settembre 2025

    ODI 14c - Utilizzo di OdiSqlUnload - OdiTools

     Per poter effettuare una select e relativo spool su filesystem si può utilizzare l'OdiTools OdiSqlUnload. Questo permette di eseguire una select utilizzando una connessione jdbc ed effettuare uno spool dei dati su un file su filesystem. Nelle versioni precedenti era permesso il passaggio delle password sia in chiaro che criptato, adesso nella versione 14c hanno risolto eventuali bug di sicurezza impedendo l'utilizzo di variabili con la password in chiaro.

    Se si vuole quindi utilizzare l'OdiTools si possono seguire due strade.

    -1- Inserire nell'OdiStudio la password in chiaro che viene criptata immediatamente dal Tools

    -2- Creare una procedura che estrae i dati prendendo la password dalla Topologia di ODI.


    1.  Creare un package nel quale inseriamo l'OdiTools e configuriamo i vari campi presenti nelle property.

      In questo caso verrà prodotto un file su filesystem


    2. Creazione di una procedura che richiama il comando dell'OdiTools che può essere estrapolato da quanto indicato sopra. In questo caso però non viene inserita alcuna password, questa viene estratta direttamente dalla topologia.

    Iniziamo creando una procedura con due Task, dove il primo ci serve per controllo, e può essere eliminato, il secondo invece contiene l'istruzione del comando relativo all'OdiTools con l'indicazione di estrarre la password dalla Topology. Questo implica che nella Topology occorre inserire le informazioni per la connessione al DB.


    Nel primo task sono stati inseriti alcuni comandi per effettuare un check visivo di quanto viene estratto e può essere tranquillamente rimosso.


    Nel secondo Task invece è riportato il comando di esecuzione dell'OdiTools:


    Di seguito il comando relativo all'OdiTools,in questo caso utilizziamo un utente DB che si chiama ODI_WORK. Al termine occorre inserire la query di estrazione dei dati. In grassetto la parte di estrazione della password dell'utente dalla Topology:

    OdiSqlUnload 
    "-FILE=/fd_MDM_TI/FileOutput/Test_OdiSqlUnload1.txt" 
    "-DRIVER=oracle.jdbc.OracleDriver" 
    "-URL=jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=....." 
    "-USER=ODI_WORK" 
    "-PASS=<%=odiRef.getInfo( "SRC_ENCODED_PASS" )%>" 
    "-FILE_FORMAT=VARIABLE" 
    "-FIELD_SEP=;" 
    "-ROW_SEP=\r\n" 
    "-DATE_FORMAT=yyyy/MM/dd" 
    "-TIME_FORMAT=HH:mm:ss" 
    "-CHARSET_ENCODING=ISO8859_1" 
    "-XML_CHARSET_ENCODING=ISO-8859-1"
    select 'aamm' as pippo, 'sjsjssjj' paperino from dual

    Per ulteriori informazioni su quanto indicato sopra fare riferimento alla documentazione ODI.
    Nella nuova versione di ODI 14c non sembra essere più possibile, come per la versione 12c, fornire in input al comando delle variabili di ambiente per quanto riguarda la password.
    Da tenere presente che questo risolve alcuni eventuali problemi di vulnerabilità del software in fase di esecuzione. 

    martedì 29 luglio 2025

    ODI 12c - How to aumentare la dimensione dell'heap in Oracle Data Integrator (ODI) Studio

    Per aumentare la dimensione dell'heap in Oracle Data Integrator (ODI) Studio, è necessario modificare il file di configurazione di ODI e riavviare lo studio.

    Nello specifico si deve modificare la direttiva:

    1. -Xms (dimensione minima dell'heap)
    2. -Xmx (dimensione massima dell'heap)

    nel file odi.conf.

    Ecco i passaggi dettagliati:

    1. Chiudere ODI Studio:
      1. Assicurarsi che ODI Studio sia completamente chiuso prima di apportare modifiche.
    1. Individuare il file odi.conf:
      1. Il file odi.conf si trova generalmente nella directory di installazione di ODI, nella sottocartella oracledi/agent/bin.
    1. Eseguire il backup del file:
      1. Prima di apportare modifiche, è consigliabile creare una copia di backup del file odi.conf.
    1. Aprire il file odi.conf per la modifica:
      1. Aprire il file odi.conf con un editor di testo.
    1. Modificare le direttive -Xms e -Xmx:
      1. Cercare le direttive -Xms e -Xmx. Queste direttive controllano rispettivamente la dimensione minima e massima dell'heap. Modificare i valori numerici per aumentarne la dimensione. Ad esempio, per impostare la dimensione massima dell'heap a 2GB, si potrebbe usare -Xmx2048m.
    1. Salvare e chiudere il file:
      1. Salvare le modifiche apportate al file odi.conf e chiuderlo.
    1. Riavviare ODI Studio:
      1. Avviare ODI Studio per applicare le modifiche. La nuova dimensione dell'heap verrà utilizzata al prossimo avvio.

    È importante notare che:

    La dimensione dell'heap deve essere appropriata per le risorse disponibili sul sistema. Iniziare con incrementi moderati e aumentare gradualmente se necessario.

    Se si utilizzano più agent, è necessario modificare il file odi.conf per ciascun agente. 

    • NOTE:
      • How To Clear The Cache For ODI Studio (Doc ID 1943854.1)
      • Unable to Launch ODI Studio Error - "Initial heap size set to a larger value than the maximum heap size" (Doc ID 2288151.1)
      • La directory dove è presente il file odi.conf sul Cloud in ODIMarketPlace è la seguente:
        • /u01/oracle/mwh/odi/studio/bin


    venerdì 16 maggio 2025

    DARCO - Data Archiving Organizer

    Di seguito daremo uno sguardo ad un software Oracle o meglio ad una soluzione di "Information Lifecycle Management" che permette di organizzare, gestire ed eseguire i processi di archiviazione dati con conseguente ottimizzazione della memoria utilizzata.

    Questa soluzione, realizzata in linguaggio plsql, è installabile su qualsiasi database Oracle a partire dalla versione 12C.

    La soluzione, come molti prodotti Oracle risulta essere DataBase centrica e si compone di un repository di metadati, di un handler ed una suite di custom plsql API, atte a:

    • Definire e personalizzare i criteri di data retentntion 
    • Configurare le strutture dati coinvolte 
    • Archiviare i dati da uno schema sorgente, ad uno schema di storico/archiviazione
    • Gestire ed ottimizzare la memoria delle strutture dati configurate sullo schema sorgente.

    Il repository dei metadati si compone di set di tabelle tra loro correlate, che si articolano nelle seguenti macrocategorie di contenuti:

    • Configurazioni
    • Processing
    • Log

    Nei prossimi articoli vedremo meglio alcune delle opzioni implementate in questo software che al momento sono 3.
    L'ultima opzione implementata è la seguente:
    • ARCHIVE_STRATEGY = 'Z' 
      • Si effettua il backup di tutti i records delle tabelle configurate nella tabella di Metadato DARCO_TABLES che sono soggetti oltre ad una data di cutoff_date anche a delle regole di BUSINESS configurate in tali tabelle. Una volta che i dati verranno spostati, in un altro schema Target che li conterrà come un Backup, questi verranno cancellati dallo schema Source.  Poichè possono essere presenti FK anche i record che rientrano all'interno della data di cutoff e che sono legati alla tabella Padre verranno spostati nello schema Target di Backup. 

    mercoledì 19 febbraio 2025

    RDBMS ORACLE - Quale grant dare per poter effettuare una truncate table

    Qual è la corretta grant per poter troncare una tabelle di un altro utente in oracle?

    --------------------------------------------------------------------

    • Connettersi come sys as sysdba

    select user from dual;

    USER                          

    ------------------------------

    SYS

    • Eseguire il seguente script per dare le grant.

    declare

          onlineSchema varchar2(500) := 'DWH_ANALYTICS';

          archiveSchema varchar2(500) := 'DWH_MD';

    begin

          execute immediate 'grant  drop any table to '||onlineSchema;

    end;

    PL/SQL procedure successfully completed.


    -----------------

    select * from all_tab_privs where table_name='TEST_TRUNCATE_TABLE' and GRANTOR='DWH_MD';


    no rows selected

    -----------------


    • Connettersi come DWH_ANALYTICS

    select user from dual;


    USER                          

    ------------------------------

    DWH_ANALYTICS


    SELECT * FROM DWH_MD.TEST_TRUNCATE_TABLE;


    ORA-01031: insufficient privileges

    01031. 00000 -  "insufficient privileges"

    *Cause:    An attempt was made to perform a database operation without

               the necessary privileges.

    *Action:   Ask your database administrator or designated security

               administrator to grant you the necessary privileges

    Error at Line: 1 Column: 23


    • Eseguire la TRUNCATE della tabella

    TRUNCATE TABLE DWH_MD.TEST_TRUNCATE_TABLE;


    Table DWH_MD.TEST_TRUNCATE_TABLE truncated.


    -------------------------------------------------------------------

    Connettersi nuovamente come sys e revocare il privilegio

    select user from dual;

    USER                          

    ------------------------------

    SYS


    • Eseguire lo script

    declare

          onlineSchema varchar2(500) := 'DWH_ANALYTICS';

          archiveSchema varchar2(500) := 'DWH_MD';

    begin

          execute immediate 'revoke drop any table from '||onlineSchema;

    end;


    PL/SQL procedure successfully completed.


    -------

    select * from all_tab_privs where table_name='TEST_TRUNCATE_TABLE' and GRANTOR='DWH_MD';


    no rows selected

    -------

    Documentazione Oracle:

    https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/TRUNCATE-TABLE.html



    martedì 21 gennaio 2025

    RDBMS ORACLE - DDL MINUS - Genera uno script per verificare il contenuto di due tabelle

     Di seguito una query che genera la ddl per una minus tra due tabelle ed inserisce il contenuto in una tabella di appoggio.

    SELECT 
      'INSERT INTO DM_ITI.APPO_COUNT_DIFF '||CHR(10)||MNS||CHR(10)||'COMMIT;' DDL_MINUS
    FROM 
    (SELECT 
       'SELECT COUNT(1) , '''||TAB||''' TAB_NAME FROM ('||CHR(10)|| MN ||');' AS MNS
     FROM
    SELECT   LISTAGG(SEL_MINUS, chr(10)||' MINUS '||CHR(10)) 
                                WITHIN GROUP (ORDER BY COL_ORD) MN, TAB
         FROM
    (SELECT 
      'SELECT '||LISTAGG(Column_Name,', ')  
        WITHIN GROUP (ORDER BY COLUMN_ID)||' FROM '|| OWNER ||'.'||TABLE_NAME SEL_MINUS,
           OWNER ||'.'||TABLE_NAME TAB,  1 COL_ORD
    FROM
     (  SELECT Column_Name,Column_Id ,OWNER,TABLE_NAME,
             COUNT(column_id) OVER (PARTITION BY TABLE_NAME) CC, data_type
        FROM SYS.ALL_TAB_COLUMNS
        WHERE OWNER=UPPER('DM_ITI') AND table_name=UPPER('DIM_ARGOMENTO'
        ORDER BY 2)
    GROUP BY OWNER,TABLE_NAME
       UNION ALL
     SELECT  
      'SELECT '||LISTAGG(Column_Name,',')  WITHIN GROUP (ORDER BY COLUMN_ID)||' FROM '||     OWNER ||'.'||TABLE_NAME||'@DB_LINK' AS  SEL_MINUS, OWNER ||'.'||TABLE_NAME TAB,
        2 COL_ORD
    FROM
     ( SELECT Column_Name,Column_Id ,OWNER,TABLE_NAME,
            COUNT(column_id) OVER (PARTITION BY TABLE_NAME) CC, data_type
        FROM SYS.ALL_TAB_COLUMNS
        WHERE OWNER=UPPER('DM_ITI') AND table_name=UPPER('DIM_ARGOMENTO')
        ORDER BY 2)
    GROUP BY OWNER,TABLE_NAME
    )
    GROUP BY TAB
    ));

    Questa una volta eseguita genera il seguente statement sql:

    INSERT INTO DM_ITI.APPO_COUNT_DIFF 
         SELECT COUNT(1) , 'DM_ITI.DIM_ARGOMENTO' TAB_NAME 
             FROM (
                  SELECT TIPARGID, TIPARGDESCRIZIONE, TIPARGDATCAR 
                         FROM 
                               DM_ITI.DIM_ARGOMENTO
                MINUS 
                  SELECT TIPARGID,TIPARGDESCRIZIONE,TIPARGDATCAR 
                       FROM    
                            DM_ITI.DIM_ARGOMENTO@DB_LINK);
    COMMIT;

    ------------------------------------------------------------------------------------
    Una volta eseguito lo statement sql avremo:



    In questo caso le due tabelle sono identiche.

    -----------------------------------------------------------------------------------

    Di seguito la DDL della tabella in cui inserire le count:

      CREATE TABLE "DM_ITI"."APPO_COUNT_DIFF" 
       ( "CC_DIFF" NUMBER, 
    "TAB_NAME" VARCHAR2(200 BYTE)
       ) ;

    COMMENT ON COLUMN "DM_ITI"."APPO_COUNT_DIFF"."CC_DIFF" IS 'COUNT delle differenze = 0 Tabelle uguali >0 Tabelle differenti come contenuto';

    COMMENT ON COLUMN "DM_ITI"."APPO_COUNT_DIFF"."TAB_NAME" IS 'Schema.Tabella indigata';





    martedì 14 gennaio 2025

    RDBMS ORACLE - Funzione SecondsSinceFromTimestamp IBM-DS Vs ORACLE


    La funzione SecondsSinceFromTimestamp in IBM- DataStage:

     

    SecondsSinceFromTimestamp(DATA_INIZIO_EVENTO, DATA_FINE_EVENTO)

     

    effettua una differenza tra due timestamp in secondi.

    Da documentazione IBM:




    In oracle non esiste una funzione che effettua questa differenza, per cui occorre creare una funzione 
    custom da richiamare. 

    La funzione che è stata creata ha lo stesso nome di quella presente in  IBM-DS.

    Da notare che la funzione presente in IBM - Datastage non effettua una differenza non tra END_DATE - START_DATE ma al contrario effettua una differenza tra la START_DATE - END_DATE per cui se consideriamo la differenza di un giorno tra start ed end avremo come risultato -86400, come indicato da documentazione IBM-DS.


    Il valore come si vede è negativo -86400 secondi.

    Se eseguiamo in oracle la funzione presente sotto avremo come risultato final -86400.


    ---------------------------------------------------------------------------------------------------------

    create or replace  

    FUNCTION SecondsSinceFromTimestamp

    (start_time_in TIMESTAMP, end_time_in TIMESTAMP)RETURN NUMBER

    AS

    l_days NUMBER;

    l_hours NUMBER;

    l_minutes NUMBER;

    l_seconds NUMBER;

    sec_tot NUMBER;

    BEGIN

    SELECT 

      EXTRACT(DAY FROM start_time_in - end_time_in)

    , EXTRACT(HOUR FROM start_time_in - end_time_in)

    , EXTRACT(MINUTE FROM start_time_in - end_time_in)

    , extract(SECOND FROM start_time_in - end_time_in)

    INTO l_days, l_hours, l_minutes, l_seconds

    FROM dual;

     

    sec_tot := l_seconds + l_minutes*60 + l_hours*60*60 + l_days*24*60*60;

    RETURN sec_tot;

    END;