plpgsql 函数 concat 可选参数 返回错误
Posted
技术标签:
【中文标题】plpgsql 函数 concat 可选参数 返回错误【英文标题】:plpgsql function concat optionnal args return error 【发布时间】:2020-05-06 08:41:09 【问题描述】:我想连接由 AND 分隔的可选参数,并返回那些非空的连接参数的 varchar。
CREATE OR REPLACE FUNCTION shop_apply_search_filters(price_min INTEGER DEFAULT NULL, price_max INTEGER DEFAULT NULL, ecom_id INTEGER DEFAULT NULL,
cat_1 VARCHAR DEFAULT NULL, cat_2 VARCHAR DEFAULT NULL)
RETURNS VARCHAR AS
$$
DECLARE final_filters VARCHAR(500);
BEGIN
IF price_min IS NOT NULL THEN
SELECT CONCAT('price<',price_min) AS n_price_min;
final_filters := n_price_min;
END IF;
IF price_max IS NOT NULL THEN
SELECT CONCAT('price>',price_max) AS n_price_max;
final_filters := CONCAT(final_filters,' AND ', n_price_max);
END IF;
IF ecom_id IS NOT NULL THEN
SELECT CONCAT('ecom_id=',ecom_id) AS n_ecom_id;
final_filters := CONCAT(final_filters,' AND ', n_ecom_id);
END IF;
IF cat_1 IS NOT NULL THEN
SELECT CONCAT('category_1:',cat_1) AS n_cat_1;
final_filters := CONCAT(final_filters,' AND ', n_cat_1);
END IF;
IF cat_2 IS NOT NULL THEN
SELECT CONCAT('category_2:',cat_2) AS n_cat_2;
final_filters := CONCAT(final_filters,' AND ', n_cat_2);
END IF;
RETURN final_filters;
END;
$$
LANGUAGE PLPGSQL;
SELECT shop_apply_search_filters(10) 的输出将是一个类似于“价格 > 10”的字符串。 调用函数时是否可以传递参数名称?为了能够区分 price_min 和 price_max 如果只通过其中一个。 是否可以将非空参数附加到列表中,然后使用 AND 加入列表元素?
你会怎么做?
编辑
我在 CONCAT() 时删除了 SELECT() 以避免错误。但我有一个新的:
ERROR: query has no destination for result data
HINT: If you want to discard the results of a SELECT, use PERFORM instead.
CONTEXT: PL/pgSQL function shop_apply_search_filters(integer,integer,integer,character varying,character varying) line 5 at SQL statement
SQL state: 42601
编辑 我试过了:
create or replace function shop_apply_search_filters(
price_min integer default null,
price_max integer default null,
ecom_id integer default null,
cat_1 text default null,
cat_2 text default null)
returns text as
$$
select concat_ws(
' and ',
'price < ' || price_min,
'price > ' || price_max,
'ecom_id = ' || ecom_id,
'category_1 = ' || cat_1,
'category_2 = ' || cat_2
);
$$
language sql;
它适用于所有传递的参数:
SELECT shop_apply_search_filters(10,10,10,'cat_1','cat_2')
没有传完参数怎么办?
SELECT shop_apply_search_filters(10,10,'cat_1','cat_2')
ERROR: invalid input syntax for integer: "cat_1"
LINE 1: SELECT shop_apply_search_filters(10,10,'cat_1','cat_2')
^
SQL state: 22P02
Character: 40
SELECT shop_apply_search_filters(10,10)
ERROR: function shop_apply_search_filters(integer, integer) is not unique
LINE 1: SELECT shop_apply_search_filters(10,10)
^
HINT: Could not choose a best candidate function. You might need to add explicit type casts.
SQL state: 42725
Character: 8
【问题讨论】:
肯定还有更多事情要做,因为显示的函数和选择绝对有效:dbfiddle.uk/… 看来您有几个具有该名称的重载函数。 【参考方案1】:为什么不直接使用concat_ws()
一次加入整个字符串?
concat_ws(
' and ',
'price < ' || price_min,
'price > ' || price_max,
'ecom_id = ' || ecom_id,
'category_1 = ' || cat_1,
'category_2 = ' || cat_2
)
然后您可以将整个过程简化为:
create or replace function shop_apply_search_filters(
price_min integer default null,
price_max integer default null,
ecom_id integer default null,
cat_1 text default null,
cat_2 text default null)
returns text as
$$
select concat_ws(
' and ',
'price < ' || price_min,
'price > ' || price_max,
'ecom_id = ' || ecom_id,
'category_1 = ' || cat_1,
'category_2 = ' || cat_2
);
$$
language sql;
【讨论】:
这不是问题中直接问题的一部分,但是:该函数听起来好像它应该创建一个要在 WHERE 子句中使用的条件。在这种情况下,cat_1
和 cat_2
的值可能应该用单引号括起来,例如使用quote_literal()
。个别条件也应该与 AND 结合使用。以上是关于plpgsql 函数 concat 可选参数 返回错误的主要内容,如果未能解决你的问题,请参考以下文章