Oracle
 sql >> Base de données >  >> RDS >> Oracle

Comment modifier les BLOB (contenant JSON) dans Oracle SQL Developer ?

Si vous exécutez une requête dans SQL Developer 3.1 (et probablement des versions antérieures) qui renvoie un BLOB, vous pouvez double-cliquer sur le BLOB particulier qui vous intéresse où vous serez invité soit à essayer d'envoyer les données à un externe éditeur ou pour essayer de faire en sorte que le contrôle d'affichage intégré de SQL Developer tente d'interpréter les données sous forme d'image ou de texte. Vos données JSON s'afficheront probablement correctement si vous choisissez l'option texte.

Cependant, si vous souhaitez modifier les données, vous devrez émettre un UPDATE pour définir réellement les données. SQL Developer n'a pas la fonctionnalité pour modifier directement les données LOB. Par exemple

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

mettra à jour la ligne spécifiée avec les nouvelles données JSON codées à l'aide du jeu de caractères de la base de données. Si vous souhaitez stocker les données dans un autre jeu de caractères, string_to_raw prend un deuxième paramètre facultatif qui spécifie le jeu de caractères. Donc, si vous voulez stocker les données en utilisant le jeu de caractères UTF-8, vous feriez quelque chose comme ça

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

Bien sûr, étant donné que les données JSON sont textuelles, vous feriez bien mieux de stocker les données dans un CLOB conçu pour stocker des objets de grande taille. Ensuite, SQL Developer (et d'autres outils) pourrait simplement afficher le texte plutôt que de vous demander de sélectionner le résultat, puis de prendre des mesures supplémentaires pour le convertir en texte. Et vous n'auriez pas à convertir les données en RAW afin de mettre à jour les données dans la base de données.

Si les données sont trop longues pour string_to_raw à gérer (qui dépend du jeu de caractères et des données mais se produira à chaque fois que le RAW les données dépassent 2000 octets), vous pouvez stocker les données dans un CLOB puis convertissez-le en un BLOB que vous utilisez pour mettre à jour la table. C'est un peu plus complexe mais c'est plus flexible. Dans cet exemple, je remplis les données JSON à 3200 caractères avec un '*' - évidemment les données de test ne sont plus valides JSON mais ce n'est pas important pour les besoins de cette question.

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