如何在Postgres中检查数组是否为空

时间:2014-08-06 08:33:31

标签: sql arrays postgresql stored-procedures null

我有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('{}')..."

但如果数组为空,则不应在查询中表示此条件 如何检查客户端数组是否为空?

我也尝试了两种变种:

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;

4 个答案:

答案 0 :(得分:45)

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

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;

这排除了空数组 NULL。


但是,如果您要将查询连接到与EXECUTE一起运行,那么传递带有USING子句的值会更聪明。例子:


BTW,要明确检查数组是否为空(就像你的标题所说 - 但 空数组:

id_clients = '{}'

这就是全部。你得到:

TRUE ..数组为空 NULL ..数组为NULL FALSE ..任何其他情况(数组都有元素 - 即使只是NULL元素)

答案 1 :(得分:14)

如果由于某种原因你不想提供数组的维度,cardinality将为空数组返回0:

来自文档:

  

基数(anyarray)返回的元素总数   数组,如果数组为空则为0

答案 2 :(得分:0)

一种检查数组是否为空的方法是使用array_ndims返回数组的维数,如果数组为空,它将返回0。我正在使用版本11的PostgreSQL。

scanner.useDelimiter("(\\s*,\\s*)|\r?\n");

$$;

输出:

$$
DECLARE

    IDS_PATROCINADOR_RED_0 INTEGER[] := ARRAY []::INTEGER[];
    IDS                        INTEGER;
BEGIN

    IF array_ndims(IDS_PATROCINADOR_RED_0) > 0 THEN
        IDS = array_length(ARRAY []::INTEGER, 1);
    ELSE
        IDS = 0 ;
    end if;
    RAISE NOTICE '%', IDS;
END

[2020-04-22 11:06:22]在143毫秒内完成

答案 3 :(得分:-1)

下面的示例接受python yourprogram.py filename.csvarray valuesNULL作为查询参数。当您尝试将empty string作为查询参数并发送空字符串时,某些框架会导致SQL错误。

查询使用json 映射检查数组参数是否为空:

NULL