I have table with real column type with example values:
123456,12
0,12345678
And code in stored procedure:
CREATE
real is a lossy, inexact floating-point type. It only uses 4 bytes for storage and cannot store the presented numeric literals precisely to begin with. In addition, implementation details depend on your platform. Consider the chapter "Floating-Point Types" in the manual.
There is nothing wrong with either round() or cast(). For exact results, you'd have to use numeric to begin with.
CREATE OR REPLACE FUNCTION test3()
RETURNS void AS
$func$
DECLARE
r record;
BEGIN
FOR r IN
SELECT abs_km AS km
,cast(abs_km AS numeric) AS km_cast
,round(abs_km::numeric, 2) AS km_round
FROM gps_entry
LOOP
RAISE NOTICE 'km: % , km_cast: % , km_round: %'
, r.km, r.km_cast, r.km_round;
INSERT INTO test (km, casting, rounding)
VALUES (r.km, r.km_cast, r.km_round);
END LOOP;
END
$func$ LANGUAGE plpgsql;
plpgsql. It's an identifier.Makes no sense to round to 2 fractional digits after casting to numeric(16,2), which forcibly rounds already. Either - or ..
round(abs_km:: numeric(16,2), 2) as round
round(abs_km::numeric, 2) as round
abs_km::numeric(16,2) as roundFinally, you need to upgrade to a current version. Postgres 8.3 has reached EOL and is unsupported.