简单 PL/pgSQL 函数的错误

Errors with an easy PL/pgSQL Function

我正在尝试编写我的第一个 PL/pgSQL 函数。现在,它只是应该 return 传递给它的值中的字符数。

CREATE OR REPLACE FUNCTION public.cents(money)
 RETURNS int
 LANGUAGE plpgsql
 LEAKPROOF
AS $function$
DECLARE
    new_price money;
    size int;
BEGIN
    size := char_length(money);
    RETURN size;
END;
$function$;

当我尝试使用 .66 进行测试时,出现一个错误:

select cents(.66);
ERROR:  syntax error at or near ".66"
LINE 1: select cents(.66);
                        ^

如果我使用 </code> 我会得到一个不同的错误:</p> <pre><code>select cents(); ERROR: there is no parameter LINE 1: select cents(); ^

仅使用整数 66 给出了第三个错误:

select cents(66);
       ^

HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

我做错了什么?

您需要在输入的两边加上单引号:

SELECT cents('.66');

如果您的设置不允许这样做(仍然会抛出错误),您可以尝试投射: SELECT cents('66.66'::float8::numeric::money);

请务必参考文档,因为它们提供了很好的概述: https://www.postgresql.org/docs/current/static/datatype-money.html

您确定要使用 money 数据类型吗?考虑:

  • PostgreSQL: Which Datatype should be used for Currency?

如果您需要 money 类型,请务必了解语言环境设置对该类型的作用。 Read the manual.

您不能输入不带单引号的文字(如数字常量)- 除非您强制转换它们,否则效率很低。但这不是唯一的错误。您的函数将像这样工作:

CREATE OR REPLACE FUNCTION public.cents(_my_money_parameter money)
  RETURNS int AS
$func$
BEGIN
   RETURN char_length(_my_money_parameter::text);
END
$func$  LANGUAGE plpgsql LEAKPROOF;

致电:

SELECT public.cents(money '66.66');
SELECT public.cents('66.66'::money);
SELECT public.cents(66.66::money);

第一次调用变体是最有效的,但它取决于语言环境设置。我示例中的 在某些语言环境中被解释为千位分隔符并被忽略(不是小数点)。

备注

  • 您将 money 视为函数体中的参数名称,但它只是数据类型。如果你想使用参数名称,你必须像演示那样声明它们。或者用位置引用引用参数:</code>、<code>

  • char_length() 需要一个字符数据类型,如果不强制转换就不能将它用于数据类型 money。只是 length() 是等价的。

  • 如果包含美元符号,则字符串文字需要单引号:'.66' - 格式必须与您的区域设置相匹配才能用于 money
    如果您只提供数字常量 66,Postgres 将不会根据 函数类型解析 的规则找到带有 money 参数的函数。详情:

首先阅读手册中的 Constants 章。
继续 CREATE FUNCTION 上的页面。