фонКак я могу создать весь блок кода PL/SQL с переменными привязки?
Я пытаюсь сделать PL процедуру/SQL многоразовой для перемещения данных из одной базы данных в другую.
Для этой цели я использую динамический SQL.
Процедура выполняется отлично, если я использую REPLACE с заполнителями. Однако из соображений безопасности я хочу использовать переменные связывания.
Вопрос
Как я могу сделать весь PL/SQL блок кода динамический (с связываемых переменных)? Если я использую REPLACE вместо переменных привязки, он отлично работает .
Как реплицировать
Чтобы повторить это в вашей базе данных, создайте следующую процедуру, как это:
create or replace procedure move_data(i_schema_name in varchar2, i_table_name in varchar2, i_destination in varchar2) as
l_sql varchar2(32767);
l_cursor_limit pls_integer := 500;
l_values_list varchar2(32767);
begin
select listagg('l_to_be_moved(i).' || column_name, ', ') within group (order by column_id)
into l_values_list
from all_tab_cols
where owner = i_schema_name and
table_name = i_table_name and
virtual_column = 'NO';
l_sql := q'[
declare
l_cur_limit pls_integer := :l_cursor_limit;
cursor c_get_to_be_moved is
select :i_table_name.*, :i_table_name.rowid
from :i_table_name;
type tab_to_be_moved is table of c_get_to_be_moved%rowtype;
l_to_be_moved tab_to_be_moved;
begin
open c_get_to_be_moved;
loop
fetch c_get_to_be_moved
bulk collect into l_to_be_moved limit l_cur_limit;
exit when l_to_be_moved.count = 0;
for i in 1.. l_to_be_moved.count loop
begin
insert into :[email protected]:i_destination values (:l_values_list);
exception
when others then
dbms_output.put_line(sqlerrm);
l_to_be_moved.delete(i);
end;
end loop;
forall i in 1.. l_to_be_moved.count
delete
from :i_table_name
where rowid = l_to_be_moved(i).rowid;
for i in 1..l_to_be_moved.count loop
if (sql%bulk_rowcount(i) = 0) then
raise_application_error(-20001, 'Could not find ROWID to delete. Rolling back...');
end if;
end loop;
commit;
end loop;
close c_get_to_be_moved;
exception
when others then
rollback;
dbms_output.put_line(sqlerrm);
end;]';
execute immediate l_sql using l_cursor_limit, i_table_name, i_destination, l_values_list;
exception
when others then
rollback;
dbms_output.put_line(sqlerrm);
end;
/
И тогда вы можете выполнить процедура со следующим:
begin
move_data('MySchemaName', 'MyTableName', 'MyDatabaseLinkName');
end;
/
Идентификаторы (имя таблицы, имя схемы и т. Д.) Не могут быть связаны. –
@NicholasKrasnov Спасибо! Наверное, я просто проверю входные переменные. Не могли бы вы поместить то же самое, что и ответ, чтобы я мог закрыть это? – Zesty