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

Busque y reemplace la cadena dentro de BLOB para Work o Excel File

Los archivos de Microsoft Word y Excel no son archivos de texto en los que simplemente puede reemplazar el texto y que definitivamente no funcionarán con un BLOB . docx y xlsx Los archivos son en realidad archivos zip (intente cambiar la extensión del archivo y descomprimirlo para verlo por sí mismo) que contienen una definición XML del documento. Entonces necesitarás:

  1. Descomprimir el archivo
  2. Convierta el archivo que necesita cambiarse de un BLOB a un CLOB
  3. Modificar el contenido del archivo XML adecuado
  4. Convertir el archivo de nuevo a un BLOB de un CLOB
  5. Vuelva a agregar el archivo modificado al archivo zip

He escrito el siguiente código como ejemplo de cómo reemplazar un docx expediente. Para xlsx archivos, cada hoja de Excel está contenida en un archivo XML diferente, por lo que deberá modificar el código ligeramente para que funcione con ambos tipos de archivos.

El código utiliza APEX_ZIP paquete que simplifica enormemente el trabajo con archivos zip y también hace que el código de ejemplo sea un poco más claro en cuanto a lo que está sucediendo. Si no tiene APEX instalado, deberá descubrir cómo descomprimir/volver a comprimir los archivos utilizando los paquetes de Oracle que tiene.

DECLARE
    l_old_file       BLOB;
    l_new_file       BLOB;
    l_files          apex_zip.t_files;
    l_document       BLOB;
    l_clob           CLOB;
    l_dest_offsset   INTEGER;
    l_src_offsset    INTEGER;
    l_lang_context   INTEGER := DBMS_LOB.default_lang_ctx;
    l_warning        INTEGER;
BEGIN
    -- Get the blob you want to "correct"
    SELECT blob_content
      INTO l_old_file
      FROM apex_application_temp_files
     WHERE ROWNUM = 1;

    -- Get a list of all the file names contained within the zip
    l_files := apex_zip.get_files (l_old_file);

    -- Loop through all the files adding each one to the new zip
    FOR i IN l_files.FIRST .. l_files.LAST
    LOOP
        l_document := apex_zip.get_file_content (l_old_file, l_files (i));

        IF l_files (i) = 'word/document.xml'
        THEN
            -- if the file name is word/document.xml then make the changes to it
            
            DBMS_LOB.createTemporary (lob_loc => l_clob, cache => FALSE);

            l_dest_offsset := 1;
            l_src_offsset := 1;

            DBMS_LOB.converttoclob (dest_lob       => l_clob,
                                    src_blob       => l_document,
                                    amount         => DBMS_LOB.lobmaxsize,
                                    dest_offset    => l_dest_offsset,
                                    src_offset     => l_src_offsset,
                                    blob_csid      => DBMS_LOB.default_csid,
                                    lang_context   => l_lang_context,
                                    warning        => l_warning);

            --------------------
            -- This is where you would do any replacements
            --------------------
            l_clob := REPLACE (l_clob, 'www.google.co.uk', 'www.google.com');
            --------------------

            l_dest_offsset := 1;
            l_src_offsset := 1;

            DBMS_LOB.CONVERTTOBLOB (dest_lob       => l_document,
                                    src_clob       => l_clob,
                                    amount         => DBMS_LOB.lobmaxsize,
                                    dest_offset    => l_dest_offsset,
                                    src_offset     => l_src_offsset,
                                    blob_csid      => DBMS_LOB.default_csid,
                                    lang_context   => l_lang_context,
                                    warning        => l_warning);
        END IF;

        apex_zip.add_file (l_new_file, l_files (i), l_document);
    END LOOP;

    apex_zip.finish (l_new_file);
    --Do whatever you want with the "new" file here
END;