2

I have a Table name called employee_Details with Columns

 EMP_ID   NAME  VECH_NO  SALARY
   1       A      1234    100
   2       B      12345   200

I Construct JSON array using Java. with structure

{["EMP_ID":1,"NAME":Y,"VECH_NO":4587,"SALARY":1500],["EMP_ID":3,"NAME":Z,"VECH_NO":4007,"SALARY":1800]}

I need to update full record where EMP_ID exists on table else insert as new record. There is any in build function available in postgreSQL to achieve this. I refer this https://www.postgresql.org/docs/9.3/static/functions-json.html but didn't get solution

3
  • It is not clear what you are trying to do. Commented Sep 8, 2016 at 10:41
  • I have a JSON array. I have to Update if exists else insert it by using any inbuild functions like "json_populate_recordset". Commented Sep 8, 2016 at 11:11
  • Seems that you swapped [] and {} in your example. And what version of PostgreSQL are you using? If before 9.5, can you upgrade (to use new upsert capabilities)? Commented Sep 8, 2016 at 11:33

1 Answer 1

3

First of all, your JSON is malformed, I guess the intended was:

[
    {"EMP_ID":1,"NAME":"Y","VECH_NO":4587,"SALARY":1500},
    {"EMP_ID":3,"NAME":"Z","VECH_NO":4007,"SALARY":1800}
]

Assuming the following table definition:

CREATE TEMP TABLE employee_details(
    "EMP_ID" integer primary key,
    "NAME" text,
    "VECH_NO" integer,
    "SALARY" numeric
);

And a sample data (just to show the update):

INSERT INTO employee_details VALUES(1, 'X', 123, 123);

You can first use json_array_elements to make each array one row and json_populate_record to get each value as the original table type, like this:

SELECT r.*
FROM
    json_array_elements('[{"EMP_ID":1,"NAME":"Y","VECH_NO":4587,"SALARY":1500},{"EMP_ID":3,"NAME":"Z","VECH_NO":4007,"SALARY":1800}]') AS a(element),
    json_populate_record(NULL::employee_details, a.element) AS r;

With that, you can simple use INSERT ... ON CONFLICT UPDATE:

INSERT INTO employee_details("EMP_ID", "NAME", "VECH_NO", "SALARY")
(
    SELECT r."EMP_ID", r."NAME", r."VECH_NO", r."SALARY"
    FROM
        json_array_elements('[{"EMP_ID":1,"NAME":"Y","VECH_NO":4587,"SALARY":1500},{"EMP_ID":3,"NAME":"Z","VECH_NO":4007,"SALARY":1800}]') AS a(element),
        json_populate_record(NULL::employee_details, a.element) AS r
)
ON CONFLICT ("EMP_ID") DO
UPDATE SET
    "NAME" = EXCLUDED."NAME",
    "VECH_NO" = EXCLUDED."VECH_NO",
    "SALARY" = EXCLUDED."SALARY"
;

The ON CONFLICT clause only works on version 9.5 or higher. Before that you have to use some tricks with loop and retry or writable common table expression (although that has race-condition issues); in any case it is a good reason to upgrade if you are on older versions.

Sign up to request clarification or add additional context in comments.

1 Comment

By using loop I have done Update and insertion. Thank you.

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.