如下这张表,包含id和name两列,其中id是主键,name允许为空,存在两条记录,一条是(id=1,name='a'),另一条是(id=2,name=''),

SQL> create table emp(id number primary key, name varchar2(25));
Table created.SQL> select * from emp;ID  NAME
---- -------1  a2

我的问题是,给定具体的id和name值作为检索条件的前提下,如何写出一条通用的SQL同时满足name为空和不为空的场景?

可能很容易想到这条SQL,

SQL> select * from emp where id=:id and name=:name;

如果针对(id=1,name='a')的记录,这条SQL是对的,

SQL> variable id number
SQL> variable name varchar2(25)
SQL> exec :id := 1; :name := 'a';
PL/SQL procedure successfully completed.SQL> select * from emp where id=:id and name=:name;                   ID  NAME
---- -------1  a

但是针对(id=2,name='')的记录,这条SQL是错的,原因就是在Oracle中null=null返回的是false,判断空值,需要使用is null或者is not null,

SQL> exec :id := 2; :name := '';
PL/SQL procedure successfully completed.SQL> select * from emp where id=:id and name=:name;
no rows selected

因此按照理解,改写SQL,此时能同时满足这两种场景,如果:name参数不为空,则会使用name=:name条件,如果:name参数为空,则会使用name is null and :name is null条件,限定检索字段name为空,同时参数:name为空,

SQL> exec :id := 1; :name := 'a';
PL/SQL procedure successfully completed.SQL> select * from emp where id=:id and (name=:name or (name is null and :name is null));ID  NAME
---- -------1  aSQL> exec :id := 2; :name := '';
PL/SQL procedure successfully completed.SQL> select * from emp where id=:id and (name=:name or (name is null and :name is null));ID  NAME
---- -------2

其实,Tom大叔和Darl的经典著作《Oracle编程艺术-深入理解数据库体系结构》中提到了一种更为简单的操作,使用decode函数,

如果decode函数中expr和search相等,则Oracle返回result,如果expr和search不等,则Oracle返回default,若未指定default,则返回空值。

改写SQL,我们看到,无论是(id=1,name='a')的记录,还是(id=2,name ='')的记录,都可以通过该语句得到,

SQL> exec :id := 1; :name := 'a';
PL/SQL procedure successfully completed.SQL> select * from emp where id=:id and decode(name, :name, 1)=1;ID   NAME
----- -------1   aSQL> exec :id := 2; :name := '';
PL/SQL procedure successfully completed.SQL> select * from emp where id=:id and decode(name, :name, 1)=1;ID   NAME
----- -------2

他的精髓就在于,decode函数中,Oracle会认为两个空值是等价的,官方文档的介绍如下,这就解决了(null=null)问题,

In a DECODE function, Oracle considers two nulls to be equivalent. If expr is null, then Oracle returns the result of the first search that is also null.

但是要注意的是,为这条SQL选择索引,只能对id列创建,不能对decode函数创建,因为Oracle不能基于未知的用户输入创建索引数据,

SQL> select * from emp where id=:id and decode(name, :name, 1)=1;

近期热文:

《公众号600篇文章分类和索引》

《Oracle ACE,一段不可思议的旅程》

《Oracle 19c之RPM安装》

《应用执行慢的问题排查路径》

《ACOUG年会感想》

《千万级表数据更新的需求》

《探寻大表删除字段慢的原因》

《一次Oracle bug的故障排查过程思考》

《新增字段的一点一滴技巧》

《对recursive calls的深刻理解》

《《Oracle Concept》第三章 - 12》

《一次惊心动魄的问题排查》

《英超梦幻之行》

《藤子不二雄博物馆之行》

《传控Tiki-Taka战术解惑》

decode函数的妙用相关推荐

  1. decode函数_decode函数的妙用网友的两个问题解答

    <decode函数的妙用>这篇文章中,提到两种写法, SQL> select * from emp where id=:id and (name=:name or (name is ...

  2. 数据库中自定义排序规则,Mysql中自定义字段排序规则,Oracle中自定义字段排序规则,decode函数的用法,field函数的用法

    数据库中自定义排序 场景:有一张banner表,表中有一个status字段,有0, 1, 2三个状态位,我想要 1,0,2的自定义排序(这里是重点),然后再进行之上对sequence字段进行二次排序( ...

  3. mysql sql decode函数用法_oracle中的decode的使用介绍

    含义解释: decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值) 该函数的含义如下: IF 条件=值1 THEN RETURN(翻译值1) ELSIF 条件=值2 THE ...

  4. oracle decode一个值对应多个值,如何使用Oracle的Decode函数进行多值判断

    Decode函数的语法结构如下: decode (expression, search_1, result_1) decode (expression, search_1, result_1, sea ...

  5. 先随机后排序的oracle,Oracle用decode函数或CASE-WHEN实现自定义排序

    Oracle用decode函数或CASE-WHEN实现自定义排序 1 问题 对SQL排序,只要在order by后面加字段就可以了,可以通过加desc或asc来选择降序或升序.但排序规则是默认的,数字 ...

  6. SQL中 decode()函数简介

    今天看别人的SQL时看这里面还有decode()函数,以前从来没接触到,上网查了一下,还挺好用的一个函数,写下来希望对朋友们有帮助哈! decode()函数简介: 主要作用:将查询结果翻译成其他值(即 ...

  7. decode函数python在哪里_Python基础知识——encode和decode函数

    以前我们介绍过,Python2.x中默认的编码的基础类型是unicode编码的类型,在Python3.x才转化为基于unicode的字符串. 那么我们在Python2.x的学习中就会遇到各种各样的编码 ...

  8. oracle中创建函数行变列,oracle decode 函数实现行转列

    用decode函数,或者case when实现行转列 Oracle ----创建测试表create table student_score( name varchar2(20), subject va ...

  9. python中的encode()和decode()函数

    对于很多人来说,python的中字符转码是一件很头疼的事情,本来期望结果输出的是中文,结果来一段像这样\xe4\xbd\xa0\xe5\xa5\xbd像是乱码的字符串. 由于学python没多久,昨天 ...

最新文章

  1. DEAP:使用生理信号进行情绪分析的数据库(二、实验设计与主观分析)
  2. 微信公众开发api接口
  3. 剑指offer 66题 -- 删除链表中重复的节点
  4. python 闭包_Python中的闭包
  5. C#设计模式之4-原型模式
  6. 360搭建windows补丁服务器
  7. 浏览器文件服务器计算器设置,【魅蓝 U20使用总结】界面|浏览器|计算器|设置_摘要频道_什么值得买...
  8. 关于印发南山区引进高层次医学团队管理办法的通知
  9. 动态二维码刷卡触摸按键门禁一体机性能与选型攻略
  10. OSPF特殊区域及其他特性
  11. 洛谷 #2197. Nim游戏
  12. uniapp登录授权获取微信手机号组件封装
  13. 拾人牙慧,浅记一些C++的类
  14. 关于tkinter的的布局管理pack()篇
  15. Eclipse中XML文件以表格形式显示
  16. java中listFiles(Filefilter filter)文件过滤器的实现过程
  17. Binder机制原理、源码、AIDL,IBinder,Binder,IInterface,BinderDriver,需要的都在这里了
  18. 齐博CMS1.0全版本的sql注入漏洞
  19. pink老师HTML5+CSS3学习笔记 | DAY9
  20. OA系统之操作系统和浏览器常识

热门文章

  1. PHP框架中的设计模式-工厂模式(简单工厂)|Simple Factory Pattern-ThinkPHP v3.2
  2. 25.2.3.35. mysql_init() http://www.cnblogs.com/ymy124/archive/2012/04/03/2430808.html
  3. slow down用法
  4. 【 数字后面的f是什么意思】
  5. upupw 本地配置ssl 证书 使用https
  6. 全网最全linux Csa 文件创建,删除的方法,教你五分钟掌握干货
  7. 增长量计算n+1原则_【岗位能力干货】:速速收藏!资料分析常见名词与干货!...
  8. Singleton Patten
  9. Y9000p/y7000p/R7000p/R9000P(2021) ubuntu 18.04 MT7921 解决无wifi (联发科mt7921无线网卡)
  10. FBI都无法破解的iOS设备也会失陷?App store 超千个APP被爆漏洞