如何在表字段中保存最终用户定义的公式(Oracle)

时间:2014-01-04 19:55:31

标签: oracle plsql

嗨, 我需要在表字段中存储公式,公式将有一个名为salario的变量。这个想法是通过代码块来评估公式以获得结果。

示例:

TABLE NAME: CONCEPTO

Field CONCEPTO: VARCHAR

Field FORMULA: VARCHAR

- - - - - - - - - - - - - - - 
CONCEPTO  -    FORMULA
- - - - - - - - - - - - - - -
 AFP ----- (salario * 0.0625)
 ISSS -----(salario * 0.030)
 RENTA-----(salario * 0.100)

现在通过存储过程或函数,我假装执行以评估公式并通过变量sueldo更改变量salario。 这样我想得到一个结果

示例:

CREATE OR REPLACE PROCEDURE pr_calculo AS

  CURSOR cur_concepto_empleado IS
    SELECT concepto, formula
      FROM concepto;

  formula   VARCHAR2(50);
  descuento NUMBER;
  sueldo    NUMBER;

  BEGIN

    FOR reg_conemp IN cur_concepto_empleado
    LOOP

      sueldo := 400;

      formula := replace(reg_conemp.formula, "salario", sueldo);

      -- THIS IS THE LINE 38:
      descuento := to_number(formula, "99");

      dbms_output.put_line(descuento);

    END LOOP;
END PR_CALCULO;

获得的结果是:

Conectando a la base de datos DBwwww.
ORA-06502: PL/SQL: error numérico o de valor
ORA-06512: en "RRHH.PR_CALCULO", línea 38
ORA-06512: en línea 2
El proceso ha terminado.
Desconectando de la base de datos DBwwww.

我如何解决此案? 你会推荐我什么? 我需要在表字段中存储公式,以便在执行一个进程(代码)后评估公式以获得结果....

感谢...

2 个答案:

答案 0 :(得分:1)

你没有乘以这些值,因为它是字符串,所以我动态地乘以数字。

create or replace PROCEDURE PR_CALCULO AS

cursor cur_concepto_empleado is
 select concepto, formula from concepto;

formula varchar2(50);
descuento number;
sueldo number;

begin

for reg_conemp in cur_concepto_empleado
loop

  sueldo := 400;

  formula := replace(reg_conemp.formula,'salario',sueldo);

  execute immediate 'select '||formula ||'   from dual' into descuento;
  --the values dint get multiplied because you store that as string
  --and the string contains * ,so to_number will not work
  --descuento := to_number(formula,'99'); --THIS IS THE LINE 38

  dbms_output.put_line(descuento);

 end loop;

END PR_CALCULO;​​
/

答案 1 :(得分:1)

首先是关于Oracle语言的一般性评论,你必须使用简单引号'而不是双引号大部分时间(列标题和一些xml函数除外)

对于你的问题,你自己接近答案。在这里,您必须使用执行立即命令。此命令用于执行动态生成的代码。

PROCEDURE PR_CALCULO AS

formula   VARCHAR2(32767);
descuento NUMBER;
sueldo    number := 400;

BEGIN
formula := 'begin :result := ' || REPLACE('(salario * 0.0625)', 'salario', sueldo) || '; end;';
dbms_output.put_line(formula);

execute immediate formula using out descuento; --THIS IS THE LINE 38

dbms_output.put_line(descuento);

END PR_CALCULO;

在公式定义中,您可以看到':result'变量,您无需声明它。它是动态代码的本地代码。 然后执行公式,使用使用语句将“动态变量”绑定到“实际变量”。您的结果显然是动​​态代码的输出变量。

最后,如果您在存储公式中的变量之前添加“:”,则可以将代码缩短为

PROCEDURE PR_CALCULO2 AS

formula   VARCHAR2(32767);
descuento NUMBER;
sueldo    number := 400;

BEGIN
formula := 'begin :result := (:salario * 0.0625); end;';

execute immediate formula using out descuento, in sueldo; --THIS IS THE LINE 38

dbms_output.put_line(descuento);

END PR_CALCULO2;

动态变量按从左到右的顺序绑定到实变量:结果是第一个动态变量,因此它绑定到第一个实变量,这是一个out变量。 :salario 这是第二个绑定到第二个变量 sueldo 的变量。 out in out 是从动态代码的角度来看。

希望这有帮助

此致