以下是您问题的对象关系解决方案。最终的 PL/SQL 看起来几乎与您的代码 sn-ps 相同:
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
以下是创建支持对象的步骤。首先,我们需要定义一个超类。这个超类不做任何事情,它只是一个允许子类存储在一起的容器。
--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;
/
接下来,我们创建实际实现数学函数的子类。
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;
/
最后,我们创建一个可以保存 OPERATION 类型以及其他一些数据的表。
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;
缺点
这种方法需要大量代码 - 1500 个字符来实现“+”和“-”。您的所有 SQL 语句都会变得复杂,人们将难以读取或写入数据。许多工具不支持对象关系数据。混合代码和数据会导致一些问题——你不能修改类型规范而不产生类似“ORA-02303:不能删除或替换类型或表依赖的类型”之类的错误。 (并且不要只是跳到使用“FORCE”选项。如果你强制编译类型,你会破坏表格并丢失数据。)性能可能很糟糕。
我从未使用过这样的系统并且不讨厌它。构建一个“脏”的动态代码解决方案通常比构建一个“纯”的对象关系解决方案要好。但是,如果您小心并记录所有内容,那么这种系统可能会有很好的用途。