Visualizzazione dei risultati da 1 a 10 su 10
  1. #1
    Utente di HTML.it L'avatar di atenea
    Registrato dal
    May 2009
    Messaggi
    82

    Mysql arrotonda totale di valori decimal

    Ciao a tutti,
    ho un problemino. Ho creato un trigger che mi calcola il totale di una fattura in base al prezzo degli articoli inserita in questa. Il problema è che per visualizzare i dati calcolo l'imponibile e l'importo dell'iva a runtime ma il totale del documento lo estraggo dal database però quest'ultimo viene arrotondato e ovviamente non è ciò che voglio anche perchè non coincido. Tutti i dati usati sono di tipo decimal(10,2).

    Sapete darmi qualche dritta??
    ^_^

  2. #2
    viene arrotondato ma non dici come, cioe' quale differenza riscontri. Poi che vuol dire che calcoli a runtime ma il totale lo estrai dal database? Forse che sommi ogni operazione runtime al totale presente nel database?

    Se runtime (come e cosa?) utilizzi 2 cifre decimali dovresti avere sempre lo stesso tipo di arrotondamento. Prova a fare gli stessi calcoli con 3 cifre decimali da portare poi a due solo al momento della stampa (decimal(10,3) ) dovresti ottenere una precisione maggiore.

    Il silenzio è spesso la cosa migliore. Pensa ... è gratis.

  3. #3
    Utente di HTML.it L'avatar di atenea
    Registrato dal
    May 2009
    Messaggi
    82
    viene fatto un arrotondamento per eccesso.

    A runtime cioè faccio il calcolo con uno script php però non mi coincide con il totale calcolato tramite il trigger.

    Questa sono le tabelle coinvolte:
    codice:
    CREATE TABLE IF NOT EXISTS `documento_vendita`(
              `tipo_tupla` enum('0','1','2','3') NOT NULL,
              `data_creazione` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
              `id` int(11) NOT NULL AUTO_INCREMENT,
              `n` int(11) NOT NULL,
              `anno` int(4) NOT NULL,
              `data` date NOT NULL,
              `totale` decimal(10,2) NOT NULL,
              `cliente` int(11) NOT NULL,
              `differita` tinyint(1) NOT NULL DEFAULT '0',
              `nota` tinyint(1) NOT NULL DEFAULT '0',
              `rif_fattura` INT(11),
              `dipendente` varchar(16) NOT NULL,
              FOREIGN KEY ( `rif_fattura`) REFERENCES documento_vendita(`id`) ,
              PRIMARY KEY (`id`),
              KEY `documento_vendita_ibfk_1` (`cliente`),
              KEY `documento_vendita_ibfk_2` (`dipendente`)
            ) ENGINE=InnoDB  DEFAULT CHARSET=utf8;
    
    CREATE TABLE IF NOT EXISTS `articolo_appartiene_a_documento_vendita` (
      `codice` int(11) NOT NULL,
      `id` int(11) NOT NULL,
      `sconto` int(11) DEFAULT '0',
      `prezzo_vendita` decimal(10,2) NOT NULL,
      `quantita` decimal(10,2) NOT NULL DEFAULT '1',
      `iva` decimal(10,2) NOT NULL,
      `in_ddt` tinyint(1) NOT NULL DEFAULT '0',
      FOREIGN KEY (codice) references articolo(codice),
      FOREIGN KEY (id) references documento_vendita(id),
      PRIMARY KEY (`codice`,`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    e questo è il trigger

    codice:
    CREATE TRIGGER`totale_documento_vendita_insert` BEFORE INSERT ON `articolo_appartiene_a_documento_vendita`
        FOR EACH ROW BEGIN
        
        DECLARE tot_imp_articolo decimal;
        DECLARE iva_articolo int;
        DECLARE tot_iva_articolo decimal;
        DECLARE sconto decimal;
        DECLARE tipo_doc char;
        DECLARE giacenza_attuale decimal;
        
        SELECT IVA from articolo where codice = new.codice INTO iva_articolo;
        SET sconto = new.prezzo_vendita*new.sconto/100;
        SET tot_imp_articolo = new.prezzo_vendita - sconto;
        SET tot_iva_articolo = tot_imp_articolo * iva_articolo / 100;
        update documento_vendita
        SET totale = totale + ((tot_imp_articolo + tot_iva_articolo))*new.quantita
        where id = new.id;
         SELECT tipo_tupla FROM documento_vendita WHERE id = new.id INTO tipo_doc;
         SELECT giacenza FROM articolo WHERE codice = new.codice INTO giacenza_attuale;
         IF tipo_doc = '2' THEN
          UPDATE articolo SET giacenza = giacenza_attuale - new.quantita WHERE codice = new.codice;
         ELSE 
          UPDATE articolo SET giacenza = 0 WHERE codice = new.codice;
         END IF;
        END;
    mi sono accorta dell'errore perchè ad un certo punto avevo: 99 € di articoli (3 articoli con prezzo unitario 33) quindi 19,80 € di iva ma il totale nel database era 120 anzichè 118,80
    ^_^

  4. #4
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    1,469
    la versione breve è: non funziona

    I calcoli vanno euro-arrotondati, cosa che non riesci minimamente a fare in quel modo, anzi ti dirò non è per nulla banale farlo in mysql (anzi... non è banale in qualsiasi linguaggio di programmazione "vero", ci sono sottigliezze che spesso sfuggono)

    vado a memoria, se proprio vuoi provare ci vuole qualcosa del genere (e non è detto che funzioni, a un certo punto mi son rotto le @@ e passato all'applicazione).

    Anzi in realtà direi che NON funziona
    codice:
    truncate(sum(totaleimponibile+spesetotaleimponibile) * (perivadiversa/100) +sign(sum(totaleimponibile+spesetotaleimponibile) * (perivadiversa/100)    )*0.005,2) as totale

  5. #5
    Utente di HTML.it L'avatar di atenea
    Registrato dal
    May 2009
    Messaggi
    82
    davvero???

    io pensavo bastasse usare il tipo decimal... comunque grazie delle informazioni...
    ^_^

  6. #6
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    1,469
    Originariamente inviato da atenea
    davvero???

    io pensavo bastasse usare il tipo decimal... comunque grazie delle informazioni...
    direi che la rottura dell'euro-arrotondamento aumenta di 10 volte almeno la complessità delle query
    (ad esempio non pensare neppure lontanamente di poter fare una SUM() su una colonna, SUM() sull'iva e poi sommare i due totali )

    Da quanto ne so non esiste la funzione EUROARROTONDA in mysql, o ti fai una stored o lo fai lato-applicazione.

    Magari qualche guru-stored potrebbe intervenire...

  7. #7
    Utente di HTML.it L'avatar di atenea
    Registrato dal
    May 2009
    Messaggi
    82
    ma scusa l'euroarrotondamento non è un semplice arrotondamento?? per eccesso se >= 5 per difetto altrimenti?? Non capisco perchè delle semplici somme non funzionino...
    ^_^

  8. #8
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    1,469
    Originariamente inviato da atenea
    ma scusa l'euroarrotondamento non è un semplice arrotondamento?? per eccesso se >= 5 per difetto altrimenti?? Non capisco perchè delle semplici somme non funzionino...
    magari fosse un semplice arrotondamento... provare, per credere!

  9. #9
    Utente di HTML.it L'avatar di atenea
    Registrato dal
    May 2009
    Messaggi
    82
    nella dichiarazione dei trigger ho modificato le variabili da tipo decimal a decimal(10,2) sembra funzionare perfettamente...
    ^_^

  10. #10
    Utente di HTML.it
    Registrato dal
    Jan 2011
    Messaggi
    1,469
    Originariamente inviato da atenea
    nella dichiarazione dei trigger ho modificato le variabili da tipo decimal a decimal(10,2) sembra funzionare perfettamente...
    concordo sul "sembra"

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2026 vBulletin Solutions, Inc. All rights reserved.