PL / SQL встроенная вставка в таблицу, которая может не существовать - PullRequest
2 голосов
/ 17 марта 2010

Я очень предпочитаю использовать вставки этого «встроенного» стиля в блоке pl / sql (в отличие от динамического sql в стиле немедленного исполнения - где вы должны разделять кавычки и т.д.)

-- a contrived example
PROCEDURE CreateReport( customer IN VARCHAR2, reportdate IN DATE )
BEGIN

   -- drop table, create table with explicit column list
   CreateReportTableForCustomer;

   INSERT INTO TEMP_TABLE 
   VALUES ( customer, reportdate );
END;
/

Проблема здесь в том, что оракул проверяет, существует ли 'temp_table' и имеет ли оно правильное количество столбцов, и выдает ошибку компиляции, если он не существует.

Так что мне было интересно, есть ли способ обойти это ?! По сути, я хочу использовать заполнитель для имени таблицы, чтобы обмануть оракула, чтобы он не проверял, существует ли таблица.

EDIT:

Я должен был упомянуть, что пользователь может выполнить любой «отчет» (как указано выше). Механизм, который будет выполнять произвольный запрос, но всегда записывать в temp_table (в схеме пользователя). Таким образом, каждый раз, когда запускается протокол proc, он удаляет temp_table и воссоздает его, скорее всего, с другим списком столбцов.

Ответы [ 3 ]

5 голосов
/ 17 марта 2010

Возможно, вам следует использовать глобальную временную таблицу (GTT). Это структуры постоянных таблиц, которые содержат временные данные для сеанса Oracle. Многие разные сеансы могут вставлять данные в один и тот же GTT, и каждый сможет видеть только свои собственные данные. Данные автоматически удаляются либо по COMMIT, либо по окончании сеанса в соответствии с определением GTT.

Вы создаете GTT (только один раз) следующим образом:

create globabal temporary table my_gtt
(customer number, report_date date) 
on commit delete/preserve* rows;

* удалить, если применимо

Тогда ваши программы могут просто использовать его как любую другую таблицу - единственное отличие в том, что он всегда начинается пустым для вашей сессии.

5 голосов
/ 17 марта 2010

Вы можете использовать динамический оператор SQL, чтобы вставить его в возможно существующую таблицу temp_table, а затем перехватить и обработать исключение, которое возникает, когда таблица не существует.

Пример:

execute immediate 'INSERT INTO '||TEMP_TABLE_NAME||'  VALUES ( :customer, :reportdate )' using customer, reportdate;

Обратите внимание, что изменение имени таблицы в динамическом SQL-выражении не очень хорошо, поэтому, если вы убедитесь, что имена таблиц остаются прежними, это будет лучше.

1 голос
/ 22 марта 2010

Использование GTT гораздо предпочтительнее, чем удаление / воссоздание таблиц на лету - если вашему приложению нужна отдельная структура для каждого отчета, я настоятельно рекомендую вам разработать все различные структуры, в которых нуждается каждый отчет, и создать отдельные GTT по мерекаждая, вместо создания обычных таблиц во время выполнения.

Тем не менее, если это просто невозможно, (и я видел хорошие примеры, когда это не так, например, в системе, которая поддерживает широкий спектр специальныхзапросы от пользователей), вам придется пойти с EXECUTE IMMEDIATE подходом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...