Адаптация вашего анонима к хранимой процедуре, как указано, потребует преобразования его в динамический c SQL. Всегда сложнее. И при условии SQL впрыска. Для этого вы должны проверить параметры замены строки. У меня есть пара других изменений:
- Передайте желаемое как метку времени, а не строку, это позволяет / заставляет вызывающую процедуру определять формат и необходимое преобразование, если таковое имеется.
- Также добавлен параметр для имени столбца. Это освобождает именование столбцов от требований процедуры.
- Нет необходимости подсчитывать оставшиеся элементы. Ваш l oop обрабатывает, пока это значение не достигнет 0, но это может быть определено количеством строк, удаленных на последнем проходе. Удалить устанавливает sql% rowcount равным количеству удаленных строк. Когда проход удаляет 0 строк, процесс завершается.
- Удалено отображение результатов и фиксация из процедуры, снова передавая это вызывающей стороне.
create or replace
procedure delete_values_by_timestamp
( p_table_name in varchar2
, p_column_name in varchar2
, p_timestamp in timestamp
, p_result_msg out varchar2
)
IS
table_name_parameter_invalid exception;
pragma exception_init(table_name_parameter_invalid, -44002);
column_name_parameter_invalid exception;
pragma exception_init(column_name_parameter_invalid, -44003);
k_nl constant varchar2(1) := chr(10);
k_max_delete_per_interation constant integer := 100000;
k_base_delete varchar2(256) :=
'delete from <table_name>' ||
' where <column_name> <= :1' ||
' and rownum <= :2';
v_delete_sql varchar2 (256) ;
v_rows_deleted integer := 0;
begin
v_delete_sql := replace(replace(k_base_delete,'<table_name>', dbms_assert.sql_object_name(p_table_name))
,'<column_name>',dbms_assert.simple_sql_name(p_column_name));
dbms_output.put_line('Running SQL:' || k_nl || v_delete_sql);
loop
execute immediate v_delete_sql using p_timestamp, k_max_delete_per_interation;
exit when sql%rowcount = 0;
v_rows_deleted :=v_rows_deleted + sql%rowcount;
end loop;
if v_rows_deleted = 0
then
p_result_msg := 'No Data Found';
else
p_result_msg := 'Number of Rows Deleted ' || to_char(v_rows_deleted);
end if;
exception
when table_name_parameter_invalid then
raise_application_error(-20199,'Invalid Table Name (' || p_table_name || ') specified.');
when column_name_parameter_invalid then
raise_application_error(-20198,'Invalid Column Name (' || p_column_name || ') specified.');
end delete_values_by_timestamp;
См. пример : В этом примере я уменьшаю количество строк, удаляемых на каждой итерации, со 100000 до 20. Дополнительным усовершенствованием будет передача количества строк для каждой итерации в качестве параметра.