1

I am very new to Postgres SQL. My requirement is to pass a dynamic number of columnId, columnValue pair and insert this combination in a table(Example: employeeId, employeeName combination). The length of list can be anything. I am thinking of building dynamic query at the code-side and pass it as string to function and execute the statement. Is there any better approach for this problem. Any example or idea will be much appreciated.

1
  • you should show a example table with require table. Commented Feb 18, 2019 at 9:51

1 Answer 1

2

If you are allowed to pass that information as a structured JSON value, this gets quite easy. Postgres has a feature to map a JSON value to a table type using the function json_populate_record

Sample table:

create table some_table 
( 
  id integer primary key, 
  some_name text, 
  some_date date, 
  some_number integer
);

The insert function:

create function do_insert(p_data text)
 returns void
as 
$$
  insert into some_table (id, some_name, some_date, some_number)
  select (json_populate_record(null::some_table, p_data::json)).*;
$$
language sql;

Then you can use:

select do_insert('{"id": 42, "some_name": "Arthur"}');
select do_insert('{"id": 1, "some_value": 42}');

Note that columns that are not part of the passed JSON string are explicitly set to NULL using this approach.

If the passed string contains column names that do not exist, they are simply ignored, so

select do_insert('{"id": 12, "some_name": "Arthur", "not_there": 123}');

will ignore the not_there "column".

Online example: https://rextester.com/JNIBL25827


Edit

A similar approach can be used for updating:

create function do_update(p_data text)
 returns void
as 
$$
  update some_table 
     set id = t.id,
         some_name = t.some_name, 
         some_date = t.some_date, 
         some_number = t.some_number
  from json_populate_record(null::some_table, p_data::json) as t;
$$
language sql;

or using insert on conflict to cover both use cases with one function:

create function do_upsert(p_data text)
 returns void
as 
$$
  insert into some_table (id, some_name, some_date, some_number)
  select (json_populate_record(null::some_table, p_data::json)).*
  on conflict (id) do update
     set id = excluded.id,
         some_name = excluded.some_name, 
         some_date = excluded.some_date, 
         some_number = excluded.some_number
$$
language sql;
Sign up to request clarification or add additional context in comments.

2 Comments

Excuse my ignorance about postgres since I am only a couple of days old in this technology but this has to be the greatest feature of postgres. Saved hours of coding. I am indeed passing JSON!
Just one question though. How do we update the record using the same approach?

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.