【问题标题】:Invalid input syntax for type numeric: "(0.0000000000000000,8)"数字类型的输入语法无效:“(0.0000000000000000,8)”
【发布时间】:2018-10-07 13:08:40
【问题描述】:

我在 PostgreSQL 中创建了这个 PL/pgSQL 函数:

CREATE OR REPLACE FUNCTION public.diploma_cal_grade(
    amk integer)
    RETURNS numeric
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE 
AS $BODY$
DECLARE
    a2 integer;
    mo1_upox_sum double precision; 
    mo1_epil_sum double precision;
    weig1 integer;
    weig2 integer;
    upox_sum numeric;
    epil_sum numeric;
    dipl_g integer ;
    cour_g numeric ;
    fin_g numeric ;
BEGIN

-----SUM(final_grade*weight)= double precition variable-------
mo1_upox_sum=(Select SUM(final_grade*weight)
        FROM ("Course" c join "Register" r USING(course_code)) natural join "Diploma" d
        where d.amka=amk and r.register_status='pass' and c.obligatory='true');

weig1=(Select SUM(weight)
        FROM ("Course" c join "Register" r USING(course_code)) natural join "Diploma" d
        where d.amka=amk and r.register_status='pass' and c.obligatory='true');

--------double precition/integer        
upox_sum=(mo1_upox_sum/weig1):: numeric;


a2=(select distinct g.min_courses from "Graduation_rules" g); --for help

-----give me a double precition variable
mo1_epil_sum=(select_courses_maxgrad(amk));
-----give me an integer----     
weig2=(select SUM(mk.we)
        from(select weight as we
        from "Course" c join "Register" r USING(course_code)
        where r.amka=amk and c.obligatory='false' and  r.register_status='pass' 
        order by r.final_grade DESC
        Limit a2)as mk);


--------double precition/integer        
epil_sum=(mo1_epil_sum/weig2):: numeric;

---give me an integer-----
dipl_g=(select thesis_grade from "Diploma" where amka=2);

cour_g=(((upox_sum+epil_sum)/2)*0,8);
fin_g=((dipl_g*0,2)+cour_g);
RETURN fin_g:: numeric(4,2);

END;
$BODY$;

试图执行它,我得到这个错误:

ERROR:  invalid input syntax for type numeric: "(0.0000000000000000,8)"
CONTEXT:  PL/pgSQL function diploma_cal_grade(integer) line 45 at assignment
SQL state: 22P02

我不知道为什么;我已经多次将我的值转换为numeric,并将我的变量更改为numeric 类型,但无济于事。

我该如何解决这个问题?

【问题讨论】:

    标签: postgresql variable-assignment plpgsql


    【解决方案1】:

    问题出在这一行:

    cour_g=(((upox_sum+epil_sum)/2)*0,8);
    

    小数点分隔符必须是句点,因此您必须使用0.8 而不是0,8

    【讨论】:

      【解决方案2】:

      什么@Laurenz said

      但为什么会出现“奇怪”的错误消息?

      您的语法错误0,8 而不是cour_g=(((upox_sum+epil_sum)/2)*0,8); 中的0.8)被添加的无偿括号 混淆,被解释为ROW constructors -前导关键字ROW 是可选噪声。

      您在错误消息中看到的内容:

      ERROR:  invalid input syntax for type numeric: "(0.0000000000000000,8)"
      

      ... 是一个行表达式,由以下字段组成:0.00000000000000008
      没有误导性的括号,赋值:

      cour_g=((upox_sum+epil_sum)/2)*0,8;  -- still incorrect: 0,8
      

      ... 会产生不同的(更具启发性的)错误消息:

      ERROR:  query "SELECT ((upox_sum+epil_sum)/2)*0,8" returned 2 columns
      

      因为逗号 (,) 被解释为列分隔符。

      此消息还表明 PL/pgSQL 在内部使用(基本和快速)SELECT 语句评估每个裸表达式。该语言基本上是核心 SQL 引擎的包装器。这就解释了为什么分配比其他 PL 的预期要贵一些。

      您的原始语句相当于更冗长的ROW 语法:

      cour_g=ROW(((upox_sum + epil_sum)/2)*0,8);  -- still incorrect: 0,8
      

      ... 在功能上 等同于:

      cour_g=(SELECT ROW(((upox_sum + epil_sum)/2)*0,8));  -- still incorrect: 0,8
      

      两者都会导致您观察到的相同错误消息。

      或者:

      cour_g=(SELECT ((upox_sum + epil_sum)/2)*0,8);  -- still incorrect: 0,8
      

      带有不同的(已经更具启发性的)错误消息:

      ERROR:  subquery must return only one column
      

      嵌套的显式SELECT 周围的括号是必需的。如果你删除了不需要的SELECT,则删除它的括号,或者它们被解释为ROW构造函数(有或没有干扰词ROW)。

      所以使用:

      cour_g := (upox_sum + epil_sum) / 2 * 0.8;
      

      ((upox_sum+epil_sum)/2) 周围的括号也是多余的,因为 */ 共享相同的 operator precedence 并且无论如何都是从左到右计算的。但在这种情况下,添加的括号是无害的噪音(这可能会或可能不会有助于可读性)。

      或简化为:

      cour_g := (upox_sum + epil_sum) * 0.4;
      

      也就是说,由于 PL/pgSQL 中的赋值相对昂贵,因此请尝试采用赋值较少的编程风格。
      并非所有无端括号都是无害的。

      【讨论】:

        猜你喜欢
        • 2018-05-22
        • 1970-01-01
        • 1970-01-01
        • 2018-09-29
        • 1970-01-01
        • 2021-11-04
        • 2021-05-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多