Оператор Oracle Native Dynamic SQL PL/SQL без начала и конца

У меня проблема с созданием резервной копии таблицы путем создания серии операторов вставки.

Входными данными является имя таблицы, и каждая таблица может иметь разное количество столбцов. Предполагается, что типы данных могут быть только varchar2, число или дата

поэтому у меня есть эта строка кода:

execute immediate fetchStmt;

где fetchStmt может быть:

fetch tableColCursor into valuesArray(1), valuesArray(2), ...,  valuesArray(n)

Это просто извлекает каждую строку из курсора и помещает ее в varray, сами операторы работают, если они не находятся в непосредственном операторе выполнения.

Я знаю, что немедленное выполнение может обрабатывать только запросы SQL или блоки PL/SQL. Проблема в том, как я смогу выполнить эту работу или что может быть похожим решением проблемы?

Обратите внимание, что во время компиляции неизвестна таблица, ее столбцы и их типы данных.


person Ram    schedule 16.11.2012    source источник
comment
: У вас есть таблица, содержащая все операторы dml? Если да, не могли бы вы опубликовать структуру таблицы или ваш курсор?   -  person Gaurav Soni    schedule 16.11.2012


Ответы (1)


EXECUTE IMMEDIATE может обрабатывать только полные операторы, т. е.: Операторы SQL или блоки PLSQL (с [DECLARE]..BEGIN..END).

Кроме того, блок, выполненный таким образом, не увидит никаких переменных из вызывающего блока (они не имеют одной и той же области видимости), например, это не сработает:

DECLARE
  l NUMBER := 1;
  k NUMBER := 0;
BEGIN
  EXECUTE IMMEDIATE 'BEGIN l := k; END;';
END;

Приведенный выше код вызовет ошибку, поскольку l и k не определены в подблоке. Вместо этого вам нужно будет использовать переменные ввода/вывода:

DECLARE
  l NUMBER := 1;
  k NUMBER := 0;
BEGIN
  EXECUTE IMMEDIATE 'BEGIN :P1 := :P2; END;' USING OUT l, k;
  dbms_output.put_line(l); -- return 0
END;

В вашем случае вы не знаете количество переменных, поэтому вы не сможете использовать EXECUTE IMMEDIATE. Вы можете использовать DBMS_SQL, но я думаю, что есть более простые методы: вы можете найти уже работающий код (например, он существует в Oracle APEX) или вы можете запрограммировать его самостоятельно, запустив SELECT, который создаст необходимую строку INSERT. Для этого метода вам придется генерировать оператор SQL динамически (в зависимости от столбцов таблицы). Оператор будет выглядеть следующим образом (для таблицы TEST(a,b,c), где все столбцы являются целыми числами [требуется адаптация для других типов данных]):

SELECT 'INSERT INTO test(a,b,c) VALUES ('||a||', '||b||', '||c||');'
  FROM test
person Vincent Malgrat    schedule 16.11.2012