Во время блока инициализации вновь созданного пакета я заполняю одно поле в записи, хранящейся в ассоциативном массиве (проиндексирован VARCHAR2). Затем я перебираю ассоциативный массив для хранения второго поля в каждой записи. Эти записи хранят имя таблицы и имя столбца, который является внешним ключом для данной таблицы. (Наш продукт имеет общую форму, поэтому позже я могу сгенерировать SQL-код, с той лишь разницей, что имена таблиц и столбцов). Вот пример кода:
CREATE OR REPLACE PACKAGE BODY pk_example IS
TYPE pkt_TableInfo IS RECORD
(
BaseTable VARCHAR2(30),
FKColumn VARCHAR2(30)
);
TYPE pkt_TableInfoTable IS TABLE OF pkt_TableInfo INDEX BY VARCHAR2(30);
pk_tTableInfo pkt_TableInfoTable;
pk_sIndex VARCHAR2(30);
/***FUNCTION AND PROCEDURE DEFINITIONS***/
--Initialization Section
BEGIN
pk_tTableInfo('TABLE_A').BaseTable := 'TABLE_B';
pk_tTableInfo('TABLE_C').BaseTable := 'TABLE_D';
pk_sIndex := pk_tTableInfo.FIRST;
WHILE pk_sIndex IS NOT NULL LOOP
SELECT acc.column_name
INTO pk_tTableInfo(pk_sIndex).FKColumn
FROM all_constraints ac
INNER JOIN all_constraints ac2 ON ac.r_owner = ac2.owner AND ac.r_constraint_name = ac2.constraint_name
INNER JOIN all_cons_columns acc ON ac.owner = acc.owner AND ac.constraint_name = acc.constraint_name
WHERE ac.owner = sys_context('userenv', 'current_schema')
AND ac.constraint_type = 'R'
AND ac.table_name = pk_sIndex
AND ac2.table_name = pk_tTableInfo(pk_sIndex).BaseTable;
pk_sIndex := pk_tTableInfo.NEXT(pk_sIndex);
END LOOP;
END pk_example;
Все компилируется просто отлично, однако всякий раз, когда я пытаюсь запустить функцию из этого пакета, я получаю ошибку «ORA-01006: переменная связывания не существует», указывающая настрока "SELECT acc.column_name".
Теперь для кикера. Это работает в моей среде разработки, но не удается, когда я пытаюсь запустить пакет в QA.
- У меня есть все те же разрешения, и я могу выполнить запрос просто отлично. На самом деле, если я заменю pk_tTableInfo (pk_sIndex) на строку 'TABLE_B', запрос будет работать нормально. (Для первого прохода через цикл ... затем я не получаю данных)
- Внешние ключи одинаковы для разных сред.
- В обеих средах работает Oracle 12cR2.
Спасибо, что нашли время, чтобы прочитать это, я ценю любой вклад.