2012-06-12 89 views
0

我想從該列存在的模式中的每個表中獲取名爲「YMDH」的列中的不同日期。我想,我需要使用嵌套的遊標(這是我以前沒做過的),並用下面的代碼上來:Oracle嵌套遊標

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)傳遞給內部遊標?

+3

你的第二個查詢也應該是動態的; 'cursor_rec.object_name'是一個_string_。這也是一個SQL注入-y。 – Ben

+0

單獨爲「SQL Injection-y」+1 ... – Ollie

回答

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; 
+0

感謝您的幫助! –

+0

您可以在遊標for loop中省略與user_tables的JOIN,只需從user_tab_columns中選擇(user_tab_columns也包含table_name)即可。 –