Oracle
 sql >> Database >  >> RDS >> Oracle

Come posso modificare i BLOB (contenenti JSON) in Oracle SQL Developer?

Se esegui una query in SQL Developer 3.1 (e probabilmente versioni precedenti) che restituisce un BLOB, puoi fare doppio clic sul particolare BLOB che ti interessa dove ti verrà chiesto di provare a inviare i dati a un editor o per provare a fare in modo che il controllo di visualizzazione SQL Developer integrato tenti di interpretare i dati come un'immagine o come testo. I tuoi dati JSON verranno probabilmente visualizzati correttamente se scegli l'opzione di testo.

Se vuoi modificare i dati, tuttavia, dovrai emettere un UPDATE per impostare effettivamente i dati. SQL Developer non dispone della funzionalità per modificare direttamente i dati LOB. Ad esempio

UPDATE table_name
   SET column_with_json_data = 
          utl_i18n.string_to_raw( '{"foo": {"id": "1", "value": "2"}}' )
 WHERE primary_key = <<some value>>

aggiornerà la riga specificata con i nuovi dati JSON codificati utilizzando il set di caratteri del database. Se vuoi memorizzare i dati in qualche altro set di caratteri, string_to_raw accetta un secondo parametro facoltativo che specifica il set di caratteri. Quindi, se desideri archiviare i dati utilizzando il set di caratteri UTF-8, faresti qualcosa del genere

UPDATE table_name
   SET column_with_json_data = 
          utl_i18n.string_to_raw( '{"foo": {"id": "1", "value": "2"}}', 'AL32UTF8' )
 WHERE primary_key = <<some value>>

Naturalmente, poiché i dati JSON sono testuali, è molto meglio archiviare i dati in un CLOB progettato per archiviare oggetti di grandi dimensioni. Quindi SQL Developer (e altri strumenti) potrebbero semplicemente visualizzare il testo anziché richiedere di selezionare il risultato e quindi intraprendere azioni aggiuntive per convertirlo in testo. E non dovresti convertire i dati in RAW per aggiornare i dati nel database.

Se i dati sono troppo lunghi per string_to_raw da gestire (che dipende dal set di caratteri e dai dati ma si verificherà ogni volta che il RAW supera i 2000 byte), è possibile memorizzare i dati in un CLOB e poi convertilo in un BLOB che usi per aggiornare la tabella. È un po' più complesso ma è più flessibile. In questo esempio, sto riempiendo i dati JSON a 3200 caratteri con un '*'-- ovviamente i dati di test non sono più JSON validi ma non è importante ai fini di questa domanda.

declare
  l_blob        blob;
  l_clob        clob := rpad('{"foo": {"id": "1", "value": "2", "name": "bob"}}',3200,'*');
  l_amt         integer := dbms_lob.lobmaxsize;
  l_dest_offset integer := 1;
  l_src_offset  integer := 1;
  l_csid        integer := dbms_lob.default_csid;
  l_ctx         integer := dbms_lob.default_lang_ctx;
  l_warn        integer;
begin
  dbms_lob.createTemporary( l_blob, false );
  dbms_lob.convertToBlob( l_blob,
                          l_clob,
                          l_amt,
                          l_dest_offset,
                          l_src_offset,
                          l_csid,
                          l_ctx,
                          l_warn );

  -- You'll want to add a WHERE clause as well
  update json_data
     set data = l_blob;

  dbms_lob.freeTemporary( l_blob );
end;
/