Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Como faço para editar BLOBs (contendo JSON) no Oracle SQL Developer?


Se você executar uma consulta no SQL Developer 3.1 (e provavelmente em versões anteriores) que retorna um BLOB, você pode clicar duas vezes no BLOB específico em que está interessado, onde será solicitado a tentar enviar os dados para um editor ou tentar fazer com que o controle de exibição do SQL Developer interno tente interpretar os dados como uma imagem ou como texto. Seus dados JSON provavelmente serão exibidos corretamente se você escolher a opção de texto.

No entanto, se você quiser alterar os dados, precisará emitir um UPDATE para realmente definir os dados. O SQL Developer não tem a funcionalidade de editar diretamente os dados LOB. Por exemplo
UPDATE table_name
   SET column_with_json_data = 
          utl_i18n.string_to_raw( '{"foo": {"id": "1", "value": "2"}}' )
 WHERE primary_key = <<some value>>

atualizará a linha especificada com os novos dados JSON codificados usando o conjunto de caracteres do banco de dados. Se você deseja armazenar os dados em algum outro conjunto de caracteres, string_to_raw recebe um segundo parâmetro opcional que especifica o conjunto de caracteres. Então, se você quiser armazenar os dados usando o conjunto de caracteres UTF-8, faça algo assim
UPDATE table_name
   SET column_with_json_data = 
          utl_i18n.string_to_raw( '{"foo": {"id": "1", "value": "2"}}', 'AL32UTF8' )
 WHERE primary_key = <<some value>>

Obviamente, como os dados JSON são textuais, seria muito melhor armazenar os dados em um CLOB projetado para armazenar objetos grandes de caracteres. Em seguida, o SQL Developer (e outras ferramentas) poderia apenas exibir o texto em vez de exigir que você selecione o resultado e, em seguida, execute ações adicionais para convertê-lo em texto. E você não precisaria converter os dados para RAW para atualizar os dados no banco de dados.

Se os dados forem muito longos para string_to_raw manipular (o que depende do conjunto de caracteres e dos dados, mas ocorrerá sempre que o RAW dados excedem 2000 bytes), você pode armazenar os dados em um CLOB e, em seguida, converta isso em um BLOB que você usa para atualizar a tabela. Isso é um pouco mais complexo, mas é mais flexível. Neste exemplo, estou preenchendo os dados JSON para 3200 caracteres com um '*' -- obviamente, os dados de teste não são mais JSON válidos, mas isso não é importante para os propósitos desta pergunta.
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;
/