PLSQL, execure formula stored in a table
I'm a newbie in PLSQL. I was ju开发者_运维技巧st wondering if I can save my formula into a table as string and use it in my functions to calculate some values.
Here is an example:
ID NAME FORMULA
1 test prm_testval*prm_percent/18
2 test2 (prm_testval +20)*prm_percent
what I want to do is to select formula column from the table and use the string in my functions
select t.* from table t where id=1
prm_calculated_value = t.formula
I don't want the string value of formula in here, just the formula itself.
Any ideas, If I can use it or not?
The starting point is execute immediate-statement. It's PL/SQL's eval()
.
create table formulas (
id number,
name varchar2(20),
formula varchar2(50)
);
insert into formulas values (1, 'test 1', 'prm_testval*prm_percent/18');
insert into formulas values (2, 'test 2', '(prm_testval +20)*prm_percent');
/* eval from: http://www.adp-gmbh.ch/blog/2005/may/5.html */
create or replace function eval (
expr in varchar2
) return varchar2 as
ret varchar2(32767);
begin
execute immediate 'begin :result := ' || expr || '; end;' using out ret;
return ret;
end;
/
create or replace function eval2 (
vars in varchar2,
expr in varchar2
) return varchar2 as
ret varchar2(32767);
begin
execute immediate vars || ' begin :result := ' || expr || '; end;' using out ret;
return ret;
end;
/
create or replace function calc_prm (
id_ in number,
prm_testval in varchar2,
prm_percent in varchar2
) return number as
formula_ formulas.formula%type;
vars constant varchar2(32767) :=
'declare prm_testval constant number := to_number(' || prm_testval ||
'); prm_percent constant number := to_number(' || prm_percent || ');';
begin
select formula into formula_ from formulas where id = id_;
return eval2(vars, formula_);
end;
/
/* call from SQL */
select eval('3*4') from dual;
select calc_prm(1, 97, 10) from dual;
select calc_prm(2, 97, 10) from dual;
/* call from PL/SQL block */
begin
dbms_output.put_line(eval('3*4'));
dbms_output.put_line(calc_prm(1, 97, 10));
dbms_output.put_line(calc_prm(2, 97, 10));
end;
/
Based on this example you can start building your own way to map symbol values (prm_testval and prm_percent) to real values. Next you might want to have a look into DBMS_SQL.
Beware SQL injection when using client supplied data ! See also e.g. Bobby Tables: A guide to preventing SQL injection.
精彩评论