与 Oracle 11g 中的元组中的 null 进行比较

Comparing against null in a tuple in Oracle 11g

如何检查以下查询中的空值?维护不是问题。查询正在 运行 自动检查是否进行了数据库更改。

SELECT COUNT(*) FROM MSG_TYP_LKUP
  WHERE ((MSG_TYP,NM,SUB_TYP,DIRECT,FORMAT) IN
            (
                    ('setr.005','Cancel to Fund',NULL,'OUT','SWIFT-XML'),
                    ('setr.011','Cancel to Fund',NULL,'OUT','SWIFT-XML'),
                    ('setr.013','Order to Fund',NULL,'OUT','SWIFT-XML'),
                    ('setr.014','Cancel to Fund',NULL,'OUT','SWIFT-XML'),
                    ('setr.016','Order Received','RECE','OUT','SWIFT-XML'),
                    ('setr.016','Order Acknowledgement','STNP','OUT','SWIFT-XML')
            )
     );

最简单的方法可能是为 NULL 插入一个新值。像这样:

SELECT COUNT(*)
FROM MSG_TYP_LKUP
WHERE ((MSG_TYP, NM, COALESCE(SUB_TYP, '<NULL>'), DIRECT, FORMAT) IN
            (
                    ('setr.005','Cancel to Fund', '<NULL>','OUT','SWIFT-XML'),
                    ('setr.011','Cancel to Fund', '<NULL>','OUT','SWIFT-XML'),
                    ('setr.013','Order to Fund', '<NULL>','OUT','SWIFT-XML'),
                    ('setr.014','Cancel to Fund', '<NULL>','OUT','SWIFT-XML'),
                    ('setr.016','Order Received','RECE','OUT','SWIFT-XML'),
                    ('setr.016','Order Acknowledgement','STNP','OUT','SWIFT-XML')
            )
     );

我对这种方法并不满意。但是 Oracle 没有 NULL 安全的比较运算符,所以这可能是最简单的方法。

最安全的方法是显式处理 NULL。代码更长,但执行速度可能更快,并且您不会引入其他问题。 (例如,如果您为 NULL 使用占位符值,您必须 100% 确定它不是数据中的有效值。)

类似

WHERE (MSG_TYP,NM,SUB_TYP,DIRECT,FORMAT) IN
            (
                    ('setr.016','Order Received','RECE','OUT','SWIFT-XML'),
                    ('setr.016','Order Acknowledgement','STNP','OUT','SWIFT-XML')
            )
OR SUB_TYP IS NULL AND (MSG_TYP,NM,DIRECT,FORMAT) IN
            (
                    ('setr.005','Cancel to Fund','OUT','SWIFT-XML'),
                    ('setr.011','Cancel to Fund','OUT','SWIFT-XML'),
                    ('setr.013','Order to Fund','OUT','SWIFT-XML'),
                    ('setr.014','Cancel to Fund','OUT','SWIFT-XML')
            )

此外,您可能应该分解出最后两列,因为要求它们在所有测试中都具有常量值。 Oracle 可以利用它(根据这些列快速过滤掉许多行),但我认为优化器不够智能,无法寻找此类快捷方式。

编辑 我很好奇所以我只是 运行 一个小测试。至少在一个简单的查询(与 OP 非常相似)和 Oracle 12.2.0.1 中,优化器 足够聪明,可以分解出需要在所有比较元组中具有常量值的列在 IN 列表中。