Я создал pl/sql procedure
для пакета, который выполняет согласование между наборами таблиц, которые должны совпадать.
Я использую listagg для объединения имен столбцов текущего имени таблицы в цикле встрока, используемая в динамическом операторе SQL, который сравнивает две таблицы (34 набора, зацикленные для каждого имени таблицы).
Процедура сработала так, как ожидалось, но результаты были неожиданно возвращены из минуса.После исследования я определил, что некоторые поля содержат символ HEX (00), полученный в плоском файле, который заполняет данные только данными с одной стороны разведки.Чтобы учесть специальные символы, я добавил regexp_replace, соединенный в линию с listagg в select имени столбца, чтобы он выводил полные результаты listagg с каждым именем столбца, заключенным в regexp_replace.
Это работает.Однако некоторые таблицы содержат более ста столбцов, и список ошибок не может быть более 4000 символов.
Есть ли лучший способ обойти все это?
Вот код:
Собирает имена столбцов в список через запятую (запятая объединяется в саму строку для использования в качестве разделителя в динамическом SQL, выберите ниже)
execute immediate
'SELECT ' || q'{listagg('regexp_replace(' || column_name || ', ''[^A-Z0-9 ]'', '''')', '||'', '' || ')}' || ' within group (order by rownum) "COLUMN_NAME"
FROM user_tab_cols
where table_name =''' || csrpubtable.table_name || ''''
into v_column_names;
Эти два динамических оператора SQL выполняют согласование в обоих направлениях.Они не связаны напрямую с ошибкой, но, безусловно, с моим вопросом о лучшем общем способе выполнения задачи.
--Insert data to RECON_PUB_TABLES where record exists in FILE but not PROD
execute immediate
'INSERT INTO RECON_PUB_TABLES
SELECT ''' || csrpubtable.table_name || ''', ''FILE'' , ' || v_column_names || ', trunc(sysdate) from ' || csrpubtable.table_name || '
minus
SELECT ''' || csrpubtable.table_name || ''', ''FILE'' , ' || v_column_names || ', trunc(sysdate) from ' || csrpubtable.table_name || '@pub_recon2prod where trunc(' || v_lastupdate_column || ') <= trunc(to_date(''' || v_compare_date || ''', ''dd-MON-yy''))';
--Insert data to RECON_PUB_TABLES where record exists in PROD but not FILE
execute immediate
'INSERT INTO RECON_PUB_TABLES
SELECT ''' || csrpubtable.table_name || ''', ''PROD'' , ' || v_column_names || ', trunc(sysdate) from ' || csrpubtable.table_name || '@pub_recon2prod where trunc(' || v_lastupdate_column || ') <= trunc(to_date(''' || v_compare_date || ''', ''dd-MON-yy''))
minus
SELECT ''' || csrpubtable.table_name || ''', ''PROD'' , ' || v_column_names || ', trunc(sysdate) from ' || csrpubtable.table_name ;