Arrays 将JSONB_数组_元素结果分配给VARCHAR数组

Arrays 将JSONB_数组_元素结果分配给VARCHAR数组,arrays,postgresql,postgresql-9.5,postgresql-json,Arrays,Postgresql,Postgresql 9.5,Postgresql Json,当尝试将调用的结果分配给时(供以后在SELECT…WHERE in(UNNEST(…)语句中使用),以下存储函数: CREATE OR REPLACE FUNCTION test1( IN in_sids jsonb, OUT out_uid integer) RETURNS integer AS $func$ DECLARE sids varchar[]; uids integer[]; BEGIN

当尝试将调用的结果分配给时(供以后在
SELECT…WHERE in(UNNEST(…)
语句中使用),以下存储函数:

CREATE OR REPLACE FUNCTION test1(
        IN in_sids jsonb,
        OUT out_uid integer)
        RETURNS integer AS
$func$
DECLARE
        sids varchar[];
        uids integer[];
BEGIN
        sids := (SELECT x->>'sid' FROM JSONB_ARRAY_ELEMENTS(in_sids) x);
        -- uids := (SELECT uid FROM social WHERE sid IN (UNNEST(sids)));

        RAISE NOTICE 'sids = %', sids;
        RAISE NOTICE 'uids = %', uids;

        SELECT 1;
END
$func$ LANGUAGE plpgsql;
不幸的是,打印错误:

# select test1('[{"sid":"aaa"},{"sid":"bbb"}]'::jsonb);

ERROR:  more than one row returned by a subquery used as an expression
CONTEXT:  SQL statement "SELECT (SELECT x->>'sid' FROM JSONB_ARRAY_ELEMENTS(in_sids) x)"
PL/pgSQL function test1(jsonb) line 6 at assignment
因此,我尝试使用-

但是得到语法错误:

ERROR:  syntax error at or near "SELECT"
LINE 10:         sids := SELECT ARRAY_AGG(SELECT x->>'sid' FROM JSONB...
                         ^
如何将
JSONB_数组_元素
结果存储到数组中

更新:

我已经听从了尼克的建议(谢谢),但现在却陷入了下一步:

CREATE OR REPLACE FUNCTION test1(
        IN in_sids jsonb,
        OUT out_uid integer)
        RETURNS integer AS
$func$
DECLARE
        sids varchar[];
        uids integer[];
BEGIN
        sids := (SELECT ARRAY_AGG(x->>'sid') FROM JSONB_ARRAY_ELEMENTS(in_sids) x);
        uids := (SELECT uid FROM social WHERE sid IN (UNNEST(sids)));

        SELECT 1;
END
$func$ LANGUAGE plpgsql;
尝试在
中使用数组时,请选择。。。其中在…
语句中:

# select test1('[{"sid":"aaa"},{"sid":"bbb"}]'::jsonb);
ERROR:  argument of IN must not return a set
LINE 1: SELECT (SELECT uid FROM social WHERE sid IN (UNNEST(si...
                                              ^
QUERY:  SELECT (SELECT uid FROM social WHERE sid IN (UNNEST(sids)))
CONTEXT:  PL/pgSQL function test1(jsonb) line 7 at assignment
uids := (SELECT ARRAY_AGG(uid) FROM social WHERE sid IN (SELECT UNNEST(sids)));
你很接近

sids := (SELECT ARRAY_AGG(x->>'sid') FROM JSONB_ARRAY_ELEMENTS(in_sids) x);
为了使用构造,您需要编写一个自包含的
SELECT
语句:

# select test1('[{"sid":"aaa"},{"sid":"bbb"}]'::jsonb);
ERROR:  argument of IN must not return a set
LINE 1: SELECT (SELECT uid FROM social WHERE sid IN (UNNEST(si...
                                              ^
QUERY:  SELECT (SELECT uid FROM social WHERE sid IN (UNNEST(sids)))
CONTEXT:  PL/pgSQL function test1(jsonb) line 7 at assignment
uids := (SELECT ARRAY_AGG(uid) FROM social WHERE sid IN (SELECT UNNEST(sids)));
或者,您可以使用以下方法检查值是否在数组中:

如果未使用
sids
数组进行后续计算,则可以将它们组合到一个查询中:

uids := (
  SELECT array_agg(uid)
  FROM social
  JOIN JSONB_ARRAY_ELEMENTS(in_sids) x ON
    sid = x->>'sid'
);

实际上,我也使用了
sids
,但是谢谢你。
ANY
不会比
unest
慢吗?如果
sid
列被索引,并且相对有选择性,那么
ANY
通常会更快。
UNNEST
版本在查询计划方面具有更大的灵活性,在索引没有帮助的情况下,它往往会占据上风。如果有疑问,只需比较两个查询之间的
EXPLAIN analysis
输出。