创建一个接受字符串和 returns 多行的函数
Create a function that accepts a string and returns multiple rows
我需要创建一个函数,根据用户的输入转换单个列的值。为此,我需要一些语法方面的帮助。
这是我当前为获取行而执行的查询:
SELECT payment_id, rental_id, amount FROM payment
关于我正在尝试做的事情的一些伪代码:
function getReport(String currencyType){
if(currencyType == 'EUR'){
Multiply the values in the amounts column by 1.16 and append Euros to it
Return all the rows in the table
}else if(currencyType == 'RMB'){
Multiple the values in the amounts column by 6.44 and append RMB to it
Return all the rows in the table
}else{
Do nothing because the default column values are in USD
Return all the rows in the table
}
}
我一直在尝试创建一个,但我在语法上遇到困难。
不工作:
CREATE OR REPLACE FUNCTION get_data(currency_type text) RETURNS TABLE payment_info AS $$
CASE currency_type
WHEN 'EUR' THEN
SELECT payment_id, rental_id, amount * 1.16 FROM payment;
WHEN 'RMB' THEN
SELECT payment_id, rental_id, amount * 6.44 FROM payment;
WHEN 'USD' THEN
SELECT payment_id, rental_id, amount FROM payment;
$$ LANGUAGE SQL;
有人可以帮我了解创建此函数的语法吗?
像这样
CREATE OR REPLACE FUNCTION get_data(currency_type text)
RETURNS TABLE ( payment_id int, rental_id int, amount numeric(5,2) )
language plpgsql
as $$
begin
return query
SELECT b.payment_id, b.rental_id,
case
when currency_type = 'EUR' then b.amount * 1.16
when currency_type = 'RMB' then b.amount * 6.44
when currency_type = 'USD' then b.amount
end as amount
FROM payment b;
end;$$
如果您使用
,它会以 table 的形式 return
select * from get_data('EUR');
这里有一个演示
Postgres 14 或更高版本
在 Postgres 14 或更高版本中,我建议使用新的标准 SQL 语法:
CREATE OR REPLACE FUNCTION get_data(_currency_type text DEFAULT 'USD')
RETURNS TABLE (payment_id int, rental_id int, amount numeric(5,2))
STABLE PARALLEL SAFE
BEGIN ATOMIC
SELECT p.payment_id, p.rental_id
, CASE _currency_type
WHEN 'USD' THEN p.amount
WHEN 'EUR' THEN p.amount * 1.16
WHEN 'RMB' THEN p.amount * 6.44
FROM payment p;
END;
参见:
以下大部分内容仍然适用...
Postgres 13(或任何版本)
CREATE OR REPLACE FUNCTION get_data(_currency_type text DEFAULT 'USD')
RETURNS TABLE (payment_id int, rental_id int, amount numeric(5,2))
LANGUAGE sql STABLE PARALLEL SAFE AS
$func$
SELECT p.payment_id, p.rental_id
, CASE _currency_type
WHEN 'USD' THEN p.amount
WHEN 'EUR' THEN p.amount * 1.16
WHEN 'RMB' THEN p.amount * 6.44
-- ELSE 1/0 END -- ??? this purposely raises an exception
FROM payment p;
$func$;
坚持使用 LANGUAGE sql
(就像您最初的尝试一样)。简单函数不需要 LANGUAGE plpgsql
- 除非您想为无效输入添加自定义错误消息或错误处理..
参见:
- Difference between language sql and language plpgsql in PostgreSQL functions
使用更简单的 switched CASE
(就像您最初的尝试一样)。
- Display column name with max value between several columns
- Simplify nested case when statement
提供明确的 ELSE
分支。 (如果未拼写 ELSE
,SQL CASE
默认为 NULL
。)
如果 payment_info
,在您最初的尝试中,是与您想要的 return 类型匹配的现有行类型,请使用简单的 RETURNS SETOF payment_info
而不是 RETURNS TABLE(...)
.
table-限定列 可能具有不明确的名称 是一种很好的风格,就像演示的那样。 (在任何情况下,从来都不是一个坏主意。)
但它是 LANGUAGE plpgsql
函数中的 要求 ,其中 RETURNS TABLE ...)
隐式声明与 table 列同名的 OUT
参数。这会引发异常,例如:
ERROR: column reference "payment_id" is ambiguous
参见:
- How to return result of a SELECT inside a function in PostgreSQL?
另外:numeric(5,2)
? 这引发了 amount > 999.99
的异常。看起来像一把上了膛的步兵枪。只需使用 numeric
或类似 numeric(20,2)
的舍入效果即可。
关于STABLE
:
关于PARALLEL SAFE
:
最后,已经清理完毕,分解结果行,调用SELECT * FROM
:
SELECT * FROM get_data('USD');
参见:
- Simple PostgreSQL function to return rows
- PostgreSQL: ERROR: 42601: a column definition list is required for functions returning "record"
我为输入参数添加了一个默认值:DEFAULT 'USD'
。这很方便,但完全是可选的。它记录了最常见的预期,并允许在没有显式参数的情况下进行简短调用:
SELECT * FROM get_data();
我需要创建一个函数,根据用户的输入转换单个列的值。为此,我需要一些语法方面的帮助。
这是我当前为获取行而执行的查询:
SELECT payment_id, rental_id, amount FROM payment
关于我正在尝试做的事情的一些伪代码:
function getReport(String currencyType){
if(currencyType == 'EUR'){
Multiply the values in the amounts column by 1.16 and append Euros to it
Return all the rows in the table
}else if(currencyType == 'RMB'){
Multiple the values in the amounts column by 6.44 and append RMB to it
Return all the rows in the table
}else{
Do nothing because the default column values are in USD
Return all the rows in the table
}
}
我一直在尝试创建一个,但我在语法上遇到困难。
不工作:
CREATE OR REPLACE FUNCTION get_data(currency_type text) RETURNS TABLE payment_info AS $$
CASE currency_type
WHEN 'EUR' THEN
SELECT payment_id, rental_id, amount * 1.16 FROM payment;
WHEN 'RMB' THEN
SELECT payment_id, rental_id, amount * 6.44 FROM payment;
WHEN 'USD' THEN
SELECT payment_id, rental_id, amount FROM payment;
$$ LANGUAGE SQL;
有人可以帮我了解创建此函数的语法吗?
像这样
CREATE OR REPLACE FUNCTION get_data(currency_type text)
RETURNS TABLE ( payment_id int, rental_id int, amount numeric(5,2) )
language plpgsql
as $$
begin
return query
SELECT b.payment_id, b.rental_id,
case
when currency_type = 'EUR' then b.amount * 1.16
when currency_type = 'RMB' then b.amount * 6.44
when currency_type = 'USD' then b.amount
end as amount
FROM payment b;
end;$$
如果您使用
,它会以 table 的形式 returnselect * from get_data('EUR');
这里有一个演示
Postgres 14 或更高版本
在 Postgres 14 或更高版本中,我建议使用新的标准 SQL 语法:
CREATE OR REPLACE FUNCTION get_data(_currency_type text DEFAULT 'USD')
RETURNS TABLE (payment_id int, rental_id int, amount numeric(5,2))
STABLE PARALLEL SAFE
BEGIN ATOMIC
SELECT p.payment_id, p.rental_id
, CASE _currency_type
WHEN 'USD' THEN p.amount
WHEN 'EUR' THEN p.amount * 1.16
WHEN 'RMB' THEN p.amount * 6.44
FROM payment p;
END;
参见:
以下大部分内容仍然适用...
Postgres 13(或任何版本)
CREATE OR REPLACE FUNCTION get_data(_currency_type text DEFAULT 'USD')
RETURNS TABLE (payment_id int, rental_id int, amount numeric(5,2))
LANGUAGE sql STABLE PARALLEL SAFE AS
$func$
SELECT p.payment_id, p.rental_id
, CASE _currency_type
WHEN 'USD' THEN p.amount
WHEN 'EUR' THEN p.amount * 1.16
WHEN 'RMB' THEN p.amount * 6.44
-- ELSE 1/0 END -- ??? this purposely raises an exception
FROM payment p;
$func$;
坚持使用 LANGUAGE sql
(就像您最初的尝试一样)。简单函数不需要 LANGUAGE plpgsql
- 除非您想为无效输入添加自定义错误消息或错误处理..
参见:
- Difference between language sql and language plpgsql in PostgreSQL functions
使用更简单的 switched CASE
(就像您最初的尝试一样)。
- Display column name with max value between several columns
- Simplify nested case when statement
提供明确的 ELSE
分支。 (如果未拼写 ELSE
,SQL CASE
默认为 NULL
。)
如果 payment_info
,在您最初的尝试中,是与您想要的 return 类型匹配的现有行类型,请使用简单的 RETURNS SETOF payment_info
而不是 RETURNS TABLE(...)
.
table-限定列 可能具有不明确的名称 是一种很好的风格,就像演示的那样。 (在任何情况下,从来都不是一个坏主意。)
但它是 LANGUAGE plpgsql
函数中的 要求 ,其中 RETURNS TABLE ...)
隐式声明与 table 列同名的 OUT
参数。这会引发异常,例如:
ERROR: column reference "payment_id" is ambiguous
参见:
- How to return result of a SELECT inside a function in PostgreSQL?
另外:numeric(5,2)
? 这引发了 amount > 999.99
的异常。看起来像一把上了膛的步兵枪。只需使用 numeric
或类似 numeric(20,2)
的舍入效果即可。
关于STABLE
:
关于PARALLEL SAFE
:
最后,已经清理完毕,分解结果行,调用SELECT * FROM
:
SELECT * FROM get_data('USD');
参见:
- Simple PostgreSQL function to return rows
- PostgreSQL: ERROR: 42601: a column definition list is required for functions returning "record"
我为输入参数添加了一个默认值:DEFAULT 'USD'
。这很方便,但完全是可选的。它记录了最常见的预期,并允许在没有显式参数的情况下进行简短调用:
SELECT * FROM get_data();