В данном конкретном случае разделение - это долгий путь к цели.Учитывая, что в целевой таблице может быть много столбцов (да, 5 - это слишком много для обработки каждого из них в отдельной переменной), я бы предложил использовать словарь схемы, чтобы добавить немного гибкости.
Давайтепосмотрите на процедуру, которая принимает два параметра: имя таблицы и строку, содержащую список значений, разделенных запятыми.Здесь предполагается, что в таблице есть только строковые, числовые и временные столбцы.Для реализации полной версии добавьте обработку всех необходимых типов данных в начале процедуры.
Обратите внимание, что в середине мы разбиваем строку на таблицу подстрок с использованием стандартного подхода SQL:
select level as column_id,
REGEXP_SUBSTR(pi_values_list, '[^,]+', 1, level) as column_val
from dual connect by REGEXP_SUBSTR(pi_values_list, '[^,]+', 1, level) is not null;
Вот вся процедура:
create or replace procedure myInsertInto(pi_table_name char,
pi_values_list char)
is
v_statement varchar2(30000) := 'INSERT INTO %TABLE_NAME% (%COLUMNS_LIST%) VALUES (%VALUES_LIST%)';
v_columns_list varchar2(10000);
v_values_list varchar2(10000);
begin
SELECT LISTAGG(T.column_name, ',') within group (order by T.column_id) ,
LISTAGG( -- implement specific types handling here
CASE
WHEN S.column_val IS NULL
THEN 'NULL'
WHEN T.data_type = 'NUMBER'
THEN S.column_val
WHEN T.data_type IN ('DATE', 'TIMESTAMP')
THEN 'TIMESTAMP ''' || S.column_val || ''''
WHEN T.data_type like '%CHAR%'
THEN '''' || S.column_val || ''''
ELSE 'NULL'
END,
',') within group (order by T.column_id)
into v_columns_list,
v_values_list
from user_tab_cols T,
(select level as column_id, REGEXP_SUBSTR(pi_values_list, '[^,]+', 1, level) as column_val
from dual connect by REGEXP_SUBSTR(pi_values_list, '[^,]+', 1, level) is not null) S
where T.table_name = pi_table_name
and T.column_id = S.column_id;
if v_columns_list IS NULL then
raise_application_error(-20000, 'Not found columns for table ' || pi_table_name);
end if;
-- finalizing the statement
v_statement := replace(v_statement, '%TABLE_NAME%', pi_table_name);
v_statement := replace(v_statement, '%COLUMNS_LIST%', v_columns_list);
v_statement := replace(v_statement, '%VALUES_LIST%', v_values_list);
execute immediate v_statement;
end;
/
Затем используйте это так
create table MY_TABLE (
col_a VARCHAR2(10),
col_b NUMBER,
col_c VARCHAR2(10),
col_d DATE,
col_E VARCHAR2(10) default 'DEFAULT'
);
begin
myInsertInto('MY_TABLE', 'abc,123,xyz,2018-01-02 23:01:10,pqr' );
myInsertInto('MY_TABLE', 'def,345,mkr' );
myInsertInto('MY_TABLE', 'fgh' );
end;
/