我为一个正在创建应该匹配的表集之间进行协调的包创建了pl/sql procedure
。
我正在使用listagg将循环中当前表名的列名连接成一个字符串,该字符串用于动态SQL语句,该语句比较两个表(每个表名都有34个循环)。
该过程按预期工作,但结果从负号意外返回。经过研究,我确定某些字段包含在平面文件中接收到的十六进制(00)字符,该字符仅将数据填充在侦察器一侧的数据上。为了解决特殊字符,我在列名select中添加了一个与listagg串联的regexp_replace,以便输出完整的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 ;
答案 0 :(得分:1)
varsql2在plsql中限制为32k 如果32就足够了,您可以尝试这样的事情
create or replace procedure conc_col_names(tableName IN varchar2) as
collist varchar2(32767);
begin
for xx in (select * from user_tab_columns where table_name = tableName order by column_name asc) loop
if ( length(collist) > 0) then
collist := collist||',';
end if;
collist := collist||'regexp_replace('||xx.column_name||',''[^A-Z0-9 ]'')';
end loop;
/* add the rest code for comparing rows in the two table here */
end;
/