简单的 PL/pgSQL 函数的错误
Posted
技术标签:
【中文标题】简单的 PL/pgSQL 函数的错误【英文标题】:Errors with an easy PL/pgSQL Function 【发布时间】:2016-06-02 00:12:26 【问题描述】:我正在尝试编写我的第一个 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.
我在这里做错了什么?
【问题讨论】:
【参考方案1】:您确定要使用数据类型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
上的页面。
【讨论】:
【参考方案2】:您需要在输入周围加上单引号:
SELECT cents('$66.66');
如果您的设置不允许这样做(仍然抛出错误),您可以尝试强制转换:
SELECT cents('66.66'::float8::numeric::money);
请务必参考文档,因为它们提供了很好的概述: https://www.postgresql.org/docs/current/static/datatype-money.html
【讨论】:
您从手册中复制了演员表:::float8::numeric::money
但在这种情况下这是无稽之谈。它旨在转换数字 values 并且对于文字输入没有意义。除此之外,答案错过了问题中的大部分问题,并且忽略了使用输入 '$66.66'
警告可能的警告。不过,您指向手册的链接很有帮助,因此我将删除反对票。以上是关于简单的 PL/pgSQL 函数的错误的主要内容,如果未能解决你的问题,请参考以下文章