Вызов функции с передачей JSONB в качестве параметра - Postgres - PullRequest
0 голосов
/ 03 августа 2020

Ниже приведена функция, которую я написал

     CREATE OR REPLACE FUNCTION upd.insert_testdata(spec jsonb[])
     RETURNS void
     LANGUAGE 'plpgsql' AS $BODY$
            
     BEGIN
    --Consider all columns in specialist table as character varying and code column as integer.
        insert into upd.specialist (to_cd, empid, code, booking_status, availability)
           select j.spec->>'to_cd', 
                  j.spec->>'empid', 
                  j.spec->>'code', 
                  j.spec->>'booking_status',
                  j.spec->>'availability' 
           from jsonb_populate_record(spec) j;
        
                
     END;
     $BODY$;

Я пытаюсь вызвать функцию с помощью следующей команды

    SELECT upd.insert_testdata(
               '{
                "to_cd":"NFG",
                "empid":"test",
                "code":123,
                "booking_status":"Y", 
                "availability":"MTWTFSS"
                 }'::jsonb[]
             );

Но я получаю сообщение об ошибке Литерал искаженного массива

ДЕТАЛЬ: Неожиданный элемент массива. SQL состояние: 22P02

Также я хотел бы знать, как вставить несколько записей / передать несколько строк в одну json переменную

Ответы [ 2 ]

1 голос
/ 03 августа 2020

Не передавайте массив из json значений, передавайте json массив:

CREATE OR REPLACE FUNCTION upd.insert_testdata( spec jsonb)
     RETURNS void
LANGUAGE plpgsql
AS $BODY$
begin
  --Consider all columns in specialist table as character varying and code column as integer.
  insert into upd.specialist (to_cd, empid, code, booking_status, availability)
  select j.spec->>'to_cd', 
         j.spec->>'empid', 
         (j.spec->>'code')::int, 
         j.spec->>'booking_status', 
         j.spec->>'availability' 
  from jsonb_array_elements(spec) as j(spec);
end;
$BODY$;

Если вы не хотите перечислять все ключи вручную и если вы уверены на 100% чтобы имена ключей всегда совпадали с именами столбцов в таблице, вы можете немного упростить это, используя jsonb_populate_record

CREATE OR REPLACE FUNCTION upd.insert_testdata( spec jsonb)
     RETURNS void
LANGUAGE plpgsql
AS $BODY$
begin
  --Consider all columns in specialist table as character varying and code column as integer.
  insert into upd.specialist (to_cd, empid, code, booking_status, availability)
  select (jsonb_populate_record(null::specialist, j.spec)).*
  from jsonb_array_elements(spec) as j(spec);
end;
$BODY$;

Затем используйте его так:

select upd.insert_testdata('[
                              {"to_cd":"NFG",
                               "empid":"test",
                               "code":123,
                               "booking_status": "Y",
                               "availability":"MTWTFSS"}
                            ]'::jsonb);

Если хотите для передачи нескольких элементов вы можете использовать его следующим образом:

select upd.insert_testdata('[
                              {"to_cd":"NFG",
                               "empid":"test",
                               "code":123,
                               "booking_status": "Y",
                               "availability":"MTWTFSS"},
                              {"to_cd":"CFG",
                               "empid":"test2",
                               "code": 456,
                               "booking_status": "N",
                               "availability":"MT"}
                            ]'::jsonb);

Онлайн-пример

0 голосов
/ 03 августа 2020

Вам не обязательно отправлять и получать как jsonb. Вы можете отправить как текст и преобразовать в объект jsonb внутри своей функции.

CREATE OR REPLACE FUNCTION upd.insert_testdata(spec text)
RETURNS void LANGUAGE 'plpgsql'
AS $BODY$
declare
  your_json jsonb;
begin
  your_json := spec::jsonb;
  

И вы отправляете jsonb как текст.

select upd.insert_testdata(
    '{
        "to_cd":"NFG",
        "empid":"test",
        "code":123,
        "booking_status":"Y", 
        "availability":"MTWTFSS"
     }'
)

...