如何将一个表字段中的表达式求值到另一表字段中?

时间:2019-06-11 04:18:02

标签: oracle plsql expression-evaluation

我有一张桌子,里面有一个叫做x的字段,x字段包含'1 + 2','1 + 3'等值,如何获取这些值并计算并将其保存到另一个字段中? / p>

3 个答案:

答案 0 :(得分:1)

对于简单的算术表达式-取决于您的Oracle版本-您可以使用xmlquery进行求值。请注意,/在xml中具有特殊含义,除法的运算符是关键字div-因此,如果算术表达式中可能有正斜杠,则需要一个replace。 (如果没有任何除法,则可以通过删除对replace的调用来简化查询。)

这里是一个示例-在with子句中(顶部的测试数据)(解决方案的不是部分!)

with
  test_data (str) as (
    select '1 + 3'       from dual union all
    select '3 * 5 - 2'   from dual union all
    select '2/4*6'       from dual union all
    select '3 * (1 - 3)' from dual
  )
select str, xmlquery(replace(str, '/', ' div ') returning content).getNumberVal() 
            as evaluated_expression
from   test_data;


STR         EVALUATED_EXPRESSION
----------- --------------------
1 + 3                          4
3 * 5 - 2                     13
2/4*6                          3
3 * (1 - 3)                   -6

答案 1 :(得分:0)

如果公式中只有有效的PL / SQL算术表达式,则可以使用EXECUTE IMMEDIATE对其求值。

为此,您需要创建一个函数:

create or replace function eval_expression(p_expression in varchar2)
  return number is
  query  varchar2(100);
  result number;
begin
  query := 'select ' || p_expression || ' from dual';
  execute immediate query
    into result;
  return result;
end eval_expression;

然后您可以在UPDATE查询中使用此功能:

update t 
--val is another field
set t.val = eval_expression(t.x)

自然地,使用EXECUTE IMMEDIATE时,该查询将不会非常高效,但可以使用。此外,对于动态查询,我们将进入不安全的领域,因此请确保您的公式中没有恶意代码。

另外,请参阅Ask TOM上的“ Evaluate Expression”。汤姆·凯特(Tom Kyte)使用了更为文明的方法(dbms_sql软件包),并创建了一个具有单个变量支持的软件包。

答案 2 :(得分:-2)

如果需要考虑您提到的情况,那么我建议您使用以下查询:

select
  xmlquery('3+4'
     returning content
  ).getNumberVal()
from
dual;

如果除除除法外还涉及更多运算符,则上述查询将起作用,但如果除法与除法运算符有关,则必须用“ div”关键字替换“ /”。类似于以下内容:

select
  xmlquery(
  replace( '20/5', '/', ' div ')
     returning content
  ).getNumberVal()
from
dual;

现在,您可以在更新语句中或其他任何地方使用它。

update tab 
set tab.result_column_name = xmlquery(t.your_expr_column_name
         returning content
      ).getNumberVal()

update tab 
set tab.result_column_name = xmlquery(
      replace( t.your_expr_column_name, '/', ' div ')
         returning content
      ).getNumberVal()

Demo

干杯!