sql >> Base de Datos >  >> RDS >> Oracle

¿Cómo edito BLOB (que contienen JSON) en Oracle SQL Developer?

Si ejecuta una consulta en SQL Developer 3.1 (y probablemente versiones anteriores) que devuelve un BLOB, puede hacer doble clic en el BLOB en particular que le interesa donde se le pedirá que intente enviar los datos a un editor o intentar que el control de visualización incorporado de SQL Developer intente interpretar los datos como una imagen o como texto. Sus datos JSON probablemente se mostrarán correctamente si elige la opción de texto.

Sin embargo, si desea cambiar los datos, tendrá que emitir un UPDATE para establecer realmente los datos. SQL Developer no tiene la funcionalidad para editar directamente los datos LOB. Por ejemplo

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

actualizará la fila especificada con los nuevos datos JSON codificados con el conjunto de caracteres de la base de datos. Si desea almacenar los datos en algún otro juego de caracteres, string_to_raw toma un segundo parámetro opcional que especifica el conjunto de caracteres. Entonces, si desea almacenar los datos usando el conjunto de caracteres UTF-8, haría algo como esto

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

Por supuesto, dado que los datos JSON son textuales, sería mucho mejor almacenar los datos en un CLOB que está diseñado para almacenar objetos grandes de caracteres. Luego, SQL Developer (y otras herramientas) podrían simplemente mostrar el texto en lugar de pedirle que seleccione el resultado y luego realice acciones adicionales para convertirlo en texto. Y no tendría que convertir los datos a RAW para actualizar los datos en la base de datos.

Si los datos son demasiado largos para string_to_raw manejar (que depende del conjunto de caracteres y los datos, pero ocurrirá en cualquier momento en que RAW los datos superan los 2000 bytes), puede almacenar los datos en un CLOB y luego convertir eso en un BLOB que utiliza para actualizar la tabla. Eso es un poco más complejo pero es más flexible. En este ejemplo, estoy rellenando los datos JSON a 3200 caracteres con un '*'; obviamente, los datos de prueba ya no son JSON válidos, pero eso no es importante para los fines de esta pregunta.

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