如何将一个 table 字段中的表达式计算为另一个字段?
How to evaluate an expression in one table field into another?
我有一个table,里面有一个叫做x的字段,x字段包含'1+2','1+3'等值,如何获取这些值并计算它以及保存到另一个字段?
如果您的公式中只有 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
包)并创建了一个具有单一变量支持的包。
对于简单的算术表达式 - 并且取决于您的 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
如果您提到的情况需要考虑,那么我建议您使用以下查询:
select
xmlquery('3+4'
returning content
).getNumberVal()
from
dual;
如果涉及除 division 以外的更多运算符,则上述查询将有效,但如果还涉及 division 运算符,则必须将“/”替换为“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()
干杯!!
我有一个table,里面有一个叫做x的字段,x字段包含'1+2','1+3'等值,如何获取这些值并计算它以及保存到另一个字段?
如果您的公式中只有 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
包)并创建了一个具有单一变量支持的包。
对于简单的算术表达式 - 并且取决于您的 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
如果您提到的情况需要考虑,那么我建议您使用以下查询:
select
xmlquery('3+4'
returning content
).getNumberVal()
from
dual;
如果涉及除 division 以外的更多运算符,则上述查询将有效,但如果还涉及 division 运算符,则必须将“/”替换为“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()
干杯!!