Newsgroup: it.comp.www.php
Titolo: [PHP,PostgreSQL] Gestione punto separatore delle migliaia

Ho cercato a lungo su internet ma non ho trovato praticamente nulla.
Ho cominciato lo studio di PHP e PostgreSQL per la realizzazione di un
(piccolo) programma per la gestione di bolle e fatture.
Quando  l'utente   inserisce  un  importo,  inserisce   anche  il  punto
separatore delle migliaia, per comodita` di lettura.
Esempio: 
IMPORTO:  1.200.000
Questo  dato viene  memorizzato  in  una tabella  di  PostgreSQL il  cui
attributo "importo" e` di tipo "text". In tal modo e` possibile inserire
senza  alcuna fatica  il valore  sopra riportato.  Inoltre, facendo  una
query al DB, verra` prelevato  il valore '1.200.000' che verra` mostrato
a video.
In questo caso, pero`, PostgreSQL non e` in grado di compiere operazioni
matematiche su "importi", dal momento che e` di tipo "text".
Utilizzando PHP pensavo di utilizzare la seguente funzione:
------------------------------------------------------------------------
// funzione per eliminare il punto decimale
// 1.200.000 ---> 1200000
function converti ($s){
$pezzi = explode (".", $s);
$dim=sizeof($pezzi);
for ($num=0;$num <= $dim;$num++){
$n1=$n1 . $pezzi[$num];
}
return $n1;
}
------------------------------------------------------------------------
I calcoli  sugli importi  (quelli senza  punto separatore)  verranno poi
svolti da PHP. E' corretto come modo di procedere?
O  forse e`  meglio definire  l'attributo "importi"  come INT,  far fare
i  conti  a  PostgreSQL  e  poi   usare  PHP  per  aggiungere  il  punto
decimale tutte le  volte che occorre? Purtroppo non  riesco a realizzare
quest'ultima funzione con PHP. In pratica:
<?
$importo='1200000';
$importo_sep = aggiungi_sep($importo);
// $importo_sep ora contiene il valore "1.200.000"
?>
Possibile che PostgreSQL non sia in grado di gestire la localizzazione ?
Grazie infinite a chi sapra` darmi una mano.
Ciao
Ale
-- 
Home Page: 
http://web.tiscalinet.it/airaghi
Per ottenere il mio indirizzo e-mail sostituire a NOSPAM il mio cognome

Possibile che PostgreSQL non sia in grado di gestire la localizzazione ?
/me indossa il grembiule verde
Potresti fare qualcosa del genere (su Linux)... crei un file tipo, che
so:
#include <ctype.h>
#include "fmgr.h"
#include "utils/builtins.h"
#define _textin(str) DirectFunctionCall1(textin, CStringGetDatum(str))
#define _textout(str) DatumGetPointer(DirectFunctionCall1(textout, \
 		PointerGetDatum(str)))
PG_FUNCTION_INFO_V1(numerics);
Datum numerics(PG_FUNCTION_ARGS)
{
        float8  horner = 0;
        size_t  i, n;
        char    *arg;
        text    *t;
        if (PG_ARGISNULL(0))
                PG_RETURN_FLOAT8(horner);
        t       = PG_GETARG_TEXT_P(0);
        arg     = VARDATA(t);
        n       = VARSIZE(t) - VARHDRSZ;#include <ctype.h>
        for (i=0; (i < n) && (arg[i]!=0); i++)
        {
                if (arg[i] >= '0' && arg[i] <= '9')
                {
                        horner = horner * 10;
                        horner = horner + (arg[i] - '0');
                }
        }
        PG_RETURN_FLOAT8(horner);
}
Lo compili con
gcc -I$PATH_DI_POSTGRES/src/backend -I$PATH_DI_POSTGRES/src/include
        -Wall -fPIC -shared -o nomefile.so nomefile.c
...e questo ti crea, diciamo, /home/airaghi/nomefile.so.
Chi ni garba di rischia', pòle aggiungere "-O3 -mpentiumpro", se la
CPU glielo consente :-)
Ora, dai psql come utente postgres, e gli dici:
create function numerics (bpchar) returns float8
                as '/home/airaghi/nomefile.so'
                language 'c';
direct=> SELECT numerics('Lire italiane 1.200.000 circa') AS value;
 value
----------
  1200000
(1 row)
direct=> SELECT numerics('Lit. 1.200.000') + 1;
 ?column?
----------
  1200001
(1 row)
...come vedi, PostgreSQL interpreta correttamente il valore, tant'e'
che ci somma correttamente 1 :-)
/me si toglie il grembiule ed esce dalla sala operatoria buttando da
 una parte la motosega sporca di sangue B-D
Leonardo
-- 
".signature": bad command or file name

 IMPORTO:  1.200.000
<?php
class Lire  {
 function aggiungi($lire) {
  $res = "";
  while(($i = strlen($lire) - 3) > 0) {
          $res = ".".substr($lire,$i,3).$res;
          $lire = substr($lire,0,$i);
  }
 return $lire .= $res;
 }
 function togli($lire) {
    return ereg_replace("\.\0","",$lire);
 }
}
$lire = new Lire;
echo "<BR>".$lire->aggiungi(23501005000);
echo "<BR>".$lire->togli("23.501.005.000");
?>
PS: non conosco PostgreSQL. In MySQL c'e' la
funzione REPLACE

 funzione REPLACE
Grazie mille per avere risposto. Mi e` stata molto utile la funzione per
rimuovere il punto separatore delle migliaia.


  una parte la motosega sporca di sangue B-D
Scusa se rispondo solo ora ma ero impegnato a terminare il programma :-(
Non oso dubitare della bonta` della soluzione da te proposta ma e` ad un
livello un "tantino" al di fuori delle mie capacita` di comprensione :)
Inoltre, avevo l'assoluta necessita` di rendere il programma a prova del
piu` improbabile errore di inserimento dei dati. Ce l'ho fatta, grazie a
un bel po' di funzioni scritte in PHP. Ora e` possibile introdurre anche
valori con la virgola ed il punto separatore delle migliaia.
Per esempio, i dati:
1000
1000,5
1.000
1.000,5
vengono tutti interpretati come "mille virgola 5". Non so quanto decente
sia la soluzione adottata, ma devo dire che funziona :-) Il programma si
trova sulla mia homepage, casomai volessi provarlo ... 
Di nuovo grazie per le preziose info che mi hai dato, con la speranza di
riuscire a comprenderle un giorno :)
Ciao
Ale
p.s. non faccio il programmatore di professione, abbiate pieta` :-)
