2014-02-26 90 views
0

下面的代码是不言自明的。我们可以在PL/SQL的FOR-IN循环中使用变量吗? 这是要求,因为FOR-IN内部的查询需要具有动态性质。我们可以在FOR-IN循环中使用变量吗

SET SERVEROUT ON; 

DECLARE 
    STMNT  varchar2(4000); 
    SELECT_SQL varchar2(4000); 
BEGIN 
    SELECT_SQL := q'[select table_name from all_tables where owner='EMP' and table_name like 'TEMP_%']'; 
    FOR REC IN (SELECT_SQL) LOOP 
     dbms_output.put_line (REC.table_name); 
    END LOOP; 
END; 

回答

3

不,您不能使用for循环浏览动态构建的查询返回的结果集。但是,你不能做的是为该动态构建的查询打开一个refcursor,并使用LOOPWHILE循环结构遍历结果集。举个简单的例子,但在你的情况,没有必要使用动态SQL可言:

set serveroutput on; 
clear screen; 

declare 
    l_sql_statement varchar2(4000); -- going to contain dynamically built statement 
    l_rcursor  sys_refcursor; -- ref cursor 
    l_owner   varchar2(100); -- variable that will contain owner's name 
    l_res_tab_name varchar2(100); -- variable we will fetch table name into 
begin 
    l_owner := 'NK'; 
    l_sql_statement := 'select table_name 
         from all_tables 
         where owner = :1'; -- bind variable 

    open l_rcursor for l_sql_statement 
    using dbms_assert.simple_sql_name(l_owner); -- slight protection from 
               -- SQL injection 

    loop 
    fetch l_rcursor into l_res_tab_name; -- fetch table name from the resultset 
    exit when l_rcursor%notfound;   -- exit, when there is nothing to fetch 
    dbms_output.put_line(l_res_tab_name); -- print table name 
    end loop; 
end; 

结果:

anonymous block completed 

TEST1 
TEST2 
TMP_TEST 
ERR$_T1 

注:考虑,在这种情况下,根本不使用动态SQL,实际上不需要它。表名和列名在编译时是已知的,只有谓词的右侧发生了变化。

+2

+1 **注**。 [带参数的光标](http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/explicit_cursor.htm#LNPLS01313)就足够了。 –

相关问题