需要oracle sql查询中动态计算的帮助吗

需要oracle sql查询中动态计算的帮助吗,sql,oracle,Sql,Oracle,我有一个表tab_1,其中包含以下值 ID Calculation value 1 10 2 10 3 1+2 4 5 5 3-2 6 5+1 需要为以下逻辑编写查询的帮助。我有一个表,其中记录包含计算字符串或用于计算的值。我需要像这样解析计算: ID 3 is the sum of ID 1 and 2. ID 5 is the minus of

我有一个表tab_1,其中包含以下值

ID Calculation value
1                10
2                10
3    1+2         
4                 5
5    3-2          
6    5+1
需要为以下逻辑编写查询的帮助。我有一个表,其中记录包含计算字符串或用于计算的值。我需要像这样解析计算:

ID 3 is the sum of ID 1 and 2.
ID 5 is the minus of ID 3 and 2.
ID 6 is the sum of ID 5 and 1.
SQL>  select dyn_calc(6) from dual;

DYN_CALC(6)
-----------
20

SQL>
然后,我需要选择引用ID的记录并执行计算。我的 预期产出:

ID Calculation value
3    1+2         20
5    3-2         10
6    5+1         20
谢谢-SQL中的nani

在Oracle中:

需要帮助为下面的逻辑编写查询

这不是纯SQL可以解决的问题,因为:

执行计算字符串需要动态SQL 您需要递归来查找记录并评估结果 下面是一个递归函数,它生成您期望的答案。它有三个私有进程,因此函数的主体很容易理解。在伪代码中:

查阅记录 若记录为值,则返回它并退出 其他爆炸计算 对分解计算的每个部分递归1、3、4,直到2 抱歉需要滚动:

create or replace function dyn_calc
     (p_id in number)
      return number
is 
    result number;
    n1 number;
    n2 number;
    l_rec t23%rowtype;
    l_val number;

    type split_calc_r is record (
        val1 number
        , operator varchar2(1)
        , val2 number
    );
    l_calc_rec split_calc_r;

    function get_rec
        (p_id in number)
        return t23%rowtype
    is 
        rv t23%rowtype;
    begin
        select *
        into rv   
        from t23
        where id = p_id;
        return rv;
    end get_rec;    

    procedure split_calc
       (p_calc in varchar2
        , p_n1 out number
        , p_n2 out number
        , p_operator out varchar2)
    is
    begin
         p_n1 := regexp_substr(p_calc, '[0-9]+', 1, 1);
         p_n2 := regexp_substr(p_calc, '[0-9]+', 1, 2);
         p_operator := translate(p_calc, '-+*%01923456789','-+*%'); --regexp_substr(p_calc, '[\-\+\*\%]', 1, 1);
    end split_calc;

    function exec_calc 
        (p_n1 in number
          , p_n2 in number
          , p_operator in varchar2)
        return number
    is 
        rv number;
    begin
        execute immediate
            'select :n1 ' ||  p_operator ||  ' :n2 from dual'
            into rv
            using p_n1, p_n2; 
        return rv;
    end exec_calc;    

begin
    l_rec := get_rec(p_id);

    if l_rec.value is not null then
        result := l_rec.value;
    else        
         split_calc(l_rec.calculation
                     , l_calc_rec.val1
                     , l_calc_rec.val2
                     , l_calc_rec.operator);
         n1 := dyn_calc (l_calc_rec.val1);
         n2 := dyn_calc (l_calc_rec.val2);
         result := exec_calc(n1, n2, l_calc_rec.operator);
    end if;

    return result;
end;
/
像这样跑:

ID 3 is the sum of ID 1 and 2.
ID 5 is the minus of ID 3 and 2.
ID 6 is the sum of ID 5 and 1.
SQL>  select dyn_calc(6) from dual;

DYN_CALC(6)
-----------
20

SQL>
或者,要完全按照您的要求获得输出:

select id, calculation, dyn_calc(id) as value
from t23
where calculation is not null;
注释

没有异常处理。如果数据无效,函数就会爆炸 split_calc proc使用translate而不是regex来提取运算符。这是因为regexp\u substrp\u calc,“[\-\+\*\%]”,1,1神秘地吞下了-。这似乎是一个与环境相关的bug。因此,将此函数扩展到进程1+4+2将很尴尬。
以下是。

用例说明您能否提供预期结果。我可以帮你找到query@ViKiNG-案例陈述究竟如何帮助解决这个问题?@APC。。对不起,迟了答复。案例的意思是,正如超级用户在下面的回答中所建议的那样?我也在考虑这些问题。总是两个操作数吗?那么,最好将id1、运算符和id2存储在单独的列中,而不是存储在一个字符串中。在ID为5和6的情况下,此sql无法工作。我只是在sql上键入而没有检查它。让我尝试粘贴youQuery的精确查询选择“ID”+castID as varchar10+'是“+case,当计算方式为“%-%”时,是“+”,当计算方式为“%+%”时,是“减号”,然后是ID的“sum”END+“+replaceColution”+、“and”、“-”,'和'test.tab1中的值,其中计算值不为null,计算输出-值ID 3是ID 1和2的和ID 5是ID 3的负数,2 ID 6是ID 5和1的和谢谢,抱歉造成混淆。添加了预期的输出。SQL中的部分错误。首先是因为Oracle使用SQL,其次是因为在SQL查询语言中,字符串连接运算符是| | not+@viking,谢谢。这是其中的一件事,一旦我和它搏斗了15分钟,我就必须坚持到底。我没有太多机会在日常工作中使用递归,所以这是一个受欢迎的练习。