如何在EXECUTE IMMEDIATE查询中添加表名?

5
我有一个关于“EXECUTE IMMEDIATE”的问题。 我在下一个PLSQL语句中动态地更改了表名。
DECLARE

TYPE CurTyp IS REF CURSOR;
cur CurTyp;
str1 VARCHAR2(30);
str2 VARCHAR2(30);
table_name  VARCHAR2(30);

BEGIN

select data
  into table_name
  from ref
 where o_id = 111
   and a_id = 222;



OPEN cur FOR
'select  name, sname  from :1 b,myobjects a where a.obj_id = b.obj_id'
USING table_name;
LOOP
FETCH cur INTO str1, str2;
EXIT WHEN cur%NOTFOUND;
dbms_output.put_line(str1||str2);
END LOOP;
CLOSE cur;
END

能否将下一个Execute Immediate查询的结果读取到游标中?

'select  name, sname  from :1 b,myobjects a where a.obj_id = b.obj_id'
    USING table_name;

也许有什么方法可以做到这一点吗?

提前感谢。

2个回答

10

在使用对象名时,您必须使用连接而不是绑定变量。

从PL/SQL语言参考手册中的Dynamic SQL章节中得知:

数据库仅使用绑定变量的值,并且不以任何方式解释其内容。

绑定变量有助于安全性和性能。但是,它们无法用于如表之类的对象。如果传递表名,则Oracle必须解释其内容,这将抵消安全性和性能的好处。


jonearles,感谢您的回答,也感谢您提供的链接,非常有用。 - Ishikawa Yoshi

7
您可以使用 ref_cursor,详情请参见 http://docs.oracle.com/cd/B10500_01/appdev.920/a96590/adg09dyn.htm
示例:
CREATE OR REPLACE PROCEDURE query_invoice(
       month VARCHAR2, 
       year VARCHAR2) IS
    TYPE cur_typ IS REF CURSOR;
    c cur_typ;
    query_str VARCHAR2(200);
    inv_num NUMBER;
    inv_cust VARCHAR2(20);
    inv_amt NUMBER;
BEGIN
    query_str := 'SELECT num, cust, amt FROM inv_' || month ||'_'|| year 
      || ' WHERE invnum = :id';
    OPEN c FOR query_str USING inv_num;
    LOOP
        FETCH c INTO inv_num, inv_cust, inv_amt;
        EXIT WHEN c%NOTFOUND;
        -- process row here
    END LOOP;
    CLOSE c;
END;
/

但正如 @jonearles 所说,你不能将表名作为参数插入


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接