【问题标题】:Oracle Nested cursorsOracle 嵌套游标
【发布时间】:2012-06-15 19:19:45
【问题描述】:

我想从存在该列的架构中的每个表中获取名为“YMDH”的列中的不同日期。我想我需要使用嵌套游标(我以前没有做过)并想出了以下代码:

CREATE OR REPLACE PROCEDURE DistinctDates AS 
   sql_statement1 varchar2(200);
   sql_statement2 varchar2(200);
   results varchar2(15);
   ColumnExist integer;
BEGIN
    for cursor_rec in (SELECT * FROM user_objects WHERE object_type='TABLE'
    AND object_name NOT LIKE 'TM%')  loop
    sql_statement1 := 'select count (*) from user_tab_columns where table_name=' || '''' || cursor_rec.object_name || '''' || ' and column_name=' || '''' ||'YMDH'  || '''';
    execute immediate sql_statement1 into ColumnExist;
    if ColumnExist = 1 then
      for inner_cursor_rec in (select distinct(ymdh) from cursor_rec.object_name) loop
         null;
      end loop;
    end if;
    end loop;
END DistinctDates;

SQL Developer 抱怨内部游标的 select 语句。错误信息是:

错误(18,32): PL/SQL: SQL 语句被忽略 错误(18,70):PL/SQL:ORA-00942:表或视图不存在

所以它无法识别对外部光标的引用。如何将表名(即 cursor_rec.object_name)传递给内部游标?

【问题讨论】:

  • 您的第二个查询也应该是动态的; cursor_rec.object_name 是一个字符串。这也有点像 SQL 注入。
  • +1 仅用于“SQL 注入-y”...

标签: sql oracle cursor


【解决方案1】:

你在不需要的地方使用了动态SQL,没有在需要的地方使用!

检查表是否有名为“YMDH”的列可以合并到第一个查询中,给出以下代码:

CREATE OR REPLACE PROCEDURE DistinctDates AS 
   sql_statement varchar2(200);
   rc sys_refcursor;
   ymdh_value ????; -- Appropriate data type
BEGIN
    for cursor_rec in (SELECT t.table_name 
                       FROM user_tables t
                       JOIN user_tab_columns c ON c.table_name = t.table_name
                       WHERE t.table_name NOT LIKE 'TM%'
                       AND c.column_name='YMDH')  
    loop
        sql_statement := 'select distinct(ymdh) from ' || cursor_rec.table_name;
        open rc for sql_statement;
        loop
            fetch rc into ymdh_value;
            exit when rc%notfound;
            null;
        end loop;
        close rc;
    end loop;
END DistinctDates;

【讨论】:

  • 您可以在光标 for 循环中完全省略与 user_tables 的 JOIN,只需从 user_tab_columns 中选择(user_tab_columns 也包含 table_name)。
猜你喜欢
  • 1970-01-01
  • 2012-01-18
  • 1970-01-01
  • 1970-01-01
  • 2015-10-09
  • 1970-01-01
  • 1970-01-01
  • 2015-04-25
  • 1970-01-01
相关资源
最近更新 更多