我有一个real
列类型的表,其中包含示例值:
123456,12
0,12345678
和存储过程中的代码:
CREATE OR REPLACE FUNCTION test3()
RETURNS integer AS
$BODY$
DECLARE
rec RECORD;
BEGIN
FOR rec IN
SELECT
gme.abs_km as km,
CAST(gme.abs_km as numeric) as cast,
round(gme.abs_km:: numeric(16,2), 2) as round
FROM gps_entry gme
LOOP
RAISE NOTICE 'Km: % , cast: % , round: %', rec.km, rec.cast, rec.round;
INSERT INTO test (km, casting, rounding) VALUES (rec.km, rec.cast, rec.round);
END LOOP;
RETURN 1;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
输出如下:
2014-02-05 12:49:53 CET NOTICE: Km: 0.12345678 , cast: 0.123457 , round: 0.12
2014-02-05 12:49:53 CET NOTICE: Km: 123456.12 , cast: 123456 , round: 123456.00
包含NUMERIC(19,2)
列的DB表:
km casting rounding
0.12 0.12 0.12
123456.00 123456.00 123456.00
为什么cast
和round
函数对值123456.12
不起作用?
1条答案
按热度按时间mzmfm0qo1#
**
real
**是一种有损的、不精确的浮点类型。它只使用4个字节进行存储,并且可能无法精确地存储所提供的数字文字。此外,实现细节取决于您的平台。请参考手册中的“浮点类型”一章。round()
或cast()
都没有问题。要获得(更)精确的结果,请使用numeric
。功能审核
当然,用单个多行
INSERT
语句替换循环会更有效。不要引用语言名称
plpgsql
。它是一个标识符。在 * 强制转换为
numeric(16,2)
之后 * 舍入为2个小数位数没有意义,因为numeric(16,2)
已经强制舍入。可以是/或..