与 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
列表中。
如何检查以下查询中的空值?维护不是问题。查询正在 运行 自动检查是否进行了数据库更改。
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
列表中。