【问题标题】:How to pass an array of JSON (or JSON array) to pg function to be INSERTed into a Table?如何将 JSON 数组(或 JSON 数组)传递给 pg 函数以插入到表中?
【发布时间】:2021-11-30 14:31:53
【问题描述】:

将json数组的行插入表中的功能:

create table mytable(col1 text, col2 boolean, col3 boolean);
create function fun1(vja json[])
... as $$
begin
  foreach v in array json_array_elements(vja)
  loop
    insert into mytable(col1, col2, col3)
    values(v->'col1', v->'col2'::boolean, v->'col3'::boolean);
  end loop;
end;
$$;

调用这个函数:

select fun1('[
    {"col1": "turow1@af.com", "col2": false, "col3": true}, 
    {"col1": "xy2@af.com", "col2": false, "col3": true} 
    ]')

或这种形式:

select fun1('[
    {"col1": "turow1@af.com", "col2": "false", "col3": "true"}, 
    {"col1": "xy2@af.com", "col2": "false", "col3": "true"}, 
    ]')

或这种形式:

select fun1('[
    {"col1": "turow1@af.com", "col2": "false", "col3": "true"}, 
    {"col1": "xy2@af.com", "col2": "false", "col3": "true"}, 
    ]'::json[])

总是收到:

ERROR:  malformed array literal: "[
  {"col1": "turow1@af.com", "col2": "false", "col3": "true"}, 
  {"col1": "xy2@af.com", "col2": "false", "col3": "true"}, 
  ]"
LINE 2:  '[
         ^
DETAIL:  "[" must introduce explicitly-specified array dimensions.
SQL state: 22P02
Character: 136

【问题讨论】:

    标签: sql arrays json postgresql function


    【解决方案1】:

    JSON 数组 (json) 不同于 JSON 值的 Postgres 数组 (json[])。

    SELECT '[{"foo": "bar"}, {"foo1": "bar1"}]'::json;  -- JSON array
    

    对比:

    SELECT '{"{\"foo\": \"bar\"}","{\"foo1\": \"bar1\"}"}'::json[]  -- array of JSON
    

    第一个是嵌套在单个 JSON 值中的数组,第二个是 JSON 值的数组。

    JSON 的 Postgres 数组 (json[])

    您的(固定!)功能:

    CREATE OR REPLACE FUNCTION fun1(vja json[])
      RETURNS void
      LANGUAGE plpgsql AS
    $func$
    DECLARE
       v json;
    BEGIN
       FOREACH v IN ARRAY vja
       LOOP
          INSERT INTO mytable(col1, col2, col3)
          VALUES(v ->> 'col1', (v ->> 'col2')::bool, (v ->> 'col3')::bool);
       END LOOP;
    END
    $func$;
    

    期待这样的调用(注意 json[] 文字的所有转义):

    SELECT fun1('{"{\"col1\": \"turow1@af.com\", \"col2\": false, \"col3\": true}","{\"col1\": \"xy2@af.com\", \"col2\": false, \"col3\": true}"}'::json[]);
    

    见:

    但是过程中单个INSERTjson_populate_record()胜过在函数中循环:

    CREATE OR REPLACE PROCEDURE proc1(vja json[])
      LANGUAGE sql AS
    $proc$
    INSERT INTO mytable  -- target column list redundant in this particular case
    SELECT r.*
    FROM   unnest(vja) v, json_populate_record(NULL::mytable, v) r
    $proc$;
    

    见:

    或者使用 Postgres 14 或更高版本中的标准 SQL 变体更简单:

    CREATE OR REPLACE PROCEDURE proc1(vja json[])
    BEGIN ATOMIC
    INSERT INTO mytable
    SELECT r.*
    FROM   unnest(vja) v, json_populate_record(NULL::mytable, v) r;
    END;
    

    见:

    调用(!):

    CALL proc1('{"{\"col1\": \"turow1@af.com\", \"col2\": false, \"col3\": true}","{\"col1\": \"xy2@af.com\", \"col2\": false, \"col3\": true}"}'::json[]);
    

    db小提琴here

    JSON 数组 (json)

    通常,您希望像尝试过的那样传递 JSON 数组。 所以,现在用json_populate_recordset()

    CREATE OR REPLACE PROCEDURE proc2(vja json)
      LANGUAGE sql AS
    $proc$
    INSERT INTO mytable
    SELECT * FROM json_populate_recordset(NULL::mytable, vja);
    $proc$;
    

    或者(Postgres 14):

    CREATE OR REPLACE PROCEDURE proc2(vja json)
    BEGIN ATOMIC
    INSERT INTO mytable
    SELECT * FROM json_populate_recordset(NULL::mytable, vja);
    END;
    

    调用(现在您可以使用最初测试的值!):

    CALL proc2('[
        {"col1": "turow1@af.com", "col2": false, "col3": true}, 
        {"col1": "xy2@af.com", "col2": false, "col3": true} 
        ]');
    

    db小提琴here

    【讨论】:

    • 很棒的细节和推荐!! Q1 关于 JSON 数组(json)pg 的 JSON 数组(json[]),如果节点 API 传入的参数值为[{col1: 'a1@a.com', col2: false, col3: true}, {col1: 'a2@a.com', col2: false, col3: true}],选择哪种形式? Q2 固定功能在public 中有效,但在其他operator does not exist: text ->> unknown 中有效,缺少什么?非常感谢! 第 12 页
    • Q1:这是一个 JSON 数组 (json)。 Q2:错误信息表明类型text,这里应该是类型json
    猜你喜欢
    • 2020-03-14
    • 1970-01-01
    • 1970-01-01
    • 2021-01-17
    • 1970-01-01
    • 1970-01-01
    • 2011-11-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多