【问题标题】:LOOP through JSON data in stored procedure Postgres循环通过存储过程 Postgres 中的 JSON 数据
【发布时间】:2020-01-27 07:58:48
【问题描述】:

我的 fpo 表如下所示

 id                             fo_data
  1          {"bene_first_name":{"value":"Chris1"},"bene_last_name":{"value":"Ronald"}}
  2          {"bene_first_name":{"value":"John"},"bene_last_name":{"value":"Wick"}}
  1          {"bene_first_name":{"value":"James"},"bene_last_name":{"value":"Cooper"}}

我已经创建了一个如下的存储过程,我正在尝试将特定列“fo_data”的所有数据推送到单个 JSON 变量中,并且我正在尝试循环获得的 JSON 数据

CREATE OR REPLACE FUNCTION file_compare()
RETURNS TEXT LANGUAGE 'plpgsql' COST 100 VOLATILE AS $BODY$
DECLARE
  fpo_data jsonb;
  i JSONB;
BEGIN
  SELECT json_agg((fpdata))::jsonb
  FROM (SELECT fo_data AS fpdata
        FROM fpo LIMIT 100
    ) t  INTO fpo_data; 
  FOR i IN SELECT * FROM jsonb_array_elements(fpo_data) LOOP
    RAISE NOTICE 'output from space %', i->>'bene_firstname';
  END LOOP;
  RETURN fpo_data;
END;
$BODY$;

我得到"RETURN fpo_data"的以下输出

 ["{\"bene_first_name\":{\"value\":\"Chris\"},\"bene_last_name\":{\"value\":\"Ronald\"}}",
  "{\"bene_first_name\":{\"value\":\"John\"},\"bene_last_name\":{\"value\":\"Wick\"}}",
   "{\"bene_first_name\":{\"value\":\"James\"},\"bene_last_name\":{\"value\":\"Cooper\"}}"

如果我尝试像这样打印'bene_firstname'

 RAISE NOTICE 'output from space %', i->>'bene_firstname'

我得到的错误是

 ERROR: operator does not exist: record ->> unknown.

如果我单独打印“i”,我会在控制台中打印以下数据

NOTICE:  output from space ("""{\\""bene_first_name\\"":{\\""value\\"":\\""Chris90\\""},\\""bene_last_name\\"":{\\""value\\"":\\""Ronald\\""}}""")
NOTICE:  output from space ("""{\\""bene_first_name\\"":{\\""value\\"":\\""John\\""},\\""bene_last_name\\"":{\\""value\\"":\\""Wick\\""}}""")
NOTICE:  output from space ("""{\\""bene_first_name\\"":{\\""value\\"":\\""James\\""},\\""bene_last_name\\"":{\\""value\\"":\\""Cooper\\""}}""")

如何从上述 json 数组中获取 'bene_firstname'

【问题讨论】:

  • 这令人惊讶;这个对我有用。你确定i 被声明为jsonb,而不是record
  • @LaurenzAlbe 抱歉,我将“i”声明为记录。我已将其更改为 jsonb。现在我得到 i->>'bene_firstname' 但在'bene_firstname' 中是'值'。如果我尝试打印 i->>'bene_firstname'->>'value' 我收到错误为 ERROR: operator does not exist: text ->> unknown
  • 那就是i->'bene_firstname'->>'value'
  • @LaurenzAlbe 如果我写 i->'bene_firstname'->>'value',我得到的输出是“来自空间 的输出”
  • 很难说不知道fpo

标签: sql postgresql stored-procedures plpgsql postgresql-9.5


【解决方案1】:

这是你要找的东西吗:

CREATE OR REPLACE FUNCTION file_compare()
RETURNS TEXT LANGUAGE plpgsql COST 100 STABLE AS $BODY$
DECLARE
  fpo_data jsonb;
  i JSONB;
BEGIN
  SELECT json_agg(fo_data)::jsonb from (select fo_data from fpo limit 100) d into fpo_data;
  FOR i IN SELECT * FROM jsonb_array_elements(fpo_data) LOOP
    RAISE NOTICE 'output from space %', i#>>'{bene_first_name,value}';
  END LOOP;
  RETURN fpo_data::text;
END;
$BODY$;

这假设 fo_data 是一个 json 字段。请注意,我将函数更改为 STABLE,因为它不会更改任何数据。

最好的问候,
比亚尼

【讨论】:

  • 是的。但是我如何在“bene_firstname”中获得“价值”,即我期望第一行的输出为“Chris90”
  • 啊,对不起。我更正了代码。不知何故, bene_firstname 进入了对话,但根据代码中的输出,它是 bene_first_name 。我改变以获得价值。我还返回文本,因为函数是这样定义的。
  • 我已经尝试打印 i->>'bene_first_name',但我得到的是'来自空间的输出 '
  • 您尝试过我发布的代码吗? i->>'bene_first_name' 不起作用,因为 bene_first_name 字段是 jsonb 对象。 i->'bene_first_name' 应该可以工作,并且 (i->'bene_first_name')::jsonb->>'value' 也是一个文本字段。 i#>>'{bene_first_name,value}' 也返回文本。
  • @BjarniRangnarsson 我仍然收到 。我也不能接受你的查询,因为我的表有数千条记录,而你的查询超时。所以我需要在写的时候写一个子查询
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-04
  • 1970-01-01
  • 2015-01-19
  • 1970-01-01
相关资源
最近更新 更多