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;