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;

mercoledì 11 settembre 2024

RDBMS ORACLE - Statistiche di uno schema DB

 Di seguito alcuni comandi per raccogliere le statistiche di uno schema oracle:

  • DBMS_UTILITY.ANALYZE_SCHEMA --> viene utilizzato per raccogliere statistiche per tutte le tabelle, i cluster e gli indici di uno schema.
Examples:

  • EXEC DBMS_UTILITY.ANALYZE_SCHEMA('SCOTT','COMPUTE');

  • EXEC DBMS_UTILITY.ANALYZE_SCHEMA('SCOTT','ESTIMATE', estimate_rows => 1000);

  • EXEC DBMS_UTILITY.ANALYZE_SCHEMA('SCOTT','ESTIMATE', estimate_percent => 25);

  • EXEC DBMS_UTILITY.ANALYZE_SCHEMA('SCOTT','DELETE');

Note: È anche possibile analizzare l'intero database con il comando  DBMS_UTILITY.ANALYZE_DATABASE('COMPUTE'); 

oppure si può utilizzare DBMS_STATS.GATHER_TABLE_STATS

  • EXEC DBMS_STATS.GATHER_SCHEMA_STATS(ownname => 'CONTRACT', cascade =>true,estimate_percent => dbms_stats.auto_sample_size);

  • EXECUTE DBMS_STATS.GATHER_TABLE_STATS(ownname => 'CONTRACT', tabname => 'CONT_NAME', method_opt => 'FOR ALL COLUMNS', granularity => 'ALL', cascade => TRUE, degree => DBMS_STATS.DEFAULT_DEGREE);

il seguente script genererà l'elenco dei comandi per l'analisi di tutte le tabelle nello schema.

SELECT 'EXECUTE DBMS_STATS.GATHER_TABLE_STATS
 (ownname =>'||CHR(39)||'CONTRACT'||CHR(39)||', 
  tabname =>'||CHR(39)||TNAME||CHR(39)||', 
  method_opt => ''FOR ALL COLUMNS'', 
  granularity => ''ALL'', 
  cascade => TRUE, 
  degree => DBMS_STATS.DEFAULT_DEGREE);'
FROM TAB;

Terminando abbiamo la possibilità di utilizzare due metodi differenti per la raccolta delle statistiche. Per capire quale utilizzare si rimanda alla documentazione ORACLE:

  • DBMS_UTILITY.ANALYZE_SCHEMA
  • DBMS_STATS.GATHER_TABLE_STATS



lunedì 12 agosto 2024

SQL developer error with "disable modules and continue"

Nel caso in cui state utilizzando SQLDEVELOPER e ricevete un errore del tipo:

"Warning - could not install some modules: oracle.java_annotations - org.netbeans.InvalidException: Netigso: D:\sqldeveloper-4.0.2.15.21-no-jre\sqldeveloper\ide\lib\annotations.jar: Not found bundle:oracle.java_annotations oracle.ide_boot  ecc."

Allora occorre fare un pò di pulizia nella system_cache di sqldeveloper.

L'esempio di seguito è per UBUNTO.


Una volta cancellata la directory si può aprire nuovamente ODI.