1

I have to create a function that takes an object of this type :

    "users":"John",
    "Level":"1",
    "list":[
      {"id":"1", "price1":"100.50", "price2":"90.50"},
      {"id":"2", "price1":"100.60", "price2":"80.50"},
      {"id":"2", "price1":"105.50", "price2":"700.50"}
    ]}

For information JSON is not obliged but it is the thing that seemed the simplest to me. But maybe the creation of a POSTGRES type can work.

Then how to process the object if I use a JSON or PostGres Type.

    CREATE OR REPLACE FUNCTION MYFUNCTION(myobject JSON ? CREATE TYPE ? )
      RETURNS TABLE (
        "OK" BOOLEAN,
        "NB" VARCHAR
      )
    
    AS $$
    
    DECLARE
    
    
    BEGIN
    
    -- I would like to get for each object in the list the price1 and price2 to 
       compare them. 
    
    END; $$
    
    LANGUAGE 'plpgsql';
2
  • It is absolutely not clear what you are trying to achieve. What is your expected result? Commented Jan 13, 2021 at 9:06
  • i want to recup all object in the list and compare price1 and price2, but how can recup for each object in the "list" ? Commented Jan 13, 2021 at 9:13

2 Answers 2

1

The crux of the question seems to be how to extract the values from the json object. This is one way:

select * from json_to_recordset('{
     "users":"John",
     "Level":"1",
     "list":[
      {"id":"1", "price1":"100.50", "price2":"90.50"},
      {"id":"2", "price1":"100.60", "price2":"80.50"},
      {"id":"2", "price1":"105.50", "price2":"700.50"}
    ]}'::json->'list') as foo(id int, price1 numeric, price2 numeric);

With a json variable instead of the literal string:

select * from json_to_recordset(jsonvariable->'list') as foo(id int, price1 numeric, price2 numeric)

Note. The json object you provide isn't legal. Some commas missing. I'd also suggest you use jsonb instead of json.

Edited:This is a skeleton on how you can use this in a plpgsql function:

create or replace function func(jsonvariable json) returns table (ok boolean, nb text) as 
$BODY$
declare 
    r record;
begin
    for r in (select * from json_to_recordset(jsonvariable->'list') as foo(id int, price1 numeric, price2 numeric)) loop
        --- DO THINGS
        ok:=(r.price1>r.price2);
        nb:='this is text returned';
        return next;
    end loop;
end;
$BODY$
language plpgsql;
Sign up to request clarification or add additional context in comments.

Comments

1

No Need to use loop for processing on the JSON ARRAY. you can use JSONB_ARRAY_ELEMENTS or JSONB_TO_RECORDSET for your requirement like below:

Using JSONB_TO_RECORDSET

CREATE OR REPLACE FUNCTION MYFUNCTION(myobject JSONB)
      RETURNS TABLE (ok BOOLEAN, nb VARCHAR)
      AS 
      $$
      BEGIN
       return query
        select 
           price1>price2,     -- you can change the condition here
           id::varchar        -- you can change the value as per your requirement
        from jsonb_to_recordset(myobject ->'list') as x(id int, price1 numeric, price2 numeric);
    
    END; 
$$
    
LANGUAGE 'plpgsql';

Using JSONB_ARRAY_ELEMENTS

CREATE OR REPLACE FUNCTION MYFUNCTION1(myobject JSONB)
      RETURNS TABLE (ok BOOLEAN, nb VARCHAR)
      AS 
      $$
      BEGIN
       return query
        select 
           (x->>'price1')::numeric > (x->>'price2')::numeric,     -- you can change the condition here
           (x->>'id')::varchar                                    -- you can change the value as per your requirement
        from jsonb_array_elements(myobject ->'list') as x;
    
    END; 
$$
    
LANGUAGE 'plpgsql';

DEMO

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.