Вы можете сделать это с dynamic PL / SQL . Используйте оператор EXECUTE IMMEDIATE
для выполнения строкового аргумента в виде PL / SQL, который вы можете создать с помощью ||
, как это и предполагалось в вопросе.
Пример:
BEGIN
FOR nr IN 1..102
LOOP
DBMS_OUTPUT.PUT_LINE(nr);
EXECUTE IMMEDIATE
'BEGIN ' ||
'IF rec.column.' || nr ||' is null THEN ' ||
'DBMS_OUTPUT.PUT_LINE(''test''); ' ||
'END IF; ' ||
'END; ';
END LOOP;
END;
Или вы также можете присвоить rec.column.' || nr ||' is null
переменной и сделать PUT_LINE
за пределами EXECUTE IMMEDIATE
:
ОБНОВЛЕНИЕ : Кажется, невозможно связать BOOLEAN
переменные, поэтому я изменил пример для использования NUMBER
.
ОБНОВЛЕНИЕ 2: Возможное повышение эффективности, хотя, возможно, не подходит в этом случае. Используйте константу VARCHAR
для динамического SQL и передайте в nr
переменную с привязкой. Это даже более эффективно, чем использование собственного SQL, если он находится в большом цикле. Я не думаю, что 'rec.column.:arg is null
будет исполняться как 'rec.column.1 is null
.
DECLARE
isnull NUMBER;
BEGIN
FOR nr IN 1..102
LOOP
DBMS_OUTPUT.PUT_LINE(nr);
EXECUTE IMMEDIATE
'BEGIN ' ||
'IF rec.column.' || nr ||' IS NULL THEN ' ||
':x:=1; ' ||
'ELSE ' ||
':x:=0; ' ||
'END IF; ' ||
'END; '
USING OUT isnull;
IF isnull = 1 THEN
DBMS_OUTPUT.PUT_LINE('test');
END IF;
END LOOP;
END;
ОБНОВЛЕНИЕ 3 :
Видя, что:
Невозможно получить доступ к rec
внутри динамического оператора SQL, поскольку он не определен (выходит за рамки),
Кажется невозможным передать тип не-sql в качестве аргумента динамического оператора (запись, курсор)
Возможный обходной путь - связать некоторые столбцы идентификатора (тип SQL) с динамическим оператором и использовать предложение select
, чтобы выяснить, является ли текущий столбец пустым:
DECLARE
isnull NUMBER;
rec_id NUMBER; -- Identifier of the fetched record
BEGIN
rec_id := rec.id;
FOR nr IN 1..102
LOOP
DBMS_OUTPUT.PUT_LINE(nr);
EXECUTE IMMEDIATE
'SELECT 1 FROM my_table WHERE id = :idarg ' ||
' AND column_' || nr || ' IS NULL'
INTO isnull USING rec_id;
IF isnull = 1 THEN
DBMS_OUTPUT.PUT_LINE('test');
END IF;
END LOOP;
END;