我有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
;
答案 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)
答案 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.csv
,array values
或NULL
作为查询参数。当您尝试将empty string
作为查询参数并发送空字符串时,某些框架会导致SQL错误。
查询使用json 映射检查数组参数是否为空:
NULL