oracle 中 parent_id = null 的变通实现

今有一表

node
id编号
parent_id父节点
name名称

自联接, 若没有父节点, parent_Id 的取值为 NULL, 而不能是 0, 因为不存在编号为 0 的节点.

SELECT * FROM node 

START WITH parent_id IS NULL

CONNECT BY PRIOR id=parent_id

可以按层次查出所有节点.

现在,如果要查从 1 的子节点,查询形如

SELECT * FROM node

START WITH parent_id = 1

CONNECT BY PRIOR id = parent_id

考虑提供参数化查询,  则此处 1 和 NULL 应为变量.

SELECT * FROM node

START WITH parent_id = :parent_id

CONNECT BY PRIOR id = parent_id

这时,提供参数为 NULL, 会发现查不出任何记录. 原因是在 Oracle 的世界观里, NULL 是无法比较的, 因为 NULL <> NULL.

使用 IN 能不能解决问题呢? 因为 IN 其实是对 (,,,) 中的各个散值进行遍历比较, 效果和 = 是一样的.写成 IN( NULL) 也查不出记录.

经过对 NULL 的多方了解, 我发现, NULL - <N> = NULL, 也就是说, NULL 减任何数都是 NULL. 据此悟出如下方法:

SELECT * FROM node

START WITH nvl(parent_id - :parent_id / 2, 0) = :parent_id / 2

CONNECT BY PRIOR id = parent_id

当提供 0 作为参数时, 相当于 null.

该方法的重点是表达式 START WITH nvl(parent_id - :parent_id / 2, 0) = :parent_id / 2

当给定参数为 0 时, 右边值为 0 , 要求左边值为 0 条件才满足, 而 nvl(x, 0) = 0 的 x 仅能取 NULL 和 0.

考虑到 X 为 parent_id - 0, 故仅当 parent_id  为 NULL 时,等式才成立.

当给定参数为非 0 数字 n 时, 等式成立的前提是 nvl (x, 0) = <n / 2>, 此时, x 为 NULL 不能使等式成立.

亦即,仅当 parent_id - parent_id / 2 = parent / 2 时,等式才会成立.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值