Home > Enterprise >  postgreSQL - ERROR: cannot extract elements from an object
postgreSQL - ERROR: cannot extract elements from an object

Time:01-09

I am a newbie to PostgreSQL. I have the below function and it is giving me an error. basically, I am passing JSON as a parameter to the function, extracting values, and inserting it into 2 tables. it is one to many relationships. so based on that one invoice has multiple line items:

PostgreSQL function:

    -- FUNCTION: public.insertorupdateinvoice(jsonb)

    -- DROP FUNCTION IF EXISTS public.insertorupdateinvoice(jsonb);

    CREATE OR REPLACE FUNCTION public.insertorupdateinvoice(
        invoice jsonb)
        RETURNS void
        LANGUAGE 'plpgsql'
        COST 100
        VOLATILE PARALLEL UNSAFE
    AS $BODY$
    Declare _invoiceid bigint;
    begin
      insert into invoicemaster (expenseid, invoiceno, transactiondate, totalinvoiceamount, invoicedoc, createdby, createdon)
      select (j.invoice->>'expenseid')::bigint, 
             j.invoice->>'invoiceno'::character, 
             (j.invoice->>'transactiondate')::date, 
             (j.invoice->>'totalinvoiceamount')::double precision, 
             j.invoice->>'invoicedoc'::character, 
             (j.invoice->>'createdby')::bigint,
             NOW()
      from jsonb_array_elements(invoice) as j(invoice)
      returning invoiceid into _invoiceid;

      insert into lineitemmaster (invoiceid, transactiondate, merchantname, amount, departmentid, policyid, itemdescription, 
                                  itemcategory, itemtype, status, isrejected, createdby, createdon)
      select _invoiceid::bigint, 
            (x.invoice->>'transactiondate')::date, 
            x.invoice->>'merchantname', 
            (x.invoice->>'amount')::double precision, 
            (x.invoice->>'departmentid')::integer, 
            (x.invoice->>'policyid')::integer, 
            x.invoice->>'itemdescription', 
            (x.invoice->>'itemcategory')::integer, 
            (x.invoice->>'itemtype')::integer, 
            (x.invoice->>'status')::boolean, 
            (x.invoice->>'isrejected')::boolean, 
            (x.invoice->>'createdby')::bigint,
            NOW()
      from jsonb_array_elements(invoice ->'lineitems') as x;
    end;
    $BODY$;

    ALTER FUNCTION public.insertorupdateinvoice(jsonb)
        OWNER TO postgres;

calling function as :

select * from insertorupdateinvoice('{"expenseid":1,
    "invoiceno":"04012022",
    "transactiondate":"2022-01-04",
    "totalinvoiceamount":1000.00,
    "invoicedoc":"invoicedoc",
    "createdby":1,
    "lineitems":[
      {"transactiondate":"2022-01-01", "merchantname":"Apple", "amount":"100.50", "departmentid":"1","policyid":"1", "itemdescription":"iphone 14 pro max", "itemcategory":"55", "itemtype":"499", "status":"true", "isrejected":"false", "createdby":"1"},
      {"transactiondate":"2022-01-02", "merchantname":"Samsung", "amount":"1050.35", "departmentid":"2","policyid":"2", "itemdescription":"samsung galaxy tab", "itemcategory":"40", "itemtype":"50", "status":"true", "isrejected":"false", "createdby":"1"},
      {"transactiondate":"2022-01-03", "merchantname":"Big bazar", "amount":"555.75", "departmentid":"3","policyid":"3", "itemdescription":"grocerry", "itemcategory":"5", "itemtype":"90", "status":"false", "isrejected":"false", "createdby":"1"}
    ]}');

getting error as below:

ERROR:  cannot extract elements from an object
CONTEXT:  SQL statement "insert into invoicemaster (expenseid, invoiceno, transactiondate, totalinvoiceamount, invoicedoc, createdby, createdon)
      select (j.invoice->>'expenseid')::bigint, 
             j.invoice->>'invoiceno'::character, 
             (j.invoice->>'transactiondate')::date, 
             (j.invoice->>'totalinvoiceamount')::double precision, 
             j.invoice->>'invoicedoc'::character, 
             (j.invoice->>'createdby')::bigint,
             NOW()
      from jsonb_array_elements(invoice) as j(invoice)
      returning invoiceid"
PL/pgSQL function insertorupdateinvoice(jsonb) line 5 at SQL statement
SQL state: 22023

Thanks

CodePudding user response:

try this :

CREATE OR REPLACE FUNCTION public.insertorupdateinvoice(
    invoice jsonb)
    RETURNS void
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE PARALLEL UNSAFE
AS $BODY$
Declare _invoiceid bigint;
begin
  insert into invoicemaster (expenseid, invoiceno, transactiondate, totalinvoiceamount, invoicedoc, createdby, createdon)
  values ( (invoice->>'expenseid') :: bigint, 
           invoice->>'invoiceno', 
           (invoice->>'transactiondate') :: date, 
           (invoice->>'totalinvoiceamount') :: double precision, 
           invoice->>'invoicedoc', 
           (invoice->>'createdby') :: bigint,
           NOW()
         )
  returning invoiceid into _invoiceid;

  insert into lineitemmaster (invoiceid, transactiondate, merchantname, amount, departmentid, policyid, itemdescription, 
                              itemcategory, itemtype, status, isrejected, createdby, createdon)
  select _invoiceid::bigint, 
        (x->>'transactiondate')::date, 
        x->>'merchantname', 
        (x->>'amount')::double precision, 
        (x->>'departmentid')::integer, 
        (x->>'policyid')::integer, 
        x->>'itemdescription', 
        (x->>'itemcategory')::integer, 
        (x->>'itemtype')::integer, 
        (x->>'status')::boolean, 
        (x->>'isrejected')::boolean, 
        (x->>'createdby')::bigint,
        NOW()
  from jsonb_array_elements(invoice ->'lineitems') as x;
end;
$BODY$;

see dbfiddle

  • Related