sql >> Database >  >> RDS >> Oracle

Zoek en vervang string in BLOB for Work of Excel File

Microsoft Word- en Excel-bestanden zijn geen tekstbestanden waar je gewoon tekst op kunt vervangen en die zeker niet werken met een BLOB . docx en xlsx bestanden zijn eigenlijk zip-bestanden (probeer de bestandsextensie te wijzigen en uit te pakken om het zelf te zien) die een XML-definitie van het document bevatten. U moet dus:

  1. Pak het bestand uit
  2. Converteer het bestand dat moet worden gewijzigd van een BLOB naar een CLOB
  3. Wijzig de inhoud van het juiste XML-bestand
  4. Converteer het bestand terug naar een BLOB van een CLOB
  5. Voeg het gewijzigde bestand weer toe aan het zipbestand

Ik heb de onderstaande code geschreven als voorbeeld voor het vervangen van een docx het dossier. Voor xlsx bestanden, is elk Excel-blad opgenomen in een ander XML-bestand, dus u moet de code enigszins aanpassen om het met beide bestandstypen te laten werken.

De code gebruikt de APEX_ZIP pakket dat het werken met zip-bestanden aanzienlijk vereenvoudigt en ook de voorbeeldcode een beetje duidelijker maakt over wat er aan de hand is. Als u APEX niet hebt geïnstalleerd, moet u uitzoeken hoe u de bestanden kunt uitpakken/opnieuw inpakken met behulp van de Oracle-pakketten die u heeft.

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;



  1. ORA-00942:tabel of weergave bestaat niet (ColdFusion-toepassing)

  2. Oracle SQL:filteren op ROWNUM geeft geen resultaten wanneer het zou moeten

  3. Database-mirroring / Postgres-streamingreplicatie

  4. Oracle-query geeft fout