【问题标题】:Oracle PLSQL - Declare a cursor on a non-existing tableOracle PLSQL - 在不存在的表上声明游标
【发布时间】:2010-12-28 20:42:55
【问题描述】:

我想在一个不存在的表上声明一个游标。当然,我的程序没有编译。

此表为临时表,由预处理创建。它将存在于运行时,但在编译时是另一回事。

对于我的选择/更新其他 DML 操作,我使用了

EXECUTE IMMEDIATE 'operation from 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 以编译代码。
  • TOAD 没有编译按钮。 :S 这应该是微不足道的!!!
  • "DECLARE..BEGIN..END;/" 表示“编译并运行这个匿名块”。这就是你得到 ORA-00942 的原因。 CREATE PROCEDURE ...;/" 的意思是“编译并创建这个过程”。在你调用这个过程之前,你不会得到 ORA-00942。

标签: oracle plsql database-cursor ora-00942


【解决方案1】:

根据需要创建临时表在 Oracle 中通常不被认为是好的做法,其中全局临时表更好,不会导致此问题

【讨论】:

  • +1 全局临时表比动态创建/销毁表要好得多。动态创建表更容易出错且更难维护。
【解决方案2】:

你应该可以像这样定义你的光标:

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';

有关详细信息,请参阅OPEN-FOR Statement 的 Oracle 文档。

使用存储过程的示例

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

【讨论】:

  • 谢谢,但 dual 是现有的表。我需要在运行时对不存在的表执行此操作。
  • 错字了,它的编译时间。
  • 我不确定你的意思。您还可以通过“SELECT * FROM some_not_existing_table”更改提供的源。如果表仍然不存在,它将在运行时正常编译并中断。
  • 我在 sqlplus 中得到一个“表或视图不存在”
  • IMO 它应该按预期工作。汤姆,我认为你做错了。
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多