压缩 AND 子句 Oracle sql

Condense AND clause Oracle sql

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

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

它正在查看 'OWN''JO' 是否在 aao.AcctRoleCd 中。如果是,则 INSTR 将导致其在字符串中的索引,因此它将大于 1。所以 AND 子句将是 true.

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

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

差不多:

  • 'OWN, JO' 是文本文字。
  • REPLACE('OWN, JO', ' ', NULL) 只是从给出 'OWN,JO'.
  • 的字符串中去掉 space
  • ',' || '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' 可能不是您期望的匹配项(或者甚至可能不是有效值),您可以将其从列表中删除,但这是您需要确定的.

您是对的,但感谢您分享令人惊讶的糟糕代码。

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

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

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

但是,由于该片段只有文字,因此可以用结果进一步替换它:

,OWN,JO,

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

问候,斯图