【发布时间】:2019-03-15 11:53:06
【问题描述】:
我为一个包创建了一个pl/sql procedure,该包在应该匹配的表集之间执行协调。
我正在使用 listagg 将循环中当前表名的列名连接成一个用于比较两个表(34 个集合,每个表名循环)的动态 SQL 语句中使用的字符串。
该过程按预期工作,但结果意外地从减号返回。经过研究,我确定某些字段包含在平面文件中收到的 HEX (00) 字符,该字符仅在侦察一侧的数据上填充数据。为了考虑特殊字符,我添加了一个 regexp_replace 与列名 select 中的 listagg 串联,因此它输出完整的 listagg 结果,每个列名都包含在一个 regexp_replace 中。
它有效。但是,有些表有一百多列,listagg 会因为结果超过 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 ;
【问题讨论】:
标签: oracle plsql dynamic-sql regexp-replace listagg