0

I am trying to Update below sample json data into an Oracle version 19 table. (I want update 1000 rows from json with 1 query):

create table jt_test (
  CUST_NUM int, SORT_ORDER int, CATEGORY varchar2(100)
);
       
   [
            {"CUST_NUM": 12345, "SORT_ORDER": 1, "CATEGORY": "ICE CREAM"}
            {"CUST_NUM": 12345, "SORT_ORDER": 2, "CATEGORY": "ICE CREAM"}
            {"CUST_NUM": 12345, "SORT_ORDER": 3, "CATEGORY": "ICE CREAM"}
           ]

I use this tutorial and this for insert rows from json and that work perfect. But for update rows I have no idea. How can I do? Note: I use Oracle19C and connect and insert to db with cx_Oracle module python.

Code for Inserting by json to Oracle columns:

DECLARE 
  myJSON  varchar2(1000) := '[
  {"CUST_NUM": 12345, "SORT_ORDER": 1, "CATEGORY": "ICE CREAM"},
  {"CUST_NUM": 12345, "SORT_ORDER": 2, "CATEGORY": "ICE CREAM"},
  {"CUST_NUM": 12345, "SORT_ORDER": 3, "CATEGORY": "ICE CREAM"}
]';

BEGIN
  insert into jt_test
    select * from json_table ( myjson, '$[*]'
      columns ( 
        CUST_NUM, SORT_ORDER, CATEGORY
      )
    );
END; 
1
  • 2
    Use merge statement with JSON table as a source to insert/update rows in a table. But you also can convert this JSON into dict at the Python side and use executemany with bind variables to insert this data via plain insert ... values (...) Commented Aug 5, 2022 at 16:08

1 Answer 1

2

In SQL Developer use below code :

MERGE INTO jt_test destttt  using(  
SELECT  CUST_NUM,SORT_ORDER,CATEGORY FROM json_table  (
'[
  {"CUST_NUM": 12345, "SORT_ORDER": 1, "CATEGORY": "ICE CREAM"},
  {"CUST_NUM": 12345, "SORT_ORDER": 2, "CATEGORY": "ICE CREAM"},
  {"CUST_NUM": 12345, "SORT_ORDER": 3, "CATEGORY": "ICE CREAM"}
]'
,'$[*]'
       COLUMNS  
      CUST_NUM int PATH '$.CUST_NUM ',
      SORT_ORDER int PATH '$.SORT_ORDER ',
     CATEGORY varchar2  PATH '$.CATEGORY ' ) )  srccccc


  ON ( destttt.CUST_NUM= srccccc.CUST_NUM)
WHEN MATCHED THEN UPDATE SET destttt.CATEGORY=srccccc.CATEGORY

WHEN NOT MATCHED THEN INSERT ( CUST_NUM,SORT_ORDER,CATEGORY) VALUES (srccccc.CUST_NUM,srccccc.SORT_ORDER,srccccc.CATEGORY);

In python with cx_Oracle use below code :

 long_json_string = '''[
    {"CUST_NUM": 12345, "SORT_ORDER": 1, "CATEGORY": "ICE CREAM"},
    {"CUST_NUM": 12345, "SORT_ORDER": 2, "CATEGORY": "ICE CREAM"},
    {"CUST_NUM": 12345, "SORT_ORDER": 3, "CATEGORY": "ICE CREAM"}
  ]'''

sql = '''
    DECLARE      jsonvalue  CLOB :=  :long_json_string     ;  
    begin  
     MERGE INTO jt_test destttt  using(  
        SELECT  CUST_NUM,SORT_ORDER,CATEGORY FROM json_table  (jsonvalue
         
        ,'$[*]'
               COLUMNS  
              CUST_NUM int PATH '$.CUST_NUM',
              SORT_ORDER int PATH '$.SORT_ORDER',
             CATEGORY varchar2  PATH '$.CATEGORY' ) )  srccccc
        
        
          ON ( destttt.CUST_NUM= srccccc.CUST_NUM)
        WHEN MATCHED THEN UPDATE SET destttt.CATEGORY=srccccc.CATEGORY
        
        WHEN NOT MATCHED THEN INSERT ( CUST_NUM,SORT_ORDER,CATEGORY) VALUES (srccccc.CUST_NUM,srccccc.SORT_ORDER,srccccc.CATEGORY);
                '''
cursor.execute(sql, long_json_string=long_json_string)

Note1: Do not forget in end use commit.

Note 2: Make sure that the column you use as a comparison is not repeated in a json and causes deadlock.

Note 3: there is case sensitivity json keys, that is, CUST_NUM is different from cust_num and CUST_num and ...

Wrong : CUST_NUM int PATH '$.CUST_num' or CUST_NUM int PATH '$.cusr _num'

Ok: CUST_NUM int PATH '$.CUST_NUM'

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

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.