I'do go with something like create or replace function eval (expr varchar2) return number deterministic is l_result number; begin execute immediate 'alter session set cursor_sharing=force'; -- execute immediate 'begin :result := '||expr||'; end;' using out l_result; execute immediate 'select '||expr||' from dual eval_expr' into l_result; execute immediate 'alter session set cursor_sharing=exact'; return l_result; end; / create table formulae (x number, formula varchar2(30)); insert into formulae (x, formula) values (10, 'X + X'); insert into formulae (x, formula) values (10, 'power (X, 2) - X'); SQL> select x, formula, eval ( replace (formula, 'X', x) ) result from formulae; X FORMULA RESULT ---------- -------------------- -------- 10 X + X 20.00 10 power (X, 2) - X 90.00 The two 'alter session set cursor_sharing=..." are there to make eval() library cache friendly - you'll have a single (hard) parse for every formula and you won't pollute the library cache: SQL> select sql_text from v$sql where sql_text like '%eval_expr'; SQL_TEXT ----------------------------------------------------------------------- select :"SYS_B_0" + :"SYS_B_1" from dual eval_expr select power (:"SYS_B_0", :"SYS_B_1") - :"SYS_B_2" from dual eval_expr The commented-out variation using an anonymous block is a possible alternative to avoid reading dual, which would give a negligible improvement and which is useless in 10g anyway, since of course there you won't read dual at all - FAST DUAL: select :"SYS_B_0" + :"SYS_B_1" from dual eval_expr ----------------------------------------------------------------- | 0 | SELECT STATEMENT | | | 2 (100)| | | 1 | FAST DUAL | | 1 | 2 (0)| 00:00:01 | ----------------------------------------------------------------- You can't, of course, avoid dynamic SQL, since the SQL compiler is a static compiler, so it can't "interpret" dynamic components such as the ones in table FORMULAE. HTH Alberto On 3/26/07, Brady, Mark <Mark.Brady@xxxxxxxxxxxxxxxxx> wrote:
Without a UDF…. I have data that is a number and a formula – one row would look like this: select 2 num, 'X + X' formula from dual The formula has 1 variable only but it can be repeated more than once. with data_looks_like_this as (select 2 num, 'X + X' formula from dual) select num, formula, replace(formula, 'X', num) f from data_looks_like_this Column f now has 2 + 2 Can I possibly get a 4? select 2 + 2 from dual does result in 4. It seems you should be able to say treat column f not as a char or a number but as if you saw only what is there. >>> This e-mail and any attachments are confidential, may contain legal, professional or other privileged information, and are intended solely for the addressee. If you are not the intended recipient, do not use the information in this e-mail in any way, delete this e-mail and notify the sender. CEG-IP1
-- Alberto Dell'Era "dulce bellum inexpertis" -- //www.freelists.org/webpage/oracle-l