giovedì 3 marzo 2016

RDBMS ORACLE - Utilizzo di DBMS_SQL per SPOOL su un file

Un amico mi ha chiamato e mi ha chiesto come funziona DBMS_SQL allora ho riscoperto due vecchie procedure e funzioni in cui si utilizza questo package per effettuare lo spool su file di una select oppure di una intera tabella.
Visto che mi piace condividere di seguito il codice:
Dobbiamo creare 3 funzioni ed una procedura di seguito i nomi:


  • Funzione IS_NUMBER_CHAR
  • Funzione ISDATE
  • Funzione DUMP_CSV
  • Procedura DUMP_TABLE_TO_CSV

Le prime due sono solo di contorno e vengono utilizzate nella procedura per capire se il contenuto del campo di cui stiamo per fare lo spoo sia Number, Varchar o Date a seconda della tipologia l'output viene scritto in modo diverso.


CREATE OR REPLACE  FUNCTION is_number_char(
    p_value VARCHAR2)
  RETURN NUMBER
-- 0 Alpha
-- 1 Number
-- 3 Errore
AS
  n_num NUMBER     :=3;
  v_num varchar2(30):=NULL;
BEGIN
  SELECT
    CASE
      WHEN INSTR(p_value,'-')>1
      THEN 'alpha'
      WHEN p_value LIKE '%.%.%'
      THEN 'alpha'
      WHEN p_value LIKE '-%-%'
      THEN 'alpha'
      WHEN REGEXP_LIKE(p_value,'^[-0-9.,]*$')
      THEN 'numeric'
      ELSE 'alpha'
    END is_numeric
  INTO v_num
  FROM dual;
  
IF v_num='alpha' THEN n_num:=0; elsif v_num='numeric' THEN n_num:=1; END IF;

RETURN n_num;

exception
WHEN OTHERS THEN
  n_num:=3;
  RETURN n_num;
END;

CREATE OR REPLACE FUNCTION isdate(
    p_string IN VARCHAR2,
    p_fmt    IN VARCHAR2 := 'yyyy-mm-dd hh24:mi:ss' )
  RETURN NUMBER
AS
  l_date DATE;
BEGIN
  l_date :=to_date(p_string,p_fmt);
  RETURN 0;
EXCEPTION
WHEN OTHERS THEN
  RETURN 1;
END;

A questo punto vi incollo il codice della procedura per lo spool del contenuto di una tabella, che riceve in input il nome della tabella, la directory di spool ed il nome del file.

CREATE OR REPLACE PROCEDURE dump_table_to_csv(
    p_tname    IN VARCHAR2,
    p_dir      IN VARCHAR2,
    p_filename IN VARCHAR2 )
IS
  l_output utl_file.file_type;
  l_theCursor   INTEGER DEFAULT dbms_sql.open_cursor;
  l_columnValue VARCHAR2(4000);
  l_status      INTEGER;
  l_query       VARCHAR2(1000) DEFAULT 'select * from ' || p_tname;
  l_colCnt      NUMBER := 0;
  l_separator   VARCHAR2(1);
  L_DESCTBL DBMS_SQL.DESC_TAB;
  L_QUOTE VARCHAR2(1);
BEGIN
  L_OUTPUT := UTL_FILE.FOPEN( P_DIR, P_FILENAME, 'w', 32760);

-- Altero il formato data per lo spool

  EXECUTE immediate 'alter session set nls_date_format=''yyyy-mm-dd hh24:mi:ss'' ';

  dbms_sql.parse( l_theCursor, l_query, dbms_sql.native );
  DBMS_SQL.DESCRIBE_COLUMNS( L_THECURSOR, L_COLCNT, L_DESCTBL );

  FOR i IN 1 .. l_colCnt
  LOOP
    utl_file.put( l_output, l_separator || '"' || l_descTbl(i).col_name || '"' );

    DBMS_SQL.DEFINE_COLUMN( L_THECURSOR, I, L_COLUMNVALUE, 4000 );
    l_separator := ';';

  END LOOP;
  utl_file.new_line( l_output );
  l_status := dbms_sql.execute(l_theCursor);

  WHILE ( dbms_sql.fetch_rows(l_theCursor) > 0 )
  LOOP
    l_separator := '';
   
   FOR i IN 1 .. l_colCnt
    LOOP
      DBMS_SQL.COLUMN_VALUE( L_THECURSOR, I, L_COLUMNVALUE );
     
   -- Verifico la tipologia del contenuto del campo

      IF IS_NUMBER_CHAR(l_columnValue) =0 AND ISDATE(l_columnValue) =0 THEN
        l_quote                       := '"';

      -- Se di tipo Varchar lo metto tra doppi apici 
      
        l_columnValue := REPLACE(l_columnValue,'"','""');
      ELSE
        L_QUOTE := '';
      END IF;
      UTL_FILE.PUT( L_OUTPUT, L_SEPARATOR || L_QUOTE || L_COLUMNVALUE || L_QUOTE);
      l_separator := ';';
    END LOOP;
    utl_file.new_line( l_output );

  END LOOP;
  
   dbms_sql.close_cursor(l_theCursor);
  utl_file.fclose( l_output );

-- Altero il formato rimettendolo come era prima

  EXECUTE immediate 'alter session set nls_date_format=''dd-MON-yy'' ';

EXCEPTION
WHEN OTHERS THEN
  EXECUTE immediate 'alter session set nls_date_format=''dd-MON-yy'' ';
  raise;
END;

Per lanciarlo possiamo usare:

DECLARE
  P_TNAME VARCHAR2(200);
  P_DIR VARCHAR2(200);
  P_FILENAME VARCHAR2(200);
BEGIN
  P_TNAME := 'GAIA_FILE1_STEP1_WORK';
  P_DIR := 'DATA_PUMP_DIR';
  P_FILENAME := 'GAIA_FILE1_STEP1_WORK.LOg';

  DUMP_TABLE_TO_CSV(
    P_TNAME => P_TNAME,
    P_DIR => P_DIR,
    P_FILENAME => P_FILENAME
  );
--rollback; 
END;

Adesso vediamo l'utilizzo del DBMS_SQL per lo spool fornendo in input una select.
Questa non è opera mia e non ricordo nemmeno più dove abbia recuperato questa funzione di spool, però come si suol dire funziona. Forse da AskTom ma non ricordo, risale ad almeno dieci anni fà.

create or replace function  dump_csv( p_query     in varchar2,
                                      p_separator in varchar2 default ',',
                                      p_dir       in varchar2 ,
                                      p_filename  in varchar2,
                                      p_header    IN VARCHAR2,
                                      p_endline   IN VARCHAR2 DEFAULT chr(13))
   -- This routine makes certain assumptions.
   -- 1) There must be a query and it can't be greater then 32K.
   -- 2) The separator must only be one character in length and can't be 
   --    a CR, LF, binary 0, or null (easy to change).
   -- 3) If the p_dir parameter is null, the p_filename must contain the
   --    path and filename (/tmp/output.txt)
   -- 4) If the p_header parameter is not null, then insert it into the first
   --    row of the output file. If the p_separator parameter is not a comma, 
   --    the comma's in the header string will be replaced with the new
   --    separator. so to add a header use 'NAME,FIRST_NAME,LAST_NAME' and if
   --    the separator is a tab, what is put into the file would be 
   --    'NAME<tab>FIRST_NAME<tab>LAST_NAME'
   -- 5) The value of p_endline will be appended to the end of each line of the 
   --    output file. It can be used to add a carriage return before the 
   --    Line Feed is inserted by the NEW_LINE (unix). If the server is running
   --    on a windows machine, set this to null since the NEW_LINE will save 
   --    a CR,LF pair anyway. This can also be used if you needed to put 
   --    something at the end. For exanple "'|'||CHR(13)" which would put a 
   --    vertical bar and CR,LF on each line on a unix machine.
   -- 
   -- The following are the returned error codes
   -- -1 The query is empty
   -- -2 The output filename is empty
   -- -3 The separator is invalid.
   -- -4 The filename only contains the path, no filename specified.
   -- -5 The output file can not be opened.
   -- -6 The query could not be parsed. It was illegal.
   --  0 The query returned NO records.
   -- >0 The number of records returned.

return number
is
    l_output        utl_file.file_type;
    l_theCursor     integer default dbms_sql.open_cursor;
    l_columnValue   varchar2(20000000);
    l_status        integer;
    l_colCnt        number default 0;
    l_separator     varchar2(10) default '';
    l_cnt           number default 0;
    l_dir           VARCHAR2(500);
    l_filename      VARCHAR2(32);
    x_pnt           NUMBER(4);
    l_header        VARCHAR2(200);
begin
    -- sanity check the input
    IF p_query IS NULL THEN
       RETURN(-1);
    END IF;
    IF p_filename IS NULL THEN
       RETURN(-2);
    END IF;
    -- Do not allow CR, LF,binary 0, or null to be used as a separator. 
    -- The length of the separator must be 1 if it exists.
    IF p_separator IS NULL OR
       p_separator IN (chr(13),chr(10),chr(0)) OR
       length(p_separator) > 1 THEN
       RETURN(-3);
    END IF;
    -- If the directory parameter is blank, assume that the directory
    -- is included in the filename.
    IF p_dir IS NOT NULL THEN
       l_dir := p_dir;
       l_filename := p_filename;
    ELSE
       x_pnt := instr(p_filename,'/',-1,1);
       -- If no path is specified or no filename is specified,
       -- the procedure will not work... get out.
       IF x_pnt = 0 OR x_pnt = length(p_filename) THEN
          RETURN(-4);
       END IF;
       l_dir := substr(p_filename,1,x_pnt-1);
       l_filename := substr(p_filename,x_pnt+1);
    END IF;


    -- Check to see if the file can be opened. If ANY error is 
    -- encountered, exit with a count of -1;
    BEGIN
       l_output := utl_file.fopen( l_dir, l_filename, 'w', 32767 );
    EXCEPTION
       WHEN OTHERS THEN
          RETURN(-5);
    END;

    -- Check to see if the query can be processed. if ANY error is
    -- encountered, close the output file and exit.
    BEGIN
       dbms_sql.parse(  l_theCursor,  p_query, dbms_sql.native );
    EXCEPTION
       WHEN OTHERS THEN
          utl_file.fclose( l_output );
          RETURN(-6);
    END;

    -- If the p_header parameter is not null, then insert the line as
    -- the first line in the output file. This is used if the user wants
    -- to insert column headings. Make sure to use a comma in your header 
    -- line and the routine will replace all comma;s with the specified 
    -- separator.
    l_header := NULL;
    IF p_header IS NOT NULL THEN
       l_header := p_header;
       IF p_separator <> ',' THEN
          l_header := REPLACE(l_header,',',p_separator);
       END IF;
    END IF;

    -- Loop through all the parameters for the select. To support
    -- unknown querys, the assumption is that the query will return
    -- all columns as varchar2 columns where the data is correctly
    -- formatted for inport. A maximum of 255 columns are supported
    -- in the query. Each column can't be greater then 2000
    -- characters in length.

    
    
    for i in 1 .. 255 loop
        begin
            dbms_sql.define_column( l_theCursor, i, l_columnValue, 2000 );
            l_colCnt := i;
        exception
            when others then
                if ( sqlcode = -1007 ) then exit;
                else
                    raise;
                end if;
        end;
    end loop;
    -- This define_column insures that at least one column is defined for the
    -- routine.
    dbms_sql.define_column( l_theCursor, 1, l_columnValue, 2000 );

    -- Fire the query.

    l_status := dbms_sql.execute(l_theCursor);

    -- Loop through all the rows returned by the query. Build up the output file
    -- by looping through the defined columns.

    loop
        exit when ( dbms_sql.fetch_rows(l_theCursor) <= 0 );
        IF l_cnt = 0 AND l_header IS NOT NULL THEN
           utl_file.put(l_output, l_header);
           utl_file.put(l_output, p_endline);
           UTL_FILE.NEW_LINE (l_output,1);
           l_cnt := 1;
        END IF;
        l_separator := '';
        for i in 1 .. l_colCnt loop
            dbms_sql.column_value( l_theCursor, i, l_columnValue );
            utl_file.put( l_output, l_separator || l_columnValue );
            l_separator := p_separator;
        end loop;
       utl_file.put(l_output, p_endline);
       UTL_FILE.NEW_LINE (l_output,1);
       l_cnt := l_cnt+1;
    end loop;

    -- Processing done. close the cursor and output file.

    dbms_sql.close_cursor(l_theCursor);
    utl_file.fclose( l_output );
    
    -- Return the number of rows built in the csv file.

    return l_cnt;
    -- If Any error occures outside of the errors checked above, then raise 
    -- and error and blow out the procedure.
    EXCEPTION
       WHEN OTHERS THEN
          RAISE;
end dump_csv;


Per lanciarla basta eseguire quanto indicato di seguito, ha però qualche problemino nella generazione dell'header. Forse per questo non è mai stata usata.

DECLARE
  P_QUERY VARCHAR2(20000);
  P_SEPARATOR VARCHAR2(200);
  P_DIR VARCHAR2(200);
  P_FILENAME VARCHAR2(200);
  P_HEADER VARCHAR2(200);
  P_ENDLINE VARCHAR2(200);
  v_Return NUMBER;
BEGIN
  P_QUERY := 'SELECT SOCIETA,  SETT_CON, SOCIETA_CONTROPARTE,
          IMPORTO,  IMPONIBILE,  IVA_COSTO,  BOLLO,
          SCENARIO,  CUSTOM1,  CUSTOM2,  CUSTOM3,  CUSTOM4,
         FROM GAIA_FILE1_STEP1_WORK';
  P_SEPARATOR := ',';
  P_DIR := 'DATA_PUMP_DIR';
  P_FILENAME := 'GAIA_FILE1_STEP1_WORK.CSV';
  P_HEADER := '######';
  P_ENDLINE := 'chr(13)';

  v_Return := DUMP_CSV(
    P_QUERY => P_QUERY,
    P_SEPARATOR => P_SEPARATOR,
    P_DIR => P_DIR,
    P_FILENAME => P_FILENAME,
    P_HEADER => P_HEADER,
    P_ENDLINE => P_ENDLINE
  );

DBMS_OUTPUT.PUT_LINE('v_Return = ' || v_Return);

  :v_Return := v_Return;
--rollback; 
END;


Finito.. a Paole.. vanno bene come esempi?
Dimenticavo altre info le trovate qui:




OWB 10gR2 - Query sul catalogo

Oggi rispolveriamo un altro dinosauro in via di estinzione OWB 10gR2 (Oracle Warehouse Builder) e vediamo alcune query da utilizzare per estrarre informazioni relativamente al runtime oppure alle locations.

Come per le query dei cursori visti qualche giorno fa io le elenco di seguito, poi le approfondite voi io non ve le spiego.



  • Info Locations

SELECT location.name           NAME
      ,location.description 
      ,location.loctypeversion version
      ,location.loctype
      ,location.elementid
      ,prop.logicalname
      ,prop.value              VALUE
      ,prop.createdby
      ,row_number () over (partition by location.name order by location.name) num_rec
  FROM cmplogicallocation_v     location
      ,cmpstringpropertyvalue_v prop
 WHERE location.elementid = prop.propertyowner;

  • Analisi Esecuzioni
select
 o.object_name "Object Name",
 o.object_type "Type",
 eo.created_on "Created On"
from all_rt_objects o,
  (select
     e.object_uoid as euoid,
     max(created_on) created_on
   from
     all_rt_audit_executions e
   group by e.object_uoid) eo
where
  eo.euoid=o.object_uoid order by object_name;

  • Process Flows
select distinct object_name PROCESS_NAME from all_rt_tasks  where task_type='ProcessFlow' order by object_name;

  • Process Flows Attivi
select p.execution_audit_id "Audit ID",c.task_name "Activity Name",
c.execution_audit_id "Activity ID", c.parent_execution_audit_id "Parent ID",
c.exec_location_name "Location", 
c.return_result "Result", ml.message_text "Audit Text"
from all_rt_audit_executions c, all_rt_audit_executions p,
all_rt_audit_exec_messages ml
where c.parent_execution_audit_id=p.execution_audit_id and
p.object_name=:PROCESS_NAME and
p.object_type='ProcessFlow' and
ml.execution_audit_id(+)=c.execution_audit_id
order by p.created_on DESC, c.execution_audit_id DESC;

  • Process Flows Overview
select to_char(p.created_on, 'HH:MM:SS DD-MON-YY') "Exec Date",p.execution_audit_id "Audit ID", p.return_Result "Result"
from  all_rt_audit_executions p
where p.object_name=:PROCESS_NAME and
object_type='ProcessFlow' 
order by p.created_on DESC, p.execution_audit_id DESC;

  • Parametri di esecuzione
select  execution_audit_id "Audit Id", parameter_name "Parameter", parameter_type "Type", value "Value" from all_rt_audit_execution_params
where execution_audit_id in (
  select distinct execution_audit_id from all_rt_audit_executions
  where object_name=:PROCESS_NAME and
  object_type='ProcessFlow')
order by execution_audit_id DESC, parameter_audit_id ASC;

  • Mapping
select distinct object_name MAPPING_NAME from all_rt_tasks  where (object_type='SQLLoaderControlFile' or object_type='ABAPFile' or object_type = 'PLSQLMap' or object_type = 'Mapping') order by object_name;

  • Throughput
select r.start_time startd, mr.map_name "Map Name"
, t.target_name "Target"
,r.step_id "Step"
, to_char(r.start_time,'DD-MON hh24:mi') "Exec Date"
, to_char(r.end_time,'DD-MON hh24:mi') "End"
, to_char(trunc(r.elapse_time/60))
|| 'm '
|| to_char(r.elapse_time - 60 * trunc(r.elapse_time/60))
|| 's' "Exec Time"
, substr(r.step_type,1,3) "Type"
, nvl(r.number_records_merged,0)+nvl(r.number_records_inserted,0)+nvl(r.number_records_updated,0) "No Records"
, decode( nvl(r.elapse_time,0)
, 0, 'N/A'
, to_char(trunc((nvl(r.number_records_merged,0)+nvl(r.number_records_inserted,0)+nvl(r.number_records_updated,0)) / r.elapse_time , 2))
) ||' Per Second' "Throughput"
from all_rt_audit_map_runs mr
, all_rt_audit_step_runs r
, all_rt_audit_step_run_targets t
where (mr.map_name=:MAPPING_NAME or substr(mr.map_name, 2, length(mr.map_name)-2) = :MAPPING_NAME)
and mr.map_run_id = r.map_run_id
and mr.map_run_id = t.map_run_id
and r.step_id = t.step_id
and r.run_status = 'COMPLETE'
order by startd DESC;

  • OwbErr
SELECT ALL_IV_RUN_ERROR.ERROR_MESSAGE
, ALL_IV_MAP_RUN.MAP_NAME
, ALL_IV_RUN_ERROR.RUN_TARGET_NAME
, to_char(ALL_IV_MAP_RUN.START_TIME,'dd-mon-yyyy hh24:mi:ss')
, ALL_IV_MAP_RUN.NUMBER_ERRORS
, ALL_IV_MAP_RUN.NUMBER_RECORDS_DELETED
, ALL_IV_MAP_RUN.NUMBER_RECORDS_DISCARDED
, ALL_IV_MAP_RUN.NUMBER_RECORDS_INSERTED
, ALL_IV_MAP_RUN.NUMBER_RECORDS_SELECTED
, ALL_IV_MAP_RUN.NUMBER_RECORDS_UPDATED
FROM DC_PRIMO_LIV.ALL_IV_MAP_RUN ALL_IV_MAP_RUN
, DC_PRIMO_LIV.ALL_IV_RUN_ERROR ALL_IV_RUN_ERROR
WHERE ( ( ALL_IV_MAP_RUN.MAP_RUN_ID = ALL_IV_RUN_ERROR.MAP_RUN_ID ) ) 
AND ( UPPER(ALL_IV_MAP_RUN.MAP_NAME) LIKE UPPER('%DPPS%') )
-- AND (UPPER( ALL_IV_RUN_ERROR.ERROR_MESSAGE) LIKE '%ANALYZE%')
AND ( ALL_IV_MAP_RUN.START_TIME >= '27/04/2016' )
ORDER BY ALL_IV_MAP_RUN.START_TIME;

E potremmo continuare cosi per un bel pò.
Se a qualcuno possono servire basta che mi contatti e  mando l'xml da importare come Report di SqlDeveloper.
Di seguito un elenco delle query disponibili.

Ciao





lunedì 29 febbraio 2016

ODI - Errore ODI -1266 : agent detected session as stale session.

Allora se vi capita questo tipo si errore sappiate che è successo qualcosa al Vs Agent. Una volta che viene restartato l'agent marca come stale le sessioni rimaste secondo lui appese.
Il problema quindi è stato causato da problemi di connessione, par capire quali verificare il log dell'agent se attivi,

Una migliore descrizione di quello che accade la trovate a questo link:




La sessioni stale sono sessioni che erroneamente vengono lasciate in uno stato di esecuzione dopo che un agente va in errore. L'agent che ha iniziato una sessione rileva automaticamente quando questa sessione diventa stale e ne cambia lo stato mettendolo in errore.

È possibile richiedere manualmente all'agent di pulire le sessioni stale. Per pulire le sessioni stale manualmente:


  • Dal menu della barra degli strumenti Operatore Navigator, selezionare Clean Stale Sessions.
  • In topologia Navigator, da Architettura fisica selezionare un agent e fare clic destro e selezionare Clean Stale Sessions.
  • Nella finestra di dialogo  specificare i criteri per la pulizia sessioni di stale:
    • Dall'elenco, selezionare gli agent che dovranno ripulire le loro sessioni stale.
    • Selezionare Pulire tutti gli agenti se si desidera pulire tutti gli  agent
    • Dall'elenco, selezionare i repository di Work che si desidera pulire.
    • Selezionare Cancella tutti gli archivi di Work se si desidera pulire le sessioni stale in tutti i repository di work.
    • Fare clic su Pulisci per avviare il processo di pulizia.
A questo punto aspettate, aspettate .... aspettate.

Ulteriori info le trovate a questi link:


  1. http://www.ateam-oracle.com/how-to-understand-and-diagnose-odi-connectivity-issues/
  2. http://docs.oracle.com/cd/E25054_01/core.1111/e10106/odi.htm#BGBEGCBB
  3. https://community.oracle.com/thread/2502935?start=0&tstart=0
  4. http://docs.oracle.com/cd/E28271_01/integrate.1111/e12643/running_executions.htm

OBIEE - 10.1.3.4.2 Installazione e configurazione

Oggi parliamo di archeologia Oracle e quindi di OBIEE 10g, per la precisione la versione 10.1.3.4.2      da installare su singola macchina o su un cluster. In entrambi cambia poco l'unica differenza sta nella configurazione di alcuni files.
Prima di continuare occorre dire che bisogna installare oltre la OBIEE anche una corretta Jdk ed un client oracle alfine di poter utilizzare la connessione ad un database oracle.

Quindi occorre procurarsi quanto segue, ormai software un pò difficile da trovare:
  1.         Java Jdk         à jdk1.6.0.21      directory di installazione /usr/java/jdk1.6.0.21
  2.        Client Oracleà 11gR2 (32 bit)  directory di installazione /u01/app/oracle/product/11.2.0/client_1
  3.         OBIEE           à 10.1.3.4.2        directory di installazione /u01/app/oracle/product/obiee

Step 1 - Per quanto riguarda il punto 1 l'installazione è semplice, a dimenticavo installiamo in ambiente Linux, quindi scaricarsi la jdk in fomrato .bin o rpm ed installarla.

[root@RSVLBI1 stage]# ./jdk-6u21-linux-x64-rpm.bin
Unpacking...
Checksumming...
Extracting...
UnZipSFX 5.50 of 17 February 2002, by Info-ZIP (Zip-Bugs@lists.wku.edu).
  inflating: jdk-6u21-linux-amd64.rpm
  inflating: sun-javadb-common-10.5.3-0.2.i386.rpm
  inflating: sun-javadb-core-10.5.3-0.2.i386.rpm
  inflating: sun-javadb-client-10.5.3-0.2.i386.rpm
  inflating: sun-javadb-demo-10.5.3-0.2.i386.rpm
  inflating: sun-javadb-docs-10.5.3-0.2.i386.rpm
  inflating: sun-javadb-javadoc-10.5.3-0.2.i386.rpm
Preparazione in corso...    ########################################### [100%]
   1:jdk                    ########################################### [100%]
Unpacking JAR files...
        rt.jar...
        jsse.jar...
        charsets.jar...
        tools.jar...
        localedata.jar...
        plugin.jar...
        javaws.jar...
        deploy.jar...
Installing JavaDB
Preparazione in corso...    ########################################### [100%]
   1:sun-javadb-common      ########################################### [ 17%]
   2:sun-javadb-core        ########################################### [ 33%]
   3:sun-javadb-client      ########################################### [ 50%]
   4:sun-javadb-demo        ########################################### [ 67%]
   5:sun-javadb-docs        ########################################### [ 83%]
   6:sun-javadb-javadoc     ########################################### [100%]

Java(TM) SE Development Kit 6 successfully installed.

Product Registration is FREE and includes many benefits:
* Notification of new versions, patches, and updates
* Special offers on Sun products, services and training
* Access to early releases and documentation

Product and system data will be collected. If your configuration
supports a browser, the Sun Product Registration form for
the JDK will be presented. If you do not register, none of
this information will be saved. You may also register your
JDK later by opening the register.html file (located in
the JDK installation directory) in a browser.

For more information on what data Registration collects and
how it is managed and used, see:
http://java.sun.com/javase/registration/JDKRegistrationPrivacy.html

Press Enter to continue.....
Done.

[root@RSVLBI1 stage]# ls /usr/java/

default  jdk1.6.0_21  latest

Installazione rapida ed indolore come utente root.

Step 2 - Occorre installare il client Oracle, nel nostro caso conviene installare un client a 32 bit e non a 64 bit. Ma prima però occorre verificare che il SO sia correttamente installato e quindi fare un check dei pacchetti presenti sulla macchina. Molto probabilmente poichè il SO è a 64 bit occorrerà installare qualche pacchetto a 32 bit, di seguito un piccolo suggerimento:


Una volta aggiunti i pacchetti eseguire il runInstaller e sicuramente dovrete modificare alcuni parametri di SO e quindi vi verrà richiesto di eseguire il seguente script:

[root@SVLBI1 CVU_11.2.0.1.0_oracle]# ./runfixup.sh
Response file being used is :./fixup.response
Enable file being used is :./fixup.enable
Log file location: ./orarun.log
Setting Kernel Parameters...
kernel.sem = 250 32000 100 128
fs.file-max = 6815744
net.ipv4.ip_local_port_range = 9000 65500
net.core.rmem_default = 262144
net.core.wmem_default = 262144
net.core.rmem_max = 4194304
net.core.wmem_max = 1048576



A questo punto continuate e terminate l'installazione del client eseguendo il consueto script root.sh.

Step 3- Finalmente possiamo installare la OBIEE e quindi procediamo tenendo ben presente che sia se installiamo su una singola macchina che su un cluster, quello che cambia è solo la configurazione dei files xml o ini della OBIEE. Inoltre nell'installazione in cluster occorrerà prevedere l'utilizzo di un filesystem condiviso tra le due macchine. 
Ma prima di procedere occorrerà eseguire nuovamente un check della configurazione della macchina Linux o Windows. In questo caso prendiamo in considerazione anche una Windows poichè si potrebbe pensare di installare il BI Server sulla macchina Linux e poichè i client della OBIEE sono solo su Windows si potrebbe pensare di installare il presentation su Windows. Tuttavia in entrambi i casi occorrerà procedere con una installazione normale sulle differenti macchine. Riepilogando quindi potremmo avere differenti  architetture del tipo 

  • 2 nodi Linux per il BI Server e 2 nodi Windows per il Presentation 
  • 2 nodi Linux per il BI Server e  per il Presentation 
  • 2 nodi Windows per il BI Server e  per il Presentation

Qualunque sia l'architettura comunque occorrerà effettuare un check dei parametri sulle differenti macchine e comunque installare in toto il software della OBIEE sui differenti nodi. Poi la differenza verrà fatta dalla configurazione dei files della OBIEE.

Quindi passo 1 facciamo un check dei parametri:

[oracle@SVLBI1 Oracle_Business_Intelligence]$ ./UnixChk.sh /u01/app/oracle/product/obiee/

SUCCESS!! - This machine is configured for Oracle BI EE 10.1.3.4

A questo punto si può procedere all'installazione e visto che siamo su Linux la facciamo alla vecchia maniera non in modalità grafica ma da console e quindi eseguiamo, posizionandoci sotto la directory setup del software:

[oracle@SVLBI1 Oracle_Business_Intelligence]$ ./setup.sh -console

Da qui in avanti si continua con una serie di  next next next o meglio poichè siamo in modalità console 1 1 1, fino a che non verrà richiesto di inserire le directory in cui installare il software.



Da qui in avanti si procede rispondendo alle domande sul tipo di installazione ed indicando il path della jdk


Ricordatevi che vi verrà richiesta la password per oc4j e questa dovete ricordarvela poichè se non inserite la OBIEE in un application server vi occorrerà oc4j e quindi per effetturne lo shutdown vi occorrerà la password.


Da questo punto in poi potete continuare con next next next o meglio in questo caso 1 1 1 fino a che non avrete terminato l'installazione del software.



Abbiamo finito adesso non rimane che mettere mano ai files di configurazione della OBIEE.

Cosa modificare nei files non ve lo dico, altrimenti che ci sto a fare io qui... però vi dico quali sono i files da modificare:


  1. NQSConfig.INI
  2. NQClusterConfig.INI
  3. instancaconfig.xml
  4. odbc.ini
  5. isapiconfig.xml

Questo nel caso di installazione su cluster Linux con Application Server IIS.

Comunque potete trovare tutte le info qui di seguito:


  1. Oracle- Business Intelligence Infrastructure Installation and Configuration Guide
  2. Su support.oracle.com la seguente nota : OBIEE 10g: How To Start/Stop Components On Unix / Linux (Doc ID 1112635.1)
  3. http://www.askjohnobiee.com/2012/05/how-to-complete-obiee-10g-stack.html
  4. http://gerardnico.com/wiki/dat/obiee/presentation_service_multiple#installation_of_a_second_presentation_service
  5. http://gerardnico.com/wiki/dat/obiee


Dimenticavo solo una cosa, visto che occorrerà creare nel caso di installazione su Windows un connettore ODBC verso la Bi Server su Linux, utilizzate quello a 32bit. Vi ricordo solo che Windows è infido e che per poter effettuare il ripuntamento occorre accedere alla versione a 32 bit e non a 64 bit dello strumento Amministratore origine dati di Microsoft Open Database Connectivity (ODBC)(Odbcad32.exe).
Il posizionamento di tale utility è nella cartella %systemdrive\Windows\SysWoW64 da non considerare quello posto nella directory %systemdrive\Windows\System32 che invece è a 64bit.


A questo punto una volta configurati correttamente i files della OBIEE avrete terminato,

giovedì 25 febbraio 2016

RDBMS ORACLE - Select per analisi OPEN CURSOR

Di seguito una collezione di query che possono essere utilizzate per il monitoraggio degli open cursor aperti su una istanza oracle, in questo caso non è stato preso in considerazione il RAC, quindi queste funzionano per singola istanza su cui ci si collega.

Visto che non ho molto tempo, io vi scrivo la query poi se siete bravi lo capite da soli quello che fa...
le scrivo in modo che possiate inserirle in un Report di SQLDeveloper. La prima sarà la query master e le altre devono essere inserite come report figli. Nel momento in cui sul master selezionate un SID sul Report figlio avrete il corrispondente risultato.
Se poi chi conosce vuole avere il file xml da importare in SQLDeveloper basta che mi contatti.

SQL 1- Total cursors open, by session

select a.value, s.username OWNER , s.sid P_SID, s.serial# SERIAL,
case when a.statistic#= 3 then 'Possibile Problematica Select' else 'OK' end statistic,
case when  b.name  = 'opened cursors current' then 'OPENED CURSOR CURRENT - CONTROLLARE SE HO KO IN STATISTIC' else b.name end name
from v$sesstat a, v$statname b, v$session s
where a.statistic# = b.statistic#  and s.sid=a.sid
and b.name = 'opened cursors current';


SQL 2- Valore attuale di cursori aperti e massimo settato.

select max(a.value) as highest_open_cur, p.value as max_open_cur
  from v$sesstat a, v$statname b, v$parameter p
  where a.statistic# = b.statistic#
  and b.name = 'opened cursors current'
  and p.name= 'open_cursors'
  group by p.value;


SQL 3- Total cursors open by username & machine

select sum(a.value) total_cur, avg(a.value) avg_cur, max(a.value) max_cur,
s.username, s.machine
from v$sesstat a, v$statname b, v$session s
where a.statistic# = b.statistic#  and s.sid=a.sid
and b.name = 'opened cursors current'
group by s.username, s.machine
order by 1 desc;

SQL 4- Session Cache Cursor

select a.value, s.username, s.sid, s.serial#
from v$sesstat a, v$statname b, v$session s
where a.statistic# = b.statistic#  and s.sid=a.sid
and b.name = 'session cursor cache count';

SQL 5- Dettaglio Query

select sql.first_load_time,sql.last_load_time,
c.user_name, c.sid, sql.sql_text, sql.sql_fulltext
from v$open_cursor c, v$sql sql
where c.sql_id=sql.sql_id
and c.sid=:P_SID
order by 2 desc,1;

SQL 6- Dettaglio Session Cached Cursor

select cach.value cache_hits, prs.value all_parses,
   prs.value-cach.value sess_cur_cache_not_used
   from v$sesstat cach, v$sesstat prs, v$statname nm1, v$statname nm2
   where cach.statistic# = nm1.statistic#
   and nm1.name = 'session cursor cache hits'
   and prs.statistic#=nm2.statistic#
   and nm2.name= 'parse count (total)'
   and cach.sid= :P_SID and prs.sid= cach.sid;

SQL 7- Dettaglio session cached cursors, for a given SID, compared to max

select a.value curr_cached, p.value max_cached, s.username, s.sid, s.serial#
from v$sesstat a, v$statname b, v$session s, v$parameter2 p
where a.statistic# = b.statistic#  and s.sid=a.sid and a.sid=:P_SID
and p.name='session_cached_cursors'
and b.name = 'session cursor cache count';

SQL 8- Dettaglio possibili leaking

SELECT SQL_ID, max(SQL_TEXT), count(*)
FROM v$open_cursor
WHERE sid = :SID
GROUP BY SQL_ID
HAVING COUNT(*) > 1
ORDER BY 3 DESC;

SQL 9- Dettaglio SQL_TEXT Cursori Aperti

SELECT a.user_name,
       a.sid,
       a.sql_text
FROM   v$open_cursor a
where a.sid=:P_SID
ORDER BY 1,2;

SQL 10- Dettaglio SQL x SID

SELECT oc.user_name, oc.sid,st.sql_text
FROM   v$sqltext st,
       v$open_cursor oc
WHERE  st.address = oc.address
AND    st.hash_value = oc.hash_value
AND    oc.sid = :P_SID
ORDER BY st.address, st.piece;

SQL 11- Dettaglio Session Management

SELECT
    s.sid                sid
  , s.serial#            serial_id
  , lpad(s.status,9)     session_status
  , lpad(s.username,12)  oracle_username
  , lpad(s.osuser,9)     os_username
  , lpad(p.spid,7)       os_pid
  , s.program            session_program
  , lpad(s.machine,14)   session_machine
  , sstat.value          open_cursors
  , ROUND((sstat.value/u.value)*100) open_pct
FROM
    v$process  p
  , v$session  s
  , v$sesstat  sstat
  , v$statname statname
  , (select name, value
     from v$parameter) u
WHERE
      p.addr (+)          = s.paddr
  AND s.sid               = sstat.sid
  AND s.sid=:P_SID
  AND statname.statistic# = sstat.statistic#
  AND statname.name       = 'opened cursors current'
  AND u.name              = 'open_cursors'
ORDER BY open_cursors DESC;