【问题标题】:postgresql 9.1 invalid input syntax for type numericpostgresql 9.1 数字类型的无效输入语法
【发布时间】:2015-06-14 22:42:46
【问题描述】:

我正在构建一个有点复杂的函数。使我的标准复杂化。当我执行下面的代码时,使用这个命令: select * from populate_lt_downside_volatility('02-Sept-2014' , '05-Sept-2014' , 5, 'df_1')

我收到这些消息:

NOTICE:  curr_sec_key: S5COND_INDEX
NOTICE:  curr_anchor_date.price_date: 2014-09-02

ERROR:  invalid input syntax for type numeric: "S5COND_INDEX   "
CONTEXT:  PL/pgSQL function "populate_lt_downside_volatility" line 26 at SQL statement

********** Error **********

ERROR: invalid input syntax for type numeric: "S5COND_INDEX   "
SQL state: 22P02
Context: PL/pgSQL function "populate_lt_downside_volatility" line 26 at SQL statement

已经花了几个小时,但无法弄清楚。 请求您的帮助。

KD

函数源码:

-- 函数:populate_lt_downside_volatility(date, date, integer, character)

CREATE OR REPLACE FUNCTION populate_lt_downside_volatility(start_date date, end_date date, look_back integer, df_series_in character)
  RETURNS numeric AS
$BODY$
DECLARE

   ---curr anchor_date     date;
   curr_sec_key         character(15);  
   rtn_ds_vol           numeric(20,12);
   max_pricedate        date;
   lookback_ln_return   numeric(20,12);
   today_date           date  :=  CURRENT_DATE ; 


   aSecKey character(15)[]  :=  array['S5COND_INDEX' ,  'S5CONS_INDEX' , 'S5ENRS_INDEX', 'S5FINL_INDEX', 'S5HLTH_INDEX', 'S5INDU_INDEX', 'S5INFT_INDEX',  'S5MATR_INDEX' ,  'S5TELS_INDEX' , 'S5UTIL_INDEX' ]  ;
   curPriceDates CURSOR  (curr_sec_key  character(15),  sDate date, eDate Date )  IS
            SELECT price_date from security_price where  sec_key = curr_sec_key  and price_date >= sDate and price_date <= eDate  ;   


BEGIN   

FOREACH curr_sec_key in ARRAY  aSecKey  LOOP
   raise notice 'curr_sec_key: %', curr_sec_key ;
   for curr_anchor_date  IN  curPriceDates( curr_sec_key , start_date,  end_date ) LOOP 

     raise notice 'curr_anchor_date.price_date: %', curr_anchor_date.price_date ;

     --  check if for this date to look back is in range.
     select sec_key, src_key, price_date , 
          LAG( ln_return_day_over_day, look_back,  null )  OVER ( PARTITION BY sec_key, src_key  ORDER BY sec_key ,  price_date ) into lookback_ln_return
     from security_price sp
     where sp.sec_key = curr_sec_key

       and  sp.price_date =  curr_anchor_date.price_date ;

     raise notice 'lookback_ln_return: %', lookback_ln_return; 


  End LOOP ;


END LOOP;


END   ;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION populate_lt_downside_volatility(date, date, integer, character)
  OWNER TO postgres;

表定义:

CREATE TABLE security_price
(
  sec_key character(15) NOT NULL,
  price_date date NOT NULL,
  open_price numeric(18,8),
  high_price numeric(18,8),
  low_price numeric(18,8),
  last_price numeric(18,8),
  close_price numeric(18,8),
  src_key character(15),
  prior_open numeric(18,8),
  prior_last numeric(18,8),
  ln_open_close_t1 numeric(22,12),
  ln_high_low numeric(22,12),
  ln_close_open numeric(22,12),
  hl_vol_sum_term numeric(22,12),
  ln_return_day_over_day numeric(22,12),
  CONSTRAINT pk_security_price PRIMARY KEY (sec_key , price_date )
)
WITH (
  OIDS=FALSE
);
ALTER TABLE security_price
  OWNER TO postgres;

【问题讨论】:

    标签: postgresql plpgsql


    【解决方案1】:
    select 
        sec_key, src_key, price_date, 
        LAG( ln_return_day_over_day, look_back,  null )  
            OVER ( PARTITION BY sec_key, src_key  ORDER BY sec_key ,  price_date ) 
    into lookback_ln_return
    ...
    

    变量lookback_ln_returnnumeric 类型,而select 返回一行(即伪类型record 的值)。您不能将 record 分配给 numeric 变量。在这种情况下,Postgres 尝试分配记录的第一个值,sec_key,类型为 character(15)。不幸的是,sec_key 不包含格式正确的 numeric 值,因此无法完成分配。

    【讨论】:

    • 非常感谢这是确切的问题。我学到了一些东西。也许不应该在累的时候编码。最好的问候 KD
    猜你喜欢
    • 2018-09-29
    • 2018-05-22
    • 1970-01-01
    • 2018-10-07
    • 2021-02-08
    • 2020-02-29
    • 1970-01-01
    • 1970-01-01
    • 2021-07-05
    相关资源
    最近更新 更多