1. ホーム
  2. sql

Postgres で配列が空かどうかを確認する方法

2023-08-21 23:14:42

質問

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

しかし、配列が空の場合、この条件はクエリで表現されるべきではありません。

クライアントの配列が空でないことを確認するにはどうしたらよいでしょうか。

2つのバリエーションも試しました。

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() が必要です。 2 パラメータが必要で、2つ目は配列の次元です。

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を除く。

あるいは cardinality() を Postgres 9.4 以降で使用します。 bronzenose さんの追加回答を参照してください。


しかし、もしクエリを連結して実行するのであれば、そのクエリを EXECUTE で値を渡すのであれば USING 節で値を渡す方が賢明です。例


ちなみに、明示的に 配列が空かどうかを明示的にチェックするには を明示的にチェックすることができます (タイトルにあるように - しかしそれは ではなく ではありません)、空の配列と比較するだけです。

id_clients = '{}'

以上です。得ることができます。

TRUE ... 配列は空です

NULL ... 配列はNULLです。

FALSE ... その他の場合(配列に要素がある - たとえそれがNULL要素でも)。