我有一个存储过程,当前输出一个包含 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。但现在他们要求我更改为每千条记录生成一个文件。
如何实现这个目标?
下面是为处理您的任务而修改的代码。它未经测试,但您应该了解总体思路。我希望我能提供帮助。
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.extend(1);
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_rows(l_counter));
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;