表如下图需求如下
存储过程一, 传入id参数, 返回解析后的字符串
比如传的id是2, 记录2的统计表达式是3+4, 记录3,4没有统计表达式 所以返回字符串是(3)+(4).再比如传的id 是1, 记录1的统计表达式是2+5+10 返回解析后的字符串是((3)+(4))+(6)+(10), 因为记录2的统计表达式是3+4, 5是6, 要逐层递归, 直到本记录没有统计表达式为止存储过程二, 解析存储过程一传回来的字符串替换其中的数字为特定格式的SQL
比如传回((3)+(4))+(6)+(10) 则最后被替换的结构是
((select en_bbalance from aa where l_item_id = 3) + (select en_bbalance from aa where l_item_id = 4))+
(select en_bbalance from aa where l_item_id = 6)+
(select en_bbalance from aa where l_item_id = 10)烦劳各位了, 帮帮忙, 我以前没写过Oracle存储过程,多谢.

解决方案 »

  1.   

    不好意思,我能看到图呢, 就是一个表 如下VC_ITEM_NAME EN_BBALANCE L_ITEM_ID COUNTSTR
    统计项目1         1         2+5+10
    子统计项目1         2         3+4
    项目1         100         3
    项目2         200         4
    子统计项目2         5         6
    项目1         300         6
    项目10         400         10
      

  2.   

    --创建函数解析表达式
    CREATE OR REPLACE FUNCTION GETSTR(P_STR VARCHAR2) RETURN VARCHAR2 AS
      V_STR  VARCHAR2(2000);
      V_POS  NUMBER;
      V_CHAR VARCHAR2(10);
      V_LSTR VARCHAR2(2000);
    BEGIN
      V_STR := P_STR;
      LOOP
        V_POS := INSTR(V_STR, '+');
        IF V_POS > 0 THEN
          V_CHAR := SUBSTR(V_STR, 0, V_POS - 1);
          V_STR  := SUBSTR(V_STR, V_POS + 1);
        ELSE
          V_CHAR := V_STR;
        END IF;
        SELECT V_LSTR ||
               NVL2(COUNTSTR,
                    '(' || GETSTR(COUNTSTR) || ')',
                    DECODE(INSTR(P_STR, '+'), 0, V_CHAR, '(' || V_CHAR || ')')) ||
               DECODE(V_POS, 0, '', '+')
          INTO V_LSTR
          FROM TEST_A
         WHERE L_ITEM_ID  = V_CHAR;
        EXIT WHEN V_POS = 0;
      END LOOP;
      RETURN V_LSTR;
    END;
    --取得每项已解析表达式
    select getstr(COUNTSTR),COUNTSTR,L_ITEM_ID from test_a where L_ITEM_ID=1;
      

  3.   

    --取得解析SQL
    CREATE OR REPLACE FUNCTION GETSQL(P_STR VARCHAR2) RETURN VARCHAR2 AS
      V_STR  VARCHAR2(200);
      V_POS  NUMBER;
      V_CHAR VARCHAR2(10);
      V_SQL VARCHAR2(200);
    BEGIN
      V_STR := REPLACE(REPLACE(P_STR,'((','('),'))',')');
      V_SQL:=P_STR;
      LOOP
        V_POS := INSTR(V_STR, '+');
        IF V_POS > 0 THEN
          V_CHAR := SUBSTR(V_STR, 0, V_POS - 1);
          V_STR  := SUBSTR(V_STR, V_POS + 1);
        ELSE
          V_CHAR := V_STR;
        END IF;
        V_SQL:=REPLACE(V_SQL,V_CHAR,'(SELECT EN_BBALANCE FROM AA WHERE L_ITEM_ID ='||SUBSTR(V_CHAR, 2, LENGTH(V_CHAR) - 2) || ')'||')');
      EXIT WHEN V_POS = 0;
      END LOOP;
      RETURN V_SQL;
    END;
      

  4.   

    SELECT ID, col1 FROM test1
    ---------------------------
    1 2+5+10
    2 3+4
    5 6
    **********************************************CREATE OR REPLACE FUNCTION getLoopStr(x_id IN NUMBER) RETURN VARCHAR2
      IS
       vc_addFlag  VARCHAR2(1) := '+';
       vn_str      VARCHAR2(100);
       vn_str2     VARCHAR2(100);
       ret_str     VARCHAR2(100);
    BEGIN
        SELECT MAX(col1)
          INTO vn_str
          FROM test1
          WHERE id = x_id;    IF vn_str IS NULL THEN
          RETURN '(' || x_id || ')';
        ELSE
          vn_str2 := vn_str || vc_addFlag;
          FOR i IN 0..length(vn_str) - length(REPLACE(vn_str, vc_addFlag)) LOOP         ret_str := ret_str || vc_addFlag ||  getLoopStr(substr(vn_str2,  1,  instr(vn_str2, vc_addFlag) - 1)) ;         vn_str2 := substr(vn_str2,  instr(vn_str2, vc_addFlag) + 1 );
          END LOOP;
        END IF;
        
        RETURN substr(ret_str, 2);END getLoopStr;**********************************************
    SELECT getloopstr(1), getloopstr(2) FROM dual
    -------------------------------------------
    (3)+(4)+(6)+(10) (3)+(4)