pl sql select * from owner.view1 减去 select * from owner2.view1 作为 for 循环中的游标

Posted

技术标签:

【中文标题】pl sql select * from owner.view1 减去 select * from owner2.view1 作为 for 循环中的游标【英文标题】:pl sql select * from owner.view1 minus select * from owner2.view1 as a cursor in for loop 【发布时间】:2017-01-12 18:58:45 【问题描述】:
DECLARE
CURSOR c1
 IS
   SELECT view_name
   FROM all_views
   WHERE owner = 'DBA_A'
   AND view_name LIKE 'IRV_%'
   OR view_name LIKE 'RD_%'
   ORDER BY view_name;
BEGIN
 FOR i IN c1
 LOOP
   FOR ii IN ('select * FROM DBA_A.' || i.VIEW_NAME || ' minus select *     FROM DBA_B.' || i.VIEW_NAME)
   LOOP
     -- I plan to put the results from the select in the FOR ii loop in a listAgg.  I think I can figure that out.
     dbms_output.put_line(listAgg);
   END LOOP; -- for ii
 END LOOP; -- for i
END;

我收到以下错误。它可能是我正在探索的语法,但我在 ii 循环中尝试做的事情看起来很理智吗?我必须弄清楚如何使用 listAgg 函数。

谢谢。

END LOOP 产生错误; -- 为 ii

PLS-00103:在预期以下情况之一时遇到符号“END”:

dbms_output.put_line 显示生成了正确的选择。再次感谢。丰富

谢谢阿列克谢。表/视图有很多字段。但我希望比较视图而不是表格。这些视图位于两个单独的模式中。两个模式对象完全相同(我将 DBA_A 复制到 DBA_B)。但是我为一个模式中的一个视图修改了一个基表。

如果我使用硬编码的 schema.view 名称对 select/minus 进行硬编码,则 select * from DBA_A.view1.... 减去 select * from DBA_B.view1... 有效。选择返回具有更改数据的视图的一行。我相信有一种方法可以返回视图的所有列名(在循环内)。我希望对列名列表和返回的行中的数据执行 dbms_output.putline(通过 listAgg)。

如果我不够清楚,我很抱歉。非常感谢您的示例代码。我将根据您的示例修改我的代码并发布我的结果。

【问题讨论】:

您的代码有一些问题,但不清楚您需要做什么,因此很难帮助您。假设您通过第一个查询找到了一个视图,然后进行减号并得到 5 列的 10 条记录。你想用这些记录做什么?您如何处理您事先不知道动态查询将返回的列的事实?请尝试建立一个minimal reproducible example来帮助人们帮助你 嗨。当我在一个视图中更改了一个模式中的基表时,仅执行(在任何代码块之外)选择...减去...选择(使用 select * owner.view 减去 select * owner2.view 手动对其进行编码)选择返回包含所有列的行。我只想获取 ii 循环中返回的行的 rowid 并执行 dbms_output.put_line(rowid)。该代码永远不会进入 ii 循环。我希望这会有所帮助。谢谢! Dynamic SQL LOOP的可能重复 视图的rowid没有多大意义.. 【参考方案1】:

试图简化你的问题,只是给你一些关于动态代码的提示

假设我有想要比较的表格;为了简单起见,我使用表来避免 rowid 问题,并使用相同的模式,只是更改表名。 表格:

create table TABLE_A_1(id) as select 1 from dual union all select 2 from dual;
create table TABLE_A_2(id) as select 2 from dual;
create table TABLE_B_1(id) as select 3 from dual union all select 3 from dual;
create table TABLE_B_2(id) as select 4 from dual;

假设我想将 TABLE_A_1 与 TABLE_A_2 和 TABLE_B_1 与 TABLE_B_2 进行比较,检查 id 值;我相信这可以让您对使用动态 SQL 的方式有所了解:

declare
    cur sys_refcursor;
    v   number;
begin    
    for tab in ( select table_name from user_tables where regexp_like (table_name, 'TABLE_[AB]_1') ) loop
        open cur for 'select id from ' || tab.table_name || ' minus select id from ' || replace(tab.table_name, '1', '2');
        loop
            fetch cur into v;
            exit when cur%NOTFOUND;
            dbms_output.put_line( tab.table_name || ' minus ' || replace(tab.table_name, '1', '2') || ': ' || v);
        end loop;
    end loop;
end;

这给出了:

TABLE_A_1 minus TABLE_A_2: 1
TABLE_B_1 minus TABLE_B_2: 3

请注意这里有两个主要的简化:

我假设所有表都有一个字段;在更一般的情况下,您必须确保您比较的视图具有相同的结构。 我使用ID 来识别缺失的行;在表格中,我可以使用rowid,但在视图上rowid 将没有用,因此您需要找到一种方法来识别另一个视图中缺少的行。

总之,为了给出一个完整的解决方案,我应该更多地了解您的观点以及您想要用来识别缺失行的方式;如果没有这些信息,这包含一些提示,希望对您编写自己的解决方案有用。

【讨论】:

谢谢 Aleksej, 如果答案适合您,请接受。 Here 当有人回答你时,你会发现该怎么做。

以上是关于pl sql select * from owner.view1 减去 select * from owner2.view1 作为 for 循环中的游标的主要内容,如果未能解决你的问题,请参考以下文章

pl/sql设置快捷键输入sf+空格出现select * from

Others-PL/SQL Developer自动替换语句(自动打印select*from语句)

PL/SQL快键键——自动替换(输入sf直接跳出来select * from)

pl/sql客户端命令

pl sql select * from owner.view1 减去 select * from owner2.view1 作为 for 循环中的游标

pl/sql快速输入select等语句