微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Oracle 为动态 SQL 创建公式以防止被零除

如何解决Oracle 为动态 SQL 创建公式以防止被零除

我有一个带有公式列的表,该表具有可获取到动态 sql LIKE n5/n14+n3

的公式

我的问题是当公式有除法时,我应该尝试转换公式以防止错误divide by zero

我目前的想法是将公式转换为CASE,当它有神圣时,例如n5/n14+n3CASE WHEN n14 = 0 THEN 0 ELSE n5/n14+n3 END

但我只能在公式只有 1 个除法的情况下进行转换,并且在公式有 > 1 个除法(例如 n5/n4+n3/n2,或公式除以表达式(例如 n5/(n4+n3))的情况下无法转换。

有人能解决这个问题吗?

WITH tmp AS 
(
    SELECT 'n5/n14+n3' AS formula FROM dual UNION ALL 
    SELECT 'n5/n14+n3/n1-n2' AS formula FROM dual UNION ALL 
    SELECT 'n8/(n17*n6)-n5/n4+n3/n1-n2' AS formula FROM dual UNION ALL 
    SELECT 'n5/(n14+n3*n2)-n1' AS formula FROM dual 
)
SELECT
    formula,CASE
         WHEN formula NOT LIKE '%/%' OR REPLACE(formula,' ','') LIKE '%/(%' OR (LENGTH(formula) - LENGTH(REPLACE(formula,'/',''))) > 1 THEN  formula
         ELSE 'CASE WHEN ' || SUBSTR(REGEXP_SUBSTR(REPLACE(formula,''),'/(n\d+)'),2) || ' = 0 THEN 0 ELSE ' || formula || ' END'
     END AS formula1,'CASE WHEN ' || SUBSTR(REGEXP_SUBSTR(REPLACE(formula,2) || ' = 0 THEN 0 ELSE ' || formula || ' END' AS formula2
 FROM tmp t;

当前结果不是预期的输出(只有第 1 行解决除以零错误):

formula                     formula1                                    formula2
n5/n14+n3                   CASE WHEN n14 = 0 THEN 0 ELSE n5/n14+n3 END CASE WHEN n14 = 0 THEN 0 ELSE n5/n14+n3 END                
n5/n14+n3/n1-n2             n5/n14+n3/n1-n2                             CASE WHEN n14 = 0 THEN 0 ELSE n5/n14+n3/n1-n2 END          
n8/(n17*n6)-n5/n4+n3/n1-n2  n8/(n17*n6)-n5/n4+n3/n1-n2                  CASE WHEN n4 = 0 THEN 0 ELSE n8/(n17*n6)-n5/n4+n3/n1-n2 END
n5/(n14+n3*n2)-n1           n5/(n14+n3*n2)-n1                           CASE WHEN  = 0 THEN 0 ELSE n5/(n14+n3*n2)-n1 END           

   

解决方法

您可以使用 NULLIF() 来防止错误。结果将是 NULL

(
    SELECT 'n5/nullif(n14,0)+n3' AS formula FROM dual UNION ALL 
    SELECT 'n5/nullif(n14,0)+n3/nullif(n1,0)-n2' AS formula FROM dual UNION ALL 
    SELECT 'n8/nullif(n17*n6,0)-n5/nullif(n4,0)-n2' AS formula FROM dual UNION ALL 
    SELECT 'n5/nullif((n14+n3*n2,0)-n1' AS formula FROM dual 
)
,

感谢@Linoff 先生的建议,我确实使用`` 来使用 NULLIF 来获取和转换公式

WITH tmp AS 
(
    SELECT 'n5/n14+n3' AS formula FROM dual UNION ALL 
    SELECT 'n5/n14+n3/n1-n2' AS formula FROM dual UNION ALL 
    SELECT 'n8/(n17*n6)-n5/n4+n3/n1-n2' AS formula FROM dual UNION ALL 
    SELECT 'n5/(n14+n3*n2)-n1' AS formula FROM dual 
)
SELECT formula,REGEXP_REPLACE(REPLACE(formula,' ',''),'\/(n\d+)|\/(\([^\)]*\))','/NULLIF(\1\2,0)') AS formula1
FROM tmp;

结果:

formula                     formula1                                    
n5/n14+n3                   n5/NULLIF(n14,0)+n3                                     
n5/n14+n3/n1-n2             n5/NULLIF(n14,0)+n3/NULLIF(n1,0)-n2                     
n8/(n17*n6)-n5/n4+n3/n1-n2  n8/NULLIF((n17*n6),0)-n5/NULLIF(n4,0)-n2
n5/(n14+n3*n2)-n1           n5/NULLIF((n14+n3*n2),0)-n1                             

                     
,
  • 用 Java 编写一个解析器来解析您的表达式(或使用现有的解析器)。
  • 编写一个静态 Java 函数,将解析器生成的抽象语法树转换为您需要的输出,并用 NULLIFCASE 表达式将除法中的每个分母包装起来,以防止被零除引发异常。
  • 使用 loadjava utility 将其加载到数据库中。
  • 编写一个 PL/SQL 函数来包装 Java 函数。
  • 使用 PL/SQL 函数将您的动态代码转换为更安全的代码。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?