From 7425e0d2c3dd8045e48fa2063534a61bfaeabbee Mon Sep 17 00:00:00 2001 From: "Simon C. Kessler" Date: Thu, 9 Apr 2026 09:42:29 +0200 Subject: [PATCH] cursor durch for-schleifen ersetzt --- database/packages/pck_auto_import.pkb | 103 +++++++++----------------- database/packages/pck_net_storage.pkb | 50 +++---------- database/packages/pck_net_storage.pkh | 2 +- 3 files changed, 46 insertions(+), 109 deletions(-) diff --git a/database/packages/pck_auto_import.pkb b/database/packages/pck_auto_import.pkb index aa47d43..13a116c 100644 --- a/database/packages/pck_auto_import.pkb +++ b/database/packages/pck_auto_import.pkb @@ -35,56 +35,39 @@ create or replace package body pck_auto_import as -- SCK 2026-04-08 Prozedur erstellt ------------------------------------------------------------------------------------------------Kopf*/ is - l_folder_cursor sys_refcursor; - l_file_cursor sys_refcursor; - l_check_cursor sys_refcursor; - -- Cursor-Felder für Unterordner - l_folder_name varchar2(1024); - l_dummy_size number; - l_dummy_modified date; - l_dummy_is_folder varchar2(1); - l_dummy_etag varchar2(256); - -- Cursor-Felder für Dateien - l_file_name varchar2(1024); - l_file_size number; - l_file_modified date; - l_file_is_folder varchar2(1); - l_file_etag varchar2(256); - -- Verarbeitungsvariablen - l_marker_key varchar2(1024); - l_target_folder varchar2(4000 char); - l_target_prefix varchar2(4000 char); - l_eingang_prefix varchar2 (4000 char); - l_zip_name varchar2(512); - l_file_content blob; - l_meta pck_net_storage.t_object_meta; - l_remaining number; - + l_marker_key varchar2(1024); + l_target_folder varchar2(4000 char); + l_target_prefix varchar2(4000 char); + l_eingang_prefix varchar2(4000 char); + l_zip_name varchar2(512); + l_file_content blob; + l_meta pck_net_storage.t_object_meta; + l_remaining number; + l_folders t_net_storage_tab; + l_files t_net_storage_tab; + l_check t_net_storage_tab; begin -- Zielordner Name zusammenstellen - l_target_prefix := pck_system.f_get_par_wert_by_programmid('NETSTORE_BA_PREFIX') || 'Verarbeitet ' || to_char(sysdate, 'YYYY') || '/'; + l_target_prefix := pck_system.f_get_par_wert_by_programmid('NETSTORE_BA_PREFIX') || 'Verarbeitet ' || to_char(sysdate, 'YYYY') || '/'; l_eingang_prefix := pck_system.f_get_par_wert_by_programmid('NETSTORE_BA_PREFIX') || pck_system.f_get_par_wert_by_programmid('NETSTORE_BA_IMPORT'); -- Unterordner in eingang/ auflisten (Delimiter '/' liefert nur direkte Kinder) - l_folder_cursor := pck_net_storage.f_list_objects( + l_folders := pck_net_storage.f_list_objects( i_prefix => l_eingang_prefix ,i_delimiter => '/' ); + for rec_folder in (select object_name, is_folder from table(l_folders)) loop - fetch l_folder_cursor - into l_folder_name, l_dummy_size, l_dummy_modified, l_dummy_is_folder, l_dummy_etag; - exit when l_folder_cursor%notfound; - -- Nur Unterordner verarbeiten - if l_dummy_is_folder != 'Y' + if rec_folder.is_folder != 'Y' then continue; end if; - -- Der Marker ist eine Datei mit speziellem Namen, welche vom quarkus automaton in einen entpackten zip-ordner gelegt wird um zu signalisieren, dass alle Dateien des ZIPs erfolgreich in den ordner gelegt wurden. + -- Der Marker ist eine Datei mit speziellem Namen, welche vom quarkus automaton in einen entpackten zip-ordner gelegt wird um zu signalisieren, dass alle Dateien des ZIPs erfolgreich in den ordner gelegt wurden. -- Das verhindert die verarbeitung von unvollständig entpackten zips - l_marker_key := l_folder_name || pck_system.f_get_par_wert_by_programmid('NETSTORE_MARKER_NAME'); + l_marker_key := rec_folder.object_name || pck_system.f_get_par_wert_by_programmid('NETSTORE_MARKER_NAME'); -- Marker prüfen: -20001 = nicht vorhanden → Upload noch nicht abgeschlossen begin @@ -101,40 +84,37 @@ create or replace package body pck_auto_import as -- Zip-Namen aus Ordnerpfad ableiten: eingang// → l_zip_name := substr( - l_folder_name + rec_folder.object_name ,length(l_eingang_prefix) + 1 - ,length(l_folder_name) - length(l_eingang_prefix) - 1 + ,length(rec_folder.object_name) - length(l_eingang_prefix) - 1 ); l_target_folder := l_target_prefix || l_zip_name || '/'; -- Alle Dateien im Unterordner auflisten (kein Delimiter = flach, alle Tiefen) - l_file_cursor := pck_net_storage.f_list_objects( - i_prefix => l_folder_name + l_files := pck_net_storage.f_list_objects( + i_prefix => rec_folder.object_name ,i_delimiter => '' ); + for rec_file in (select object_name, is_folder from table(l_files)) loop - fetch l_file_cursor - into l_file_name, l_file_size, l_file_modified, l_file_is_folder, l_file_etag; - exit when l_file_cursor%notfound; - -- Marker und Pseudo-Ordner überspringen - if l_file_name = l_marker_key or l_file_is_folder = 'Y' + if rec_file.object_name = l_marker_key or rec_file.is_folder = 'Y' then continue; end if; begin -- 1. Dateiinhalt laden - l_file_content := pck_net_storage.f_download_object(l_file_name); + l_file_content := pck_net_storage.f_download_object(rec_file.object_name); -- 2. Fachliche Verarbeitung (noch kein Commit) - p_import_file(l_file_name, l_file_content); + p_import_file(rec_file.object_name, l_file_content); -- 3. Datei in Zielordner verschieben (noch kein Commit) -- Rollback von p_move_object macht auch den Import rückgängig pck_net_storage.p_move_object( - i_object_key => l_file_name + i_object_key => rec_file.object_name ,i_target_prefix => l_target_folder ); @@ -144,7 +124,7 @@ create or replace package body pck_auto_import as i_module => c_module ,i_action => 'IMPORT_FILE' ,i_message => 'Datei erfolgreich verarbeitet' - ,i_object_ref => l_file_name + ,i_object_ref => rec_file.object_name ); exception when others @@ -155,34 +135,27 @@ create or replace package body pck_auto_import as ,i_action => 'IMPORT_FILE' ,i_message => 'Fehler bei Dateiverarbeitung: ' || sqlerrm ,i_detail => to_clob(dbms_utility.format_error_backtrace) - ,i_object_ref => l_file_name + ,i_object_ref => rec_file.object_name ); end; end loop; - close l_file_cursor; - -- Prüfen ob noch nicht verarbeitete Dateien im Unterordner verbleiben l_remaining := 0; - l_check_cursor := pck_net_storage.f_list_objects( - i_prefix => l_folder_name + l_check := pck_net_storage.f_list_objects( + i_prefix => rec_folder.object_name ,i_delimiter => '' ); + for rec_check in (select object_name, is_folder from table(l_check)) loop - fetch l_check_cursor - into l_file_name, l_file_size, l_file_modified, l_file_is_folder, l_file_etag; - exit when l_check_cursor%notfound; - - if l_file_name != l_marker_key and l_file_is_folder = 'N' + if rec_check.object_name != l_marker_key and rec_check.is_folder = 'N' then l_remaining := l_remaining + 1; end if; end loop; - close l_check_cursor; - -- Marker löschen wenn Batch vollständig abgeschlossen if l_remaining = 0 then @@ -192,20 +165,10 @@ create or replace package body pck_auto_import as i_module => c_module ,i_action => 'PROCESS_INCOMING' ,i_message => 'Batch abgeschlossen, Marker gelöscht' - ,i_object_ref => l_folder_name + ,i_object_ref => rec_folder.object_name ); end if; end loop; - - close l_folder_cursor; - - exception - when others - then - if l_folder_cursor%isopen then close l_folder_cursor; end if; - if l_file_cursor%isopen then close l_file_cursor; end if; - if l_check_cursor%isopen then close l_check_cursor; end if; - raise; end p_process_incoming_ba_data; end pck_auto_import; diff --git a/database/packages/pck_net_storage.pkb b/database/packages/pck_net_storage.pkb index 785dc9f..1f8f481 100644 --- a/database/packages/pck_net_storage.pkb +++ b/database/packages/pck_net_storage.pkb @@ -140,7 +140,7 @@ create or replace package body pck_net_storage as ,i_delimiter in varchar2 ,i_start_with in varchar2 ,i_limit in number - ) return sys_refcursor + ) return t_net_storage_tab /*Kopf------------------------------------------------------------------------------------------------ -- Beschreibung: Listet Objekte und Unterordner im Bucket ohne Rechte- oder Scope-Prüfung. -- Paginiert automatisch über nextStartWith bis alle Ergebnisse geladen sind. @@ -151,7 +151,7 @@ create or replace package body pck_net_storage as -- i_start_with Optionaler Startpunkt für Paginierung -- i_limit Maximale Anzahl Ergebnisse (0 = unbegrenzt) ------------------------------------------------------------------------------------------------------ - -- Rückgabe: Ref Cursor mit Spalten (object_name, object_size, last_modified, is_folder, etag) + -- Rückgabe: Collection t_net_storage_tab mit allen gefundenen Objekten ------------------------------------------------------------------------------------------------------ -- MA Datum Änderung -- SCK 2026-04-08 Funktion erstellt @@ -161,7 +161,6 @@ create or replace package body pck_net_storage as l_response clob; l_result t_net_storage_tab := t_net_storage_tab(); l_next_start varchar2(1024); - l_cursor sys_refcursor; l_count number := 0; l_done boolean := false; l_cur_start varchar2(1024) := i_start_with; @@ -256,15 +255,7 @@ create or replace package body pck_net_storage as end if; end loop; - open l_cursor for - select t.object_name - ,t.object_size - ,t.last_modified - ,t.is_folder - ,t.etag - from table(l_result) t; - - return l_cursor; + return l_result; end f_list_objects_internal; -- ==================== Öffentliche Funktionen ==================== @@ -274,7 +265,7 @@ create or replace package body pck_net_storage as ,i_delimiter in varchar2 default '/' ,i_start_with in varchar2 default null ,i_limit in number default 0 - ) return sys_refcursor + ) return t_net_storage_tab /*Kopf------------------------------------------------------------------------------------------------ -- Beschreibung: Listet Objekte und Unterordner im Bucket mit Rechteprüfung und Scope-Validierung. ------------------------------------------------------------------------------------------------------ @@ -283,7 +274,7 @@ create or replace package body pck_net_storage as -- i_start_with Optionaler Startpunkt für Paginierung -- i_limit Maximale Anzahl Ergebnisse (0 = unbegrenzt) ------------------------------------------------------------------------------------------------------ - -- Rückgabe: Ref Cursor mit Spalten (object_name, object_size, last_modified, is_folder, etag) + -- Rückgabe: Collection t_net_storage_tab mit allen gefundenen Objekten ------------------------------------------------------------------------------------------------------ -- MA Datum Änderung -- SCK 2026-04-08 Funktion erstellt @@ -396,48 +387,31 @@ create or replace package body pck_net_storage as -- SCK 2026-04-08 Prozedur erstellt ------------------------------------------------------------------------------------------------Kopf*/ is - l_cursor sys_refcursor; - l_object_name varchar2(1024); - l_object_size number; - l_last_modified date; - l_is_folder varchar2(1); - l_etag varchar2(256); - l_response clob; + l_objects t_net_storage_tab; + l_response clob; begin pck_mitarbeiterrecht.p_hat_recht('ADMIN'); p_assert_allowed(i_prefix); -- Alle Objekte im Prefix auflisten (kein Delimiter = rekursiv, alle Tiefen) - l_cursor := f_list_objects_internal( + l_objects := f_list_objects_internal( i_prefix => i_prefix ,i_delimiter => '' ,i_start_with => null ,i_limit => 0 ); + -- Nur echte Objekte löschen, keine Pseudo-Ordner + for rec in (select object_name, is_folder from table(l_objects)) loop - fetch l_cursor into l_object_name, l_object_size, l_last_modified, l_is_folder, l_etag; - exit when l_cursor%notfound; - - -- Nur echte Objekte löschen, keine Pseudo-Ordner - if l_is_folder = 'N' + if rec.is_folder = 'N' then l_response := f_make_request( i_method => 'DELETE' - ,i_url => f_build_url(l_object_name) + ,i_url => f_build_url(rec.object_name) ); end if; end loop; - - close l_cursor; - exception - when others - then - if l_cursor%isopen - then - close l_cursor; - end if; - raise; end p_delete_folder; procedure p_rename_object ( diff --git a/database/packages/pck_net_storage.pkh b/database/packages/pck_net_storage.pkh index 7dd7bb4..8623f87 100644 --- a/database/packages/pck_net_storage.pkh +++ b/database/packages/pck_net_storage.pkh @@ -14,7 +14,7 @@ create or replace package pck_net_storage as ,i_delimiter in varchar2 default '/' ,i_start_with in varchar2 default null ,i_limit in number default 0 - ) return sys_refcursor; + ) return t_net_storage_tab; function f_download_object ( i_object_key in varchar2