Подтвердить что ты не робот

Как проверить, нет ли массива в Postgres

У меня есть функция 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;

4b9b3361

Ответ 1

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-элементы)

Ответ 2

если по какой-то причине вы не хотите указывать размерность массива, cardinality вернет 0 для пустого массива:

Из документов:

(anyarray) возвращает общее количество элементов в массив или 0, если массив пуст