简单 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
上的页面。
我正在尝试编写我的第一个 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
上的页面。