如何将表中的信息分成 100,000 条记录的 Oracle Sql 组

问题描述 投票:0回答:1

我有一个存储过程,当前输出一个包含 csv 的 zip 文件,这可以正常工作。

CREATE OR REPLACE PROCEDURE generate_fbdi_sp (
        p_id_proceso_oic  IN VARCHAR2,
        p_source          IN VARCHAR2,
        p_file_reference  IN VARCHAR2,
        out_result        OUT VARCHAR2,
        out_message       OUT VARCHAR2
    ) IS
    --Query when all categories were found
        CURSOR c_csv_fbdi IS
        SELECT
            status_code
            || ','
            || ledger_id
            || ','
            || effective_date_of_transaction
            || ','
            || journal_source
            || ','
            || journal_category
            || ','
            || currency_code
            || ','
            || journal_entry_creation_date
            || CHR(10) AS linea
        FROM
            int_dat_journals_fbdi_layout
        WHERE
                journal_source = p_source
            AND id_proceso_oic = p_id_proceso_oic;
            
        --variables
        v_csv_line      CLOB;
        g_zipped_blob   BLOB;
        v_blob_csv_line BLOB;
    BEGIN
    
    --Iterate lines to create CSV File into CLOB variable 'v_csv_line'
    FOR curr_line IN c_csv_fbdi LOOP
        v_csv_line := v_csv_line || curr_line.linea;
    END LOOP;
    
    --Convert csv clob variable 'v_csv_line' to blob into variable 'v_blob_csv_line'
    SELECT
      clob_to_blob_fn(v_csv_line)
    INTO v_blob_csv_line
    FROM
    dual;
    
    --Zip FBDI file
    as_zip.add1file(g_zipped_blob, 'GlInterface_'
                                   || replace(p_source, ' ', '_')
                                   || '_'
                                   || p_id_proceso_oic
                                   || '.csv', v_blob_csv_line);
                                   
    --Close zip file
    as_zip.finish_zip(g_zipped_blob);
    
    --Insert csv file
        INSERT INTO journals_fbdi (
            file_name,
            file_content,
            id_proceso_oic,
            file_name_cv027,
            source
        ) VALUES (
            'FBDI_'
            || replace(p_source, ' ', '_')
            || '_'
            || p_id_proceso_oic
            || '.zip',
            g_zipped_blob,
            p_id_proceso_oic,
            p_file_reference,
            p_source
        );

        COMMIT;
    EXCEPTION
        WHEN OTHERS THEN
            out_result := 'ERROR: ' || sqlerrm;
            out_message := dbms_utility.format_error_backtrace;
    END;

当前该过程从表中获取所有记录(例如,单个文件中可以有 5000 条记录......)并生成 CSV。但现在他们要求我更改它以每千条记录生成一个文件。

如何实现这个目标?

oracle stored-procedures plsql plsqldeveloper
1个回答
0
投票

下面是为处理您的任务而修改的代码。它未经测试,但您应该了解总体思路。我希望我能提供帮助。

CREATE OR REPLACE PROCEDURE generate_fbdi_sp (
    p_id_proceso_oic   IN     VARCHAR2,
    p_source           IN     VARCHAR2,
    p_file_reference   IN     VARCHAR2,
    out_result            OUT VARCHAR2,
    out_message           OUT VARCHAR2)
IS
    --Query when all categories were found
    CURSOR c_csv_fbdi IS
        SELECT    status_code
               || ','
               || ledger_id
               || ','
               || effective_date_of_transaction
               || ','
               || journal_source
               || ','
               || journal_category
               || ','
               || currency_code
               || ','
               || journal_entry_creation_date
               || CHR (10)    AS linea
          FROM int_dat_journals_fbdi_layout
         WHERE     journal_source = p_source
               AND id_proceso_oic = p_id_proceso_oic;

    --variables
    v_csv_line                CLOB;
    g_zipped_blob             BLOB;

    --    v_blob_csv_line           BLOB;

    TYPE clob_rows IS TABLE OF CLOB;

    v_indx                    NUMBER := 1; -- index used for the collection of clob rows
    v_csv_line_rows           clob_rows;               -- your clob collection
    v_record_counter          NUMBER := 0;
    v_record_limit   CONSTANT NUMBER := 1000; -- You don't need this but it helps if you want to quickly change the requirement later.
BEGIN
    --Iterate lines to create CSV File into CLOB variable 'v_csv_line'
    FOR curr_line IN c_csv_fbdi
    LOOP
        v_record_counter := v_record_counter + 1;

        v_csv_line := v_csv_line || curr_line.linea;

        IF v_record_counter = v_record_limit -- You could just call the file creation here and not deal with a row collection
        THEN
            v_csv_line_rows (v_indx) := v_csv_line;
            v_indx := v_indx + 1;
            v_csv_line := NULL;
            v_record_counter := 0;
        END IF;
    END LOOP;

    -- Adding this to catch the last set of rows. Say you had 1200, the above would have only captured the first 1000. This gets the stranglers.
    IF v_record_counter > 0
    THEN
        v_csv_line_rows (v_indx) := v_csv_line;
    END IF;

    -- I am using a new block to keep this all in one procedure, but I would break this whole thing up into differnt fncs and procedures with their own purpose like gathering the data, converting to blob and then out putting the file.
    -- For now, this should give you an idea of what to do and then you can worry about organizing it better later.

    DECLARE
        l_counter         NUMBER;
        l_blob_csv_line   BLOB;
        l_file_name       VARCHAR2 (32767);
    BEGIN
        l_clounter := v_csv_line_rows.FIRST;

        WHILE (l_clounter IS NOT NULL)
        LOOP
            --Convert csv clob variable 'v_csv_line' to blob into variable 'v_blob_csv_line'
            l_blob_csv_line := clob_to_blob_fn (v_csv_line);

            l_file_name :=
                   'GlInterface_'
                || REPLACE (p_source, ' ', '_')
                || '_'
                || p_id_proceso_oic
                || '_'
                || l_clounter -- Adding the counter to file name for uniqueness.
                || '.csv';

            --Zip FBDI file
            as_zip.add1file (g_zipped_blob, l_file_name, l_blob_csv_line);

            l_clounter := v_csv_line_rows (l_clounter).NEXT; -- When you hit the last record, this returns NULL which is what stops the loop.
        END LOOP;
    END;

    --Close zip file
    as_zip.finish_zip (g_zipped_blob);

    --Insert csv file
    INSERT INTO journals_fbdi (file_name,
                               file_content,
                               id_proceso_oic,
                               file_name_cv027,
                               source)
             VALUES (
                           'FBDI_'
                        || REPLACE (p_source, ' ', '_')
                        || '_'
                        || p_id_proceso_oic
                        || '.zip',
                        g_zipped_blob,
                        p_id_proceso_oic,
                        p_file_reference,
                        p_source);

    COMMIT;
EXCEPTION
    WHEN OTHERS
    THEN
        out_result := 'ERROR: ' || SQLERRM;
        out_message := DBMS_UTILITY.format_error_backtrace;
END;

© www.soinside.com 2019 - 2024. All rights reserved.