【问题标题】:Condense AND clause Oracle sql压缩AND子句Oracle sql
【发布时间】:2018-12-06 10:48:57
【问题描述】:

我在我们的一个应用程序的一个 sql 脚本中遇到了这个问题。我注意到它在其他各个地方都有使用,但它不只是检查项目的存在吗?

AND INSTR((SELECT (',' || REPLACE('OWN, JO', ' ', NULL) || ',') b FROM DUAL),
         (',' || aao.AcctRoleCd || ',')) > 0

它在哪里寻找'OWN''JO' 是否在aao.AcctRoleCd 中。如果是,那么INSTR 将导致它在字符串中的索引,所以它会大于一。所以AND 子句将是true

这样检查一个项目是否存在不是很糟糕吗? IN 子句的更多内容会更好吗?

AND aao.AcctRoleCd IN ('OWN', 'JO');

【问题讨论】:

    标签: oracle in-clause


    【解决方案1】:

    差不多:

    • 'OWN, JO' 是文本字面量。
    • REPLACE('OWN, JO', ' ', NULL) 只是从字符串中去掉空格,给出'OWN,JO'
    • ',' || 'OWN,JO' || ',' 只是将逗号连接到字符串的开头和结尾,给出',OWN,JO,'
    • (SELECT ',OWN,JO,') b FROM DUAL) 是多余的,你可以使用前面的文本文字。
    • INSTR( ',OWN,JO,', (',' || aao.AcctRoleCd || ',') ) > 0 正在寻找等于 aao.AcctRoleCd 的子字符串开头和结尾的逗号,因此可以匹配 'OWN''JO''OWN,JO'

    所以你可以将其替换为:

    AND aao.AcctRoleCd IN ( 'OWN', 'JO', 'OWN,JO' )
    

    现在,'OWN,JO' 可能不是您期望的匹配项(或者甚至可能不是有效值),您可以将其从列表中删除,但这是您需要确定的。

    【讨论】:

    • 是的,在这种情况下'OWN,JO' 可以被删除,因为aao.AcctRoleCd 只能有一个值。它必须是'OWN''JO',或其他一些代码,但只有一个是有效的。所以我想用IN 子句替换它是安全的。
    【解决方案2】:

    您是对的,但感谢您分享这么糟糕的代码。

    (SELECT (',' || REPLACE('OWN, JO', ' ', NULL) || ',') b FROM DUAL)
    

    是一个完全不必要的标量子查询。可以换成

    ',' || REPLACE('OWN, JO', ' ', NULL) || ','
    

    但是,由于 sn-p 只有文字,因此可以进一步替换为结果:

    ,OWN,JO,
    

    是的,似乎整个 INSTR 可以用您建议的代码替换,除非 aao.AcctRoleCd 可能包含“N,J”或类似的内容,在这种情况下,原始代码和您的代码会得到不同的结果。我严重怀疑这是个问题。

    最好的问候,炖菜

    【讨论】:

    • 谢谢,在我的例子中,'OWN''JO' 是作为参数查询传入的,但我只是以 'OWN''JO' 为例。
    • 这在技术上是不正确的,因为aao.AcctRoleCd IN ( 'OWN', 'JO') 与 OP 的原始代码不同,它可以匹配 3 个值('OWN''JO''OWN,JO')。但是,如果aao.AcctRoleCd 列上存在阻止字符串中逗号的限制(或其他类似限制),则它可能足够接近。
    猜你喜欢
    • 1970-01-01
    • 2011-12-13
    • 2021-10-21
    • 2023-03-31
    • 2014-06-17
    • 1970-01-01
    • 2019-01-06
    • 1970-01-01
    • 2016-04-25
    相关资源
    最近更新 更多