postgresql中的该类型精度支持到1000位,采用变长方式存储,那么如何通过atttypmod来获取到定义的precision和scale呢?
两种方法:
1.观察二进制: numeric(5,4) => 327688 0101 0000 0000 0000 1000 numeric(5,5) => 327689 0101 0000 0000 0000 1001 numeric(2,2) => 393222 0110 0000 0000 0000 0110 numeric(7,2) => 458758 0111 0000 0000 0000 0110 numeric(8,2) => 524294 1000 0000 0000 0000 0110 numeric(9,2) => 589830 1001 0000 0000 0000 0110 第一个字节为 numeric (n,m) 的N, 最后一个字节为 m+4,即precision为第一个字节,scale为最后一个字节-4 2.计算公式: atttypmod=-1表示null precision: ((atttypmod - 4) >> 16) & 65535 scale: (atttypmod - 4) & 65535 SELECT CASE atttypid WHEN 21 /*int2*/ THEN 16 WHEN 23 /*int4*/ THEN 32 WHEN 20 /*int8*/ THEN 64 WHEN 1700 /*numeric*/ THEN CASE WHEN atttypmod = -1 THEN null ELSE ((atttypmod - 4) >> 16) & 65535 -- calculate the precision END WHEN 700 /*float4*/ THEN 24 /*FLT_MANT_DIG*/ WHEN 701 /*float8*/ THEN 53 /*DBL_MANT_DIG*/ ELSE null END AS numeric_precision, CASE WHEN atttypid IN (21, 23, 20) THEN 0 WHEN atttypid IN (1700) THEN CASE WHEN atttypmod = -1 THEN null ELSE (atttypmod - 4) & 65535 -- calculate the scale END ELSE null END AS numeric_scale, * FROM pg_attribute ;