sql - plpgsql 函数 concat optionnal args 返回错误
问题描述
我想连接由 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
解决方案
为什么不直接使用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;
推荐阅读
- django - Django API 调用需要太多时间来响应
- facebook - 从 ffmpeg 流式传输到 Facebook Live 被终止
- javascript - 如何制作一个 discord.js 随机数生成器来生成用户输入
- c# - Microsoft.WindowsAzure.Storage 是否符合 FIPS 140-2
- python - 在设置文件上将 DEBUG 设置为 true 时出现错误
- c# - 如何在 LINQ SQL C# 中返回动态周数?
- python - 尝试在 snort 日志 (.csv) 中分隔日期时间
- r - grid.Call 中的错误(C_textBounds,as.graphicsAnnot(x$label),x$x,x$y,:未找到多边形边
- python - 设置一个 vispy 自动缩放,显示屏幕上的所有项目,如 pyqtgraph autoRange() 函数
- firebase - 如果没有 List 或 ForEach,我无法从 Firebase 读取数据