关于Oracle存储过程未编译因为表当前不存在

时间:2010-06-30 17:31:24

标签: sql oracle stored-procedures oracle10g

所有

我有以下包装说明:

CREATE OR REPLACE PACKAGE ashish.PKG_Customer AUTHID CURRENT_USER AS
  TYPE cursorType IS REF CURSOR;

  PROCEDURE CreateCustomerTable;
  PROCEDURE SelectCustomers(o_ResultSet OUT cursorType);    
END PKG_Customer;

这是包体:

CREATE OR REPLACE PACKAGE BODY ashish.PKG_Customer AS

  PROCEDURE CreateCustomerTable AS
    sQuery VARCHAR2(1000);
  BEGIN
    sQuery := 'CREATE TABLE tblCustomer2(
               CustomerID INTEGER PRIMARY KEY,
               FirstName VARCHAR2(50),
               LastName VARCHAR2(50),
               City VARCHAR2(200), 
               State_Province VARCHAR2(100),
               PostalCode VARCHAR2(25)
              )';
    EXECUTE IMMEDIATE sQuery;
  END CreateCustomerTable;

  PROCEDURE SelectCustomers(o_ResultSet OUT cursorType) AS
  BEGIN
    OPEN o_ResultSet FOR
      SELECT CustomerID,
             FirstName,
             LastName,
             City,
             State_Province,
             PostalCode
        FROM tblCustomer;
  END SelectCustomers;
END PKG_Customer;

我面临的问题是我的包不会编译,因为该表当前不存在。当然,我应该能够为Oracle目前不存在的表提前创建存储过程吗?我在这里做错了吗?

服务器版本是Oracle数据库10g企业版10.2.0.4.0 - 64位。

谢谢!
-Ashish

4 个答案:

答案 0 :(得分:1)

不是我知道的。如何针对不存在的对象编译内容? Oracle不知道您是否错误地输入了尝试引用现有表的表名,或者希望以后创建该表。

为什么不先创建表,然后创建/编译包呢?

答案 1 :(得分:1)

您可以提前创建包(意味着它将作为数据库中的对象存在),但Oracle将其标记为无效。 Oracle将在第一次引用时尝试重新编译该对象,因此如果您的表在那时存在则可以。

但是,当依赖关系深度超过一级时,您可能会遇到问题 - Oracle不会深入到依赖关系链中以重新编译所有必需的无效对象,并且通过重新编译丢弃包的状态可能会导致问题如果之前的状态被另一个包使用。

答案 2 :(得分:0)

编译包时,所有引用的对象(包括表和视图)都必须存在。如果表被更改或删除,则包将变为无效并且必须重新编译。因此,首先在ashish架构中创建表。

对于“AUTHID CURRENT_USER”包,这甚至是正确的。这是一个有趣的情况,因为当运行包中的过程时,过程将在调用程序的模式中查找表,而不是包所有者模式,因此表可能不存在于该模式中,Oracle将引发运行时异常。但是包的所有者可以编译它,因为该表存在于其模式中。这很有趣但是就是这样。

答案 3 :(得分:0)

您可以将sql编码为字符串(动态),然后将其传递给execute语句。我确定这样,oracle不会知道你手头的东西。