Below is an object-relational solution to your question. The final PL/SQL looks almost identical to your code snippets:
declare
type data_nt is table of table1%rowtype;
data data_nt;
result number;
begin
select * bulk collect into data from table1 order by seq asc;
for i in 1 .. data.count loop
result := data(i).operation.operate(data(i).input1, data(i).input2);
dbms_output.put_line('Result: '||result);
end loop;
end;
/
DBMS_OUTPUT:
Result: 2
Result: 0
Below are the steps to create the supporting objects. First, we need to define a superclass. This superclass doesn't do anything, it's just a container to allow the subclasses to be stored together.
--Rollback:
-- drop table operations;
-- drop type addition;
-- drop type operation;
create or replace type operation is object
(
--Weird PL/SQL limitation - every type must have a value, so add a dummy column.
dummy varchar2(1),
member function operate(operand1 number, operand2 number) return number,
--Custom constructor so we don't have to pass it a dummy value.
constructor function operation return self as result
)
not final;
/
create or replace type body operation is
member function operate(operand1 number, operand2 number) return number is
begin
return null;
end;
constructor function operation return self as result is begin return; end;
end;
/
Next, we create subclasses that actually implement the math functions.
create or replace type addition under operation
(
overriding member function operate(operand1 number, operand2 number) return number,
constructor function addition return self as result
) not final;
/
create or replace type body addition is
overriding member function operate(operand1 number, operand2 number) return number is
begin
return operand1 + operand2;
end;
constructor function addition return self as result is begin return; end;
end;
/
create or replace type subtraction under operation
(
overriding member function operate(operand1 number, operand2 number) return number,
constructor function subtraction return self as result
) not final;
/
create or replace type body subtraction is
overriding member function operate(operand1 number, operand2 number) return number is
begin
return operand1 - operand2;
end;
constructor function subtraction return self as result is begin return; end;
end;
/
Finally, we create a table that can hold an OPERATION type, along with some other data.
create table table1
(
seq varchar2(10) primary key,
input1 number,
input2 number,
operation operation
);
insert into table1 values('A', 1, 1, addition());
insert into table1 values('B', 1, 1, subtraction());
commit;
Downsides
This approach requires a lot of code - 1500 characters to implement "+" and "-". All your SQL statements will become complicated, and people will have difficulty reading or writing the data. Many tools won't support object-relational data. Mixing code and data causes some problems - you can't modify the type specifications without generating an error like "ORA-02303: cannot drop or replace a type with type or table dependents". (And do NOT just jump to using the "FORCE" option. If you force the types to compile, you will break the table and lose your data.) Performance will probably be lousy.
I've never worked with a system like this and not hated it. It's usually better to build a "dirty" dynamic code solution than a "pure" object-relational solution. But if you're careful and document everything, there might be a good use for this kind of system.