PL/SQL用"+"分割字符串并将其中的数字相加?

and*_*asb 2 sql oracle plsql

CREATE OR REPLACE FUNCTION sumNumbers(p VARCHAR2) RETURN NUMBER IS

...

SELECT sumNumbers('3 + 6 + 13 + 0 + 1') FROM dual;
Run Code Online (Sandbox Code Playgroud)

所以输出应该是: 23

Ale*_*ole 8

您可以使用XML和XPath评估的"技巧"来执行此操作,而无需手动标记字符串:

select * from xmltable('3 + 6 + 13 + 0 + 1' columns result number path '.');

    RESULT
----------
        23
Run Code Online (Sandbox Code Playgroud)

要么:

select to_number(xmlquery('3 + 6 + 13 + 0 + 1' returning content).getStringVal()) as result
from dual;

    RESULT
----------
        23
Run Code Online (Sandbox Code Playgroud)

这可以更灵活,因为可以使用其他运算符:

select * from xmltable('2 * (5 + 7) - 3' columns result number path '.');

    RESULT
----------
        21
Run Code Online (Sandbox Code Playgroud)

它不喜欢使用普通/运算符的除法,div而是需要使用,所以如果源字符串可能包含斜杠,则可能需要对源字符串进行替换:

select * from xmltable('2 * (5 + 7) div 3' columns result number path '.');

    RESULT
----------
         8
Run Code Online (Sandbox Code Playgroud)

阅读有关Oracle的XPath处理XPath数字运算符的更多信息.

你可以直接调用它,没有函数; 但是如果你特别想把它包装在一个函数中,那么因为XPath必须在解析时修复它会更复杂,所以你需要使用动态SQL:

CREATE OR REPLACE FUNCTION sumNumbers(p VARCHAR2) RETURN NUMBER IS
  l_result NUMBER;
BEGIN
  execute immediate q'[select * from xmltable(']'
    || replace(p, '/', ' div ')
    || q'[' columns result number path '.')]'
  into l_result;

  return l_result;
END;
/

SELECT sumNumbers('3 + 6 + 13 + 0 + 1') FROM dual;

               SUMNUMBERS('3+6+13+0+1')
---------------------------------------
                                     23
Run Code Online (Sandbox Code Playgroud)

我已经使用了替代引用机制来避免在语句中转义单引号,尽管我不确定它在这里更清楚.并且我已经包含了replace()以防万一你需要能够划分,但是你不希望它只是直接连接p到SQL语句.有了替换你可以做到:

SELECT sumNumbers('2 * (5 + 7) / 3') FROM dual;
Run Code Online (Sandbox Code Playgroud)

如果你想让它变得灵活,那么这个功能应该有一个不同的名字......

  • 很好,从来没有想过(误)使用XPath. (2认同)