mercoledì 24 giugno 2009

JasperServer e iReport: Collegamento ad un database Oracle

Oggi mi è arrivata una nuova richiesta. Creare un report che potesse prendere dati da una fonte Oracle e non Mysql.
Come sempre partendo dalla documentazione web ho subito verificato che la cosa fosse possibile.

Quindi sono entrato nella creazione dei Data Source e ho iniziato a configurare per primo iReport.
La connessione è stata così configurata:
Driver:
oracle.jdbc.driver.OracleDriver
URL:
jdbc:oracle:thin:@Indirizzo_IP_Server:Porta_Server:Nome_DataBase
(usare l'IP del server per evitare problemi sulla network interface e non i nomi WINS es: nomeserver.dominio)

Ovviamente user e password.
E qui iniziano i problemi. Perchè anche se i parametri sono tutti corretti riceviamo un messaggio di errore sulle classi java.
E' necessario scaricare la classe java apposita per la comunicazione.
Il pacchetto è:
ojdbc14.jar
Ne ho trovato una versione scaricabile senza effettuare registrazioni di sorta su www.findjar.com.
Questo pacchetto va messo nelle directory:
X:\Programmi\jasperserver-3.0\ireport\lib (iReport)
X:\Programmi\jasperserver-3.0\apache-tomcat\common\lib
(JasperServer)
Riavviando Jasperserver sarà possibile inizializzare i Data Source necessari.
Buon lavoro.

Wsc

martedì 26 maggio 2009

JasperServer e iReport: Inserimento delle immagini nei report

Per la prima volta oggi mi sono trovato a dover gestire l'inserimento di immagine statiche in un report. Come al solito è stato il solito delirio per riuscire a trovare una risposta.
I manuali sono sempre molto poco ricchi e spiegano spesso male o in maniera incompleta le procedure.

Ad ogni modo siamo arrivati ad una risposta.

Innanzitutto le immagini possono essere caricate come risorsa legata al singolo report oppure inserita nella Cartella Images della Repository di JasperServer.

Ci verranno chiesti un nome per la risorsa, una label e una breve descrizione.

Una volta caricato il file non ci resta che legarlo nel report.
Aggiungiamo quindi un oggetto immagine nel layout delle immagini e per linkarlo all'immagine caricata entriamo nel cammpo Expression e qui usiamo la seguente sintassi:
"repo:nome_risorsa"
Ora il nostro report visualizzarà correttamente l'immagine.
Buon lavoro a tutti. Alla prossima difficoltà.

Wsc

mercoledì 6 maggio 2009

Una passione genera un nuovo progetto

Oggi ho avviato un piccolo progetto sperimentale. Per chi è appassionato di modellismo ferroviario può dare un occhio e un commento qui.

Attendo i vostri commenti in merito.

PS: purtroppo non posso adottare tecnologie database (essendo sulla piattaforma di blogspot) per ora, ma non si sa mai.

giovedì 2 aprile 2009

MySQL: Generare una chiave primaria per una tabella

Oggi ho avuto la necessità di generare una chiave primaria per una tabella. Siccome non ho molto in simpatia l'uso degli autoincrement ho deciso di costruirla sulla base di un campo varchar(30).

Una delle problematiche è che in una fase di insert massivo (il sistema riesce ad inserire alcune migliaia di record in un secondo) la generazione di questa stringa non è stata semplicissima.
Vediamo comunque le strategie usate partendo dal risultato finale.
SET @numero = 1;

SELECT CONCAT('DVBH',DATE_FORMAT(NOW(),'%Y%m%d%H%i%s'),LPAD(FLOOR(1 + RAND() * 999999),7,0),LPAD(@numero := @numero + 1,5,0)) AS RecordId
Leggendo così a primo colpo può quasi spaventare, ma vediamola passo passo.
La Set iniziale servirà più avanti e per ora evito di trattarla.
Innanzi tutto per ottenere una stringa avremo bisogno ci concatenare gli elementi che useremo per andare a formare la stringa.
SELECT CONCAT('DVBH',DATE_FORMAT(NOW(),'%Y%m%d%H%i%s'),LPAD(FLOOR(1 + RAND() * 999999),7,0),LPAD(@numero := @numero + 1,5,0)) AS RecordId
Come primo elemento aggiungiamo un prefisso (in questo caso di 4 lettere) che ci identifica la tabella o qualsiasi altra cosa vi possa venire in mente.
SELECT CONCAT('DVBH',DATE_FORMAT(NOW(),'%Y%m%d%H%i%s'),LPAD(FLOOR(1 + RAND() * 999999),7,0),LPAD(@numero := @numero + 1,5,0)) AS RecordId
Per la seconda parte utilizziamo la data attuale con precisione al secondo in tale maniera ogni volta che creeremo la chiave primaria si già diversa in dipendenza del tempo.
SELECT CONCAT('DVBH',DATE_FORMAT(NOW(),'%Y%m%d%H%i%s'),LPAD(FLOOR(1 + RAND() * 999999),7,0),LPAD(@numero := @numero + 1,5,0)) AS RecordId
A questo punto siccome in un secondo possono esserci anche migliaia di inserimenti che manderebbero in violazione di chiave la nostra operazione aggiungiamo il terzo e quarto elemento. Il terzo sarò un numero randomico generato come già spiegato in un latro post secondo una formula matematica.
SELECT CONCAT('DVBH',DATE_FORMAT(NOW(),'%Y%m%d%H%i%s'),LPAD(FLOOR(1 + RAND() * 999999),7,0),LPAD(@numero := @numero + 1,5,0)) AS RecordId
Ultima parte un numero sequenziale, che io nel caso gli ho passato da una variabile @numero, ma che si può tranquillamente immagazzinare in una tabella e richiamare a piacere, aumentando il suo valore ad ogni passaggio.
SELECT CONCAT('DVBH',DATE_FORMAT(NOW(),'%Y%m%d%H%i%s'),LPAD(FLOOR(1 + RAND() * 999999),7,0),LPAD(@numero := @numero + 1,5,0)) AS RecordId
Il risultato che si ottiene è qualcosa come questo:
DVBH20090402133508062740800002
Ecco fatto!

Wsc

martedì 24 marzo 2009

JasperServer e iReport: Tabelle a nome variabile nei dataset

Oggi ho avuto una nuova problematica da affrontare nell'utilizzo di JasperServer e iReport.

Avevo necessità che l'utente potesse in qualche modo parametrizzare tutto o in parte in nome di una tabella sulla quale far girare il report. Nel caso specifico sul lavor creiamo delle tabelle giornaliere che hanno un nome formato come segue:
DataBase.Piattaforma _090324
Quindi il problema era passare la data al report in modo che l'utente potesse con un singolo report, e senza create procedure particolari al livello di db, interrogare più di una tabella a secondo del giorno di interesse.
La cosa più ovvia era che la parte variabile venisse passata tramite un parametro al report e quindi gioco forza il primo tentativo è stato quello di provare la seguente sintassi, dove il parametro veniva passato come stringa:
SELECT * FROM DataBase.Piattaforma _$P{DataTabella}
Ovviamente l'esperimento ha prodotto un errore, ma devo dire che la soluzione era a portata di mano. Il trucco sta nell'aggiungere un "!" dopo $P:
SELECT * FROM DataBase.Piattaforma _$P!{DataTabella}
Così facendo il tutto funziona perchè il motore effettua la sostituzione del parametro con il suo valore inserito dall'utente prima di inviare la query.

Spero di avervi aiutato anche questa volta.

Wsc

mercoledì 18 marzo 2009

MySQL: Generare numeri casuali in un intervallo

L'altro giorno mi sono imbattuto nella necessità di rielaborare dei dati creando un dataset simile ma rielaborando secondo funzioni statistiche dei campi numerici.

Avendo precedentemente calcolato Media e Varianza di questo set di dati (funzioni AVG() e STD()) quello che si desiderava fare era:
Media + (NumeroRandom * Varianza)
così facendo si sarebbe lavorato sulla media dei valori aggiungendogli una deviazione fornita dal numero randomico (compreso tra -0,8 e 0,8) moltiplicato la varianza.

L'inica funzione MySQL che genera numeri casuali è RAND(), però questa funzione produce numeri in virgola mobile compresi tra 0 e 1.
La sola funzione non riusciva a risolvere la problematica, quindi andava ulteriormente elaborata.
Googlando ho trovato per ottenere un numero intero variabile in un intervallo, mettiamo 1 e 3, si può applicare la seguente formula dove 1=i e 3=j:
FLOOR(i + RAND() * (j – i))
La formula di venta:
FLOOR(1 + RAND() * 2)
A questo punto non è stato necessario altro che effettuare una sostituzione per ottenere la formula finale dell'intervallo a cui ero interessato:
CEILING(Media + (-0.8 + (RAND() * 1.6)) * Varianza)
Ho usato il CEILING() in quanto a mi serviva arrotondare all'intero superiore contrariamente al FLOOR().
Spero che questo piccolo promemoria possa essere utile ad altri. Continuate a seguirmi.

Wsc

lunedì 16 marzo 2009

JasperServer e iReport: linkare i report tra di loro

Utilizzando Google Analytics ho notato che all'interno del mio blog gli articoli più interessanti per il pubblico siano quelli incentratti sull'argomento Jasper Server e iReport.

Altra funzione che ho usato ultimamente è la possibilità di poter linkare tra loro diversi report.
iReport ci permette di inserire dei link legati ai vari oggetti che compongono il nostro template. Si possono precificare delle URL e quindi possiamo linkare tra loro report già realizzati.

Si procede molto velocemente creando un capo di testo. Dalle "Proprietà" dell'oggetto si sceglie la linguetta "Link ipertestuale" e quindi è possibile inserire il link al report.
Di solito i link ai report sono di questo tipo:
http://NOME_SERVER/jasperserver/flow.html?_flowId=viewReportFlow&reportUnit=/reports/NOME_REPORT&standAlone=true&ParentFolderUri=/reports
Quindi è sufficiente dopo aver deciso la tipologia del link (nel nostro caso Blank e Reference) indicare nella linguetta "Riferimento" l'indirizzo.
Da notare che è anche possibile passare dei parametri se il report destinazione lo prevede passati del report chiamante.
Nel qualcaso un'esempio di link potrebbe essere questo:
"http://NOME_SERVER/jasperserver/flow.html?_flowId=viewReportFlow&reportUnit=/reports/NOME_SOTTOCARTELLA_REPORT/NOME_REPORT&standAlone=true&ParentFolderUri=/reports/NOME_SOTTOCARTELLA_REPORT&SelectFromDateTime="+$V{SelectFrom_STRING}+"&SelectToDateTime="+$V{SelectTo_STRING}
La parte in neretto ci consente di passare ai parametri del report chiamato SelectFromDateTime e SelectToDateTime i valori delle Variabili $V{SelectFrom_STRING} e $V{SelectTo_STRING}.
In questo caso stiamo passando delle date con ora per cui dovendo passare un text alla stringa dell'indirizzo abbiamo usato la seguente espressione per formattarle:
new java.text.SimpleDateFormat("yyyyMMddHHmmss").format($P{SelectFromDateTime})
Come potete vedere a loro volta le variabili erano state costruite da uno dei parametri immessi nel report chiamante.

Spero che anche questa spiegazione sia utile. Se qualcosa non fosse chiaro usate i commenti per porre delle domande.
Alla prossima.

Wsc