web-dev-qa-db-ja.com

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

ただし、配列が空の場合、この条件はクエリで表されるべきではありません。
クライアントの配列が空でないかどうかを確認するにはどうすればよいですか?

また、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;

29
joni jones

array_length() にはtwoパラメーターが必要です。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の両方が除外されます。


しかし、クエリを連結してEXECUTEで実行する場合、USING句で値を渡す方が賢明です。例:


ところで、配列が空であるかどうかを明示的にチェックするには(タイトルが言うように-しかし、それはnotここで必要なものです)比較するだけです空の配列に:

id_clients = '{}'

それで全部です。あなたが得る:

TRUE ..配列は空です
NULL ..配列はNULLです
FALSE ..その他の場合(配列には要素があります-NULL要素だけでも)

51

何らかの理由で配列の次元を指定したくない場合、 cardinality は空の配列に対して0を返します:

ドキュメントから:

cardinality(anyarray)は、配列内の要素の総数を返します。配列が空の場合は0を返します

15
bronzenose