PostgreSQL, funkce round() a 666
To mě zase jednou sloník PgSQL pěkně převezl.. Program automatizace přiřazování plateb k fakturám pracoval bezproblémově, než došlo na fakturu s částkou 666 bez DPH, což je s 19% daní 792,54. Funkce vyvolaná triggerem na insert platbu nespárovala.. Kde je chyba?
Ceny s DPH zaokrouhluji klasickým způsobem, tedy na celá čísla k nejbližší hodnotě (72,5 je 73 apod.) a právě při zaokrouhlení došlo k problému.

Jakou myslíte, že bude mít proměnná not_paid hodnotu, pokud je price=666 a tax=19? 792, ale proč? Pokud rozšíříme zaokrouhlení na dvě desetinná místa, tak dostaneme odpovědi 792,00, takže musí docházet k zaokrouhlení již někde dříve.. Myslel jsem, že při tom dělení stem, ale nakonec se ukázalo, že při tom násobení (samozřejmě, že ne, že to zapříčiňuje dělení), proto stačí doplnit definici numeric(v,s), přičemž v definuje počet číslic v čísle a s přesnost desetinných míst. Doplněno: Nebo, jak psal Andrew v komentářích, nepřetypovávat a jedno z čísel, např. 100 napsat desetinně a výsledek bude s desetinnou čárkou.

Pro mé účely jsem použil výše zmíněnou syntaxi a vše již běhá v pořádku a aspoň vím, že si někdy dokáže Postgre leccos domyslet a převést, bohužel v tomto případě na integer..
Aktualizováno:
Ani si nikdo nevšiml, že nadpis článku proklamoval funkci rand, přitom byl text o round, adresu spotu nechávám starou, je již indexována a nahodilí hledači by se nemuseli k tématu dostat.. ;o)
z kategorie Web design, přidej na Linkuj.cz, publikováno 17.05.2006 17:11
Nápověda sytaxe komentářů
Reakci na předchozí komentář můžete učinit napsáním např. [2] či stisknutím odkazu reakce u dotyčného komentáře.
Základní formátování textu - zvýrazněné písmo je v Texy! definováno následovně *pro kurzívu* a **pro tučný řez**.
Odkazy se převádějí automaticky, ale dá se upravit slovní spojení, které bude na dotyčnou adresu ukazovat - např. "xomův fotoblog":[http://www.xom-tom.com/].
Další možnosti syntaxe
Komentáře formátuje Texy! Podrobná dokumentace syntaxe je ka nalezení na oficiálních stránkách.

RSS blogu
Seznam.cz RSS čtečka
Google.com RSS čtečka
Komentáře k článku (2×)
Předně si dovolím upozornit, že v násobení zcela jistě chyba není. Jsouce oba činitelé celočíselní, bude i výsledek celočíselný. IMHO předvídatelně ;) Co mě překvapuje víc, je, že PgSQL u dělení automaticky nezmění typ výsledku. Třeba v opovrhovaném MySQL to funguje podle očekávání.
Nahodil jsem PgSQL (8.1) a jal se bádat. A zjistil jsem, že aby to fungovalo, jak má, je potřeba, aby alespoň jedno číslo ve vzorci bylo desetinné. Tzn. řešení je např toto: round(SUM(price*(tax+100.0)/100)) INTO not_paid, což je IMHO mnohem přehlednější a elegantnější než to přetypování.
|1| - reakce na Andrew: Nojo, opět mé unáhlené konce.. Prvně jsem zkoušel přetypovat celý vzorec, ale to nepomáhalo, tudíž jsem to prdnul na první pozici, kde to bylo žádoucí.. ;o)
Verze s desetinnou stovkou vypadá dobře a hlavně nemůže dojít k přetečení čísla definovaného přetypováním, díky za analýzu.. Akorát nechápu, proč PgSQL natvrdo přetypovává na Integer, když na každou jinou prkotinu v chybných datových typech upozorňuje a kód neprovede..