Как можно объявить имя и тип переменной условно?
Возможно ли объявлять переменные условно в функциях или процедурах?
Например, можно ли сделать что-то такое:
CREATE OR REPLACE FUNCTION get_total_sales(in_year PLS_INTEGER) RETURN NUMBER IS
IF condtion THEN
variable_name_1 BINARY_FLOAT;
ELSE
variable_name_2 NUMBER;
END;
BEGIN
NULL;
-- логика функции
END;
Если условие condtion выполнится, то нужно объявить переменную с именем variable_name_1, если нет, то вместо этой переменной нужно объявить другую переменную - variable_name_2.
Свободный перевод вопроса Oracle PL/SQL Conditional Declaration? от участника @Ashan Priyadarshana
Ответы (2 шт):
Условная компиляция (Conditional Compilation) досупна с версии 10g.
Пример:
create or replace procedure cctest as
$IF $$cctest_on $THEN
var1 binary_float;
$ELSE
var2 number;
$END
begin
$IF $$cctest_on $THEN
var1 := 1.23E+004;
$ELSE
var2 := 999;
$END
end cctest;
/
Procedure CCTEST compiled
alter procedure cctest compile PLSQL_CCFLAGS='cctest_on:true' reuse settings
/
Procedure CCTEST altered.
Так можно посмотреть исходный код последней компиляции:
exec dbms_preprocessor.print_post_processed_source ( -
object_type => 'procedure', -
schema_name => 'myschema', -
object_name => 'cctest');
procedure cctest as
var1 binary_float;
begin
var1 := 1.23E+004;
end cctest;
Не всегда условная компиляция возможна, например, значение условия вычисляется и на момент компиляции неизвестно. В этом случае можно воспользоваться условным оперетором IF-ELSE, чтобы поделить блок на подблоки, другими словами, на отдельные пространства имён.
Для избежания дубликации кода можно определить внутренние перегруженые функции. Принятые для этих целей в других ЯП синтктические конструкцие вида template, generic, в PL/SQL отсутствуют.
Примерно так это будет выглядеть:
create or replace procedure condtest (cond boolean) as
function checkCondition return boolean is
begin return cond;
end;
function foo (par binary_float) return binary_float is
begin dbms_output.put_line ('foo(float)='||par); return par;
end;
function foo (par number) return number is
begin dbms_output.put_line ('foo(number)='||par); return par;
end;
begin
if checkCondition then <<cond_on>>
declare
var1 binary_float := 1.23E+004;
res binary_float := foo (var1);
begin null;
end;
else <<cond_off>>
declare
var2 number := 999;
res number := foo (var2);
begin null;
end;
end if;
end condtest;
/
exec condtest (true)
foo(float)=1,23E+004
exec condtest (false)
foo(number)=999