代码之家  ›  专栏  ›  技术社区  ›  Jimenemex

压缩和子句Oracle SQL

  •  1
  • Jimenemex  · 技术社区  · 6 年前

    我在我们的一个应用程序的一个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');
    
    2 回复  |  直到 6 年前
        1
  •  2
  •   MT0    6 年前

    几乎:

    • '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' “自己,乔” .

    因此,您可以将其替换为:

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

    现在,可能是 “自己,乔” 不是您期望的匹配项(甚至可能不是有效值),您可以将其从列表中删除,但这是您需要确定的。

        2
  •  1
  •   Stew Ashton    6 年前

    你是对的,但感谢你分享那令人惊讶的坏代码。

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

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

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

    但是,由于该代码段只有文本,因此可以用结果进一步替换:

    ,OWN,JO,
    

    是的,似乎整个instr可以被您建议的代码替换,除非aao.acctrolecd可以包含“n,j”或类似的代码,在这种情况下,原始代码和您的代码将得到不同的结果。我很怀疑这是个问题。

    顺祝商祺,Stew