Oracle PLSQL - 在不存在的表上声明一个游标

9
我想在一张不存在的表上声明一个游标。当然,我的过程无法编译。
这个表是一个临时表,在预处理中创建。它将在运行时存在,但在编译时又是另一回事了。
对于我的select / update和其他DML操作,我已经使用了EXECUTE IMMEDIATE 'tmp_table中的操作',但我找不到解决游标的方法。
有什么办法吗?
基本上,我希望这个过程可以编译通过。
drop table test;

/*from this on should compile*/
DECLARE
cursor c is select * from test;

BEGIN
  for reg in c LOOP
  /*...*/
  END LOOP;
END;

更新

目前尚未编译:

SQL> declare
  2  c sys_refcursor;
  3  BEGIN
  4  open c for 'select * from pepito'; -- 'pepito' does not exist
  5  close c;
  6  end;
  7  /
declare
*
ERROR at line 1:
ORA-00942: table or view does not exist
ORA-06512: at line 4

建议使用CREATE PROCEDURE语句,谢谢。

提前致谢。


你会收到异常,因为你实际上运行了代码。将你的 declare 替换为 CREATE PROCEDURE test_cursor AS 以编译代码。 - Peter Lang
TOAD没有编译按钮。:S 这应该是微不足道的!!! - Tom
"DECLARE..BEGIN..END;/" 的意思是“编译并运行此匿名块”。这就是为什么您会收到ORA-00942的原因。而“CREATE PROCEDURE ...;/” 的意思是“编译并创建此过程”。在调用该过程之前,您将不会收到ORA-00942的错误提示。 - Jeffrey Kemp
3个回答

8
你应该可以按照以下方式定义你的光标:
DECLARE
  c SYS_REFCURSOR;
BEGIN
  OPEN c FOR 'SELECT * FROM dual';
  CLOSE c;
END;

你也可以绑定参数:

OPEN c FOR 'SELECT * FROM dual WHERE DUMMY = :1' USING 'X';

如需更多信息,请参阅Oracle文档中的OPEN-FOR语句

使用存储过程的示例:

CREATE OR REPLACE PROCEDURE test IS
  c SYS_REFCURSOR;
BEGIN
  OPEN c FOR 'SELECT * FROM fdfdfdfdfd';
  CLOSE c;
END;
/

谢谢,但是dual是一个现有的表。我需要在运行时为一个不存在的表执行此操作。 - Tom
那里有个打字错误,应该是编译时。 - Tom
我不确定你的意思。你也可以将提供的源更改为“SELECT * FROM some_not_existing_table”。如果该表仍不存在,则编译将成功,但在运行时会出错。 - Peter Lang
我在sqlplus中遇到了“表或视图不存在”的错误。 - Tom
@ammoQ 我同意使用 dual 时可以编译通过,但是在使用不存在的表时无法编译。我已经在我的问题中添加了一个示例。 - Tom
显示剩余2条评论

5

在Oracle中,按需创建临时表通常不被认为是良好的实践。更好的方法是使用全局临时表,这样就不会引起该问题。


1
全局临时表比即时创建/销毁表要好得多。即时创建表更容易出错,难以维护。 - Klas Lindbäck

3
您可以使用DBMS_SQL来获得比Peter Lang描述的游标方法更多的灵活性。但这也意味着需要更多的工作量。

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