Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Wie bearbeite ich BLOBs (mit JSON) in Oracle SQL Developer?

Wenn Sie in SQL Developer 3.1 (und wahrscheinlich früheren Versionen) eine Abfrage ausführen, die ein BLOB zurückgibt, können Sie auf das bestimmte BLOB, an dem Sie interessiert sind, doppelklicken, wo Sie aufgefordert werden, entweder zu versuchen, die Daten an einen externen zu senden Editor oder um zu versuchen, dass das integrierte SQL Developer-Anzeigesteuerelement versucht, die Daten als Bild oder als Text zu interpretieren. Ihre JSON-Daten werden wahrscheinlich korrekt angezeigt, wenn Sie die Textoption wählen.

Wenn Sie die Daten jedoch ändern möchten, müssen Sie ein UPDATE ausgeben um die Daten tatsächlich einzustellen. SQL Developer verfügt nicht über die Funktionalität zum direkten Bearbeiten der LOB-Daten. Zum Beispiel

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

aktualisiert die angegebene Zeile mit den neuen JSON-Daten, die mit dem Datenbankzeichensatz codiert sind. Wenn Sie die Daten in einem anderen Zeichensatz speichern möchten, string_to_raw akzeptiert einen optionalen zweiten Parameter, der den Zeichensatz angibt. Wenn Sie also die Daten im UTF-8-Zeichensatz speichern möchten, gehen Sie so vor:

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

Da JSON-Daten textuell sind, sollten Sie die Daten natürlich viel besser in einem CLOB speichern, das zum Speichern von zeichengroßen Objekten ausgelegt ist. Dann könnte SQL Developer (und andere Tools) einfach den Text anzeigen, anstatt dass Sie das Ergebnis auswählen und dann zusätzliche Aktionen ausführen müssen, um es in Text umzuwandeln. Und Sie müssten die Daten nicht in RAW konvertieren um die Daten in der Datenbank zu aktualisieren.

Wenn die Daten für string_to_raw zu lang sind zu handhaben (was vom Zeichensatz und den Daten abhängt, aber immer auftreten wird, wenn die RAW Daten größer als 2000 Bytes), können Sie die Daten in einem CLOB speichern und dann in ein BLOB umwandeln die Sie verwenden, um die Tabelle zu aktualisieren. Das ist etwas komplexer, aber flexibler. In diesem Beispiel fülle ich die JSON-Daten mit einem „*“ auf 3200 Zeichen auf – offensichtlich handelt es sich bei den Testdaten nicht mehr um gültiges JSON, aber das ist für die Zwecke dieser Frage nicht wichtig.

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;
/