sql - PL/SQL 将一个字符串按 "+ "拆分并将其中的数字相加?

标签 sql oracle plsql

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

...

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

所以输出应该是:23

最佳答案

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

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

    RESULT
----------
        23

或者:

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

    RESULT
----------
        23

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

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

    RESULT
----------
        21

虽然它不喜欢使用普通的 / 运算符进行除法,但您需要使用 div 来代替,因此您可能需要对源字符串进行替换如果它可能包含斜杠:

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

    RESULT
----------
         8

阅读更多关于 Oracle's XPath handling 的信息, 和 XPath numeric operators .

你可以直接调用它,不需要函数;但是如果你特别想把它包装在一个函数中,它会稍微复杂一些,因为 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

我用过 the alternative quoting mechanism以避免在语句中转义单引号,但我不确定这里是否更清楚。我已经包含了 replace() 以防你需要能够除法,但如果你不想要它,那么只需将 p 直接连接到 SQL 语句中.通过替换,您可以执行以下操作:

SELECT sumNumbers('2 * (5 + 7) / 3') FROM dual;

如果你想让它变得灵活,函数应该有一个不同的名字......

关于sql - PL/SQL 将一个字符串按 "+ "拆分并将其中的数字相加?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36884473/

相关文章:

oracle - 输入重复序列号时增加数量字段

sql - pl/sql 上的序列

sql - 在 Oracle 中连接和分组多行

java - 第一次使用preparedStatement,它不断向我发送异常。代码审查

html - 有人能告诉我为什么这段代码不起作用吗?

sql - 如何在 COUNT() 聚合中包含零?

database - 使用虚拟列导出架构

c# - 需要以 C# 字符串数据类型 "as is"获取 Oracle RAW

php - 如何使用 PHP PDO 运行 Transact-SQL

sql - 无法找到每个月的最大值