PostgreSQL错误:整数的输入语法无效:" 1e + 06"

时间:2016-11-09 17:47:44

标签: postgresql function casting integer plr

完整的错误消息是:

ERROR: invalid input syntax for integer: "1e+06"
SQL state: 22P02
Context: In PL/R function sample

我使用的查询是:

WITH a as
(
 SELECT a.tract_id_alias,
     array_agg(a.pgid ORDER BY a.pgid) as pgids,
     array_agg(a.sample_weight_geo ORDER BY a.pgid) as block_weights
 FROM results_20161109.block_microdata_res_joined a
 WHERE a.tract_id_alias in (66772, 66773, 66785, 66802, 66805, 66806, 66813)
 AND a.bldg_count_res > 0 
 GROUP BY a.tract_id_alias

)
SELECT NULL::INTEGER agent_id, 
     a.tract_id_alias,
     b.year,
    unnest(shared.sample(a.pgids, 
                       b.n_agents, 
                       1 * b.year, 
                       True, 
                       a.block_weights)
                       ) as pgid
FROM a
LEFT JOIN results_20161109.initial_agent_count_by_tract_res_11 b
ON a.tract_id_alias = b.tract_id_alias
ORDER BY b.year, a.tract_id_alias, pgid;

我使用的shared.sample函数是:

CREATE OR REPLACE FUNCTION shared.sample(ids bigint[], size integer, seed integer DEFAULT 1, with_replacement boolean DEFAULT false, probabilities numeric[] DEFAULT NULL::numeric[])
  RETURNS integer[] AS
$BODY$
    set.seed(seed)
    if (length(ids) == 1) {
        s = rep(ids,size)
    } else {
        s = sample(ids,size, with_replacement,probabilities)
    }
    return(s)
$BODY$
  LANGUAGE plr VOLATILE
  COST 100;
ALTER FUNCTION shared.sample(bigint[], integer, integer, boolean, numeric[])
  OWNER TO "server-superusers";

我对这些东西很陌生,所以任何帮助都会受到赞赏。

1 个答案:

答案 0 :(得分:4)

不是功能问题。与错误消息一样:字符串'1e+06'无法转换为integer

显然,表n_agents中的列results_20161109.initial_agent_count_by_tract_res_11不是integer列。可能输入textvarchar? (这些信息对你的问题有帮助。)

无论哪种方式,赋值转换都不适用于目标类型integer。但它适用于numeric

不起作用:

SELECT '1e+06'::text::int;  -- error as in question

使用:

SELECT '1e+06'::text::numeric::int;

如果我的假设成立,你可以用它作为垫脚石 使用 b.n_agents 替换查询中的b.n_agents::numeric::int

你的责任是数字保持在整数范围内,否则你会得到下一个例外。

如果没有指出,你需要查看函数重载

功能类型解析

架构搜索路径在许多相关案例中都是相关的,但是您对所有对象进行了架构限定,因此我们可以对其进行排除。

您的查询通常看起来不错。我看了一眼,发现了一些小改进:

SELECT NULL::int AS agent_id  -- never omit the AS keyword for column alias
     , a.tract_id_alias
     , b.year
     , s.pgid
FROM  (
   SELECT tract_id_alias
        , array_agg(pgid)              AS pgids
        , array_agg(sample_weight_geo) AS block_weights
   FROM  (  -- use a subquery, cheaper than CTE
      SELECT tract_id_alias
           , pgid
           , sample_weight_geo
      FROM   results_20161109.block_microdata_res_joined
      WHERE  tract_id_alias IN (66772, 66773, 66785, 66802, 66805, 66806, 66813)
      AND    bldg_count_res > 0
      ORDER  BY pgid  -- sort once in a subquery. cheaper.
      ) sub
   GROUP  BY 1
   ) a
LEFT   JOIN results_20161109.initial_agent_count_by_tract_res_11 b USING (tract_id_alias)
LEFT   JOIN LATERAL
   unnest(shared.sample(a.pgids
                      , b.n_agents
                      , b.year  -- why "1 * b.year"?
                      , true
                      , a.block_weights)) s(pgid) ON true
ORDER  BY b.year, a.tract_id_alias, s.pgid;