我正在尝试编写我的第一个PL / pgSQL函数。现在,它应该只返回传递给它的值中的字符数。
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.66
进行测试时出现一个错误:
select cents($66.66);
ERROR: syntax error at or near ".66"
LINE 1: select cents($66.66);
^
如果我使用$66
,我会收到不同的错误:
select cents($66);
ERROR: there is no parameter $66
LINE 1: select cents($66);
^
仅使用整数66
给出了第三个错误:
select cents(66);
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
我在这里做错了什么?
答案 0 :(得分:2)
您确定要使用数据类型money
吗?考虑:
如果您需要类型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);
第一个调用变量效率最高,但它取决于区域设置。我的示例中的 dot 被解释为千位分隔符,并在某些区域设置中被忽略(不是小数点)。
您将money
视为函数体中的参数名称,但它只是数据类型。如果要使用参数名称,则必须将它们声明为已演示。或者参考带有位置参考的参数:$1
,$2
等。
char_length()
需要一种字符数据类型,如果不进行强制转换,则不能将其用于数据类型money
。只需length()
即可。
如果您包含美元符号,则需要单引号用于字符串文字:'$66.66'
- 并且格式必须与您的区域设置匹配才能用于money
。
如果您只提供数字常量66
,由于函数类型解析的规则,Postgres将找不到带money
参数的函数。详细说明:
首先阅读手册中的Constants章节
继续CREATE FUNCTION
上的页面。
答案 1 :(得分:1)
您需要在输入中放置单引号:
SELECT cents('$66.66');
如果您的设置不允许此操作(仍然会抛出错误),您可以尝试投射:
SELECT cents('66.66'::float8::numeric::money);
请务必参考文档,因为它们提供了一个很好的概述: https://www.postgresql.org/docs/current/static/datatype-money.html