Не передавайте массив из 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);
Онлайн-пример