Относительно того, что хранимая процедура Oracle не компилируется, потому что таблица в настоящее время не существует - PullRequest
0 голосов
/ 30 июня 2010

Все,

У меня есть следующее описание пакета:

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 Database 10g Enterprise Edition Release 10.2.0.4.0 - 64-бит.

Спасибо!
-Ashish

Ответы [ 4 ]

1 голос
/ 30 июня 2010

Вы можете создать пакет заранее (то есть он будет существовать как объект в базе данных), но Oracle пометит его как недействительный.Oracle попытается перекомпилировать объект при первом обращении к нему, поэтому, если ваши таблицы существуют в то время, все будет в порядке.

Однако вы можете столкнуться с проблемами, когда зависимости находятся более чем на одном уровне - Oracle не сможет перейти в цепочку зависимостей для перекомпиляции всех необходимых недопустимых объектов, и отбрасывание состояния пакета путем перекомпиляции можетвызвать проблему, если предыдущее состояние использовалось другим пакетом.

1 голос
/ 30 июня 2010

Не то, чтобы я знал. Как вы можете скомпилировать что-то для объектов, которые не существуют? Oracle не знает, ошиблись ли вы в названии таблицы, пытаясь сослаться на существующую таблицу, или надеетесь создать таблицу позже.

Почему бы сначала не создать таблицы, а затем создать / скомпилировать пакеты?

0 голосов
/ 02 мая 2013

Вы можете закодировать ваш sql в строку (динамический) и затем передать его в оператор execute.Я уверен, что так, оракул не будет знать, что ты собираешься бежать, прежде чем под рукой.

0 голосов
/ 30 июня 2010

Все ссылочные объекты, включая таблицы и представления, должны существовать при компиляции пакета.Если таблица будет изменена или удалена, пакет станет недействительным и его придется перекомпилировать.Итак, сначала создайте таблицу в схеме Ашиша.

Это верно даже для пакетов "AUTHID CURRENT_USER".Это забавная ситуация, поскольку при запуске процедуры в пакете процедура будет искать таблицу в схеме вызывающего, а не схему владельца пакета, поэтому таблица может не существовать в этой схеме, и Oracle вызовет исключение времени выполнения.Но владелец пакета может скомпилировать его, поскольку таблица существует в его схеме.Забавно, но так оно и есть.

...