我有一个Postgres功能:

CREATE OR REPLACE FUNCTION get_stats(
    _start_date timestamp with time zone,
    _stop_date timestamp with time zone,
    id_clients integer[],
    OUT date timestamp with time zone,
    OUT profit,
    OUT cost
)
RETURNS SETOF record
LANGUAGE plpgsql
AS $$
DECLARE
    query varchar := '';
BEGIN
... -- lot of code
IF id_clients IS NOT NULL THEN
    query := query||' AND id = ANY ('||quote_nullable(id_clients)||')';
END IF;
... -- other code
END;
$$;

所以如果我运行类似这样的查询:

SELECT * FROM get_stats('2014-07-01 00:00:00Etc/GMT-3'
                      , '2014-08-06 23:59:59Etc/GMT-3', '{}');

生成的查询具有以下条件:

"... AND id = ANY('{}')..."

但如果数组为空,则不应在查询中表示此条件

我还try 了两种变体:

IF ARRAY_UPPER(id_clients) IS NOT NULL THEN
    query := query||' AND id = ANY ('||quote_nullable(id_clients)||')';
END IF;

以及:

IF ARRAY_LENGTH(id_clients) THEN
    query := query||' AND id = ANY ('||quote_nullable(id_clients)||')';
END IF;

在这两种情况下,我都得到了这个错误:ARRAY_UPPER(ARRAY_LENGTH) doesn't exists

推荐答案

array_length()需要two个参数,第二个是数组的维度:

array_length(id_clients, 1) > 0

所以:

IF array_length(id_clients, 1) > 0 THEN
    query := query || format(' AND id = ANY(%L))', id_clients);
END IF;

这不包括空数组和空array.

或者在Postgres 9.4或更高版本中使用cardinality().See added answer by @bronzenose.


但是,如果将查询与EXECUTE连接起来运行,那么使用USING子句传递值会更明智.例如:


顺便说一句,要明确地判断array is empty(就像你的标题所说的——但这里需要的是not)是否与空数组进行比较:

id_clients = '{}'

这就是全部.你会得到:

TRUE .. array is empty
NULL .. array is NULL
FALSE .. any other case (array has elements - even if just NULL elements)

Sql相关问答推荐

Oracle SQL中的累计总数

如何使用ROW_NUM() Select 一个没有第二条记录的实例?

如何根据特定的内部json元素值过滤postgres查询结果?

收到%1、%2或%2邮箱的唯一客户

基于多参数的SQL Server条件过滤

我需要一个regexp_like来只验证字母D或T、数字和管道

从类似JSON的字符串列创建新列

按两列分组,并根据SQL中的条件返回第三个列值

在VB.NET中如何在MS Access数据库中创建SQL项目历史库存卡

排除具有部分匹配条件的记录

Postgres jsonpath运算符的变量替换,如_regex?

SQL仅返回第一个字母在A-Z之间的值

如何使用Clickhouse的COUNT聚合返回所有列,但GROUP BY是这些列的子集

删除行而不使数据库超载

在 R 值的 SQL 块中显示值

根据要过滤的列的值进行联接和分组

达到特定值时,从0开始累加求和

比使用NOT EXISTS更高效的SQL删除方法是什么?

SQL/Postgres:按日期和其他属性对相关性能进行分组

如何在 SQLite 中将列的两个或多个相等的连续值合并为一个?