今天在学习时,碰到一个问题:在联表查询取得结果后,如果取得的结果是空值,则给一个默认值,如果不是空值,则返回这个值。

下面我们来看看业务场景:

在menu表中:

存储的是前端页面的菜单配置,注意成员权限管理,报表权限管理和配置工具,这三个菜单是项目管理这个菜单的子菜单,他们通过parent_id这个字段进行关联。

在另外一张映射表project_menu中:

在将菜单归属到具体的项目下时,依然要把配置的父子菜单进行关联,但是在这里关联的id和上面关联的id是不一样的。

现在需求就是,在插入到project_menu表时,需要在插入时将子菜单的parent_id顺带插入其中。如果这个目录不是某个已存在目录的子菜单时,则parent_id默认是0,如果是某个菜单的子菜单,则需要关联表的查询,算出当前子目录的parent_id。

我们来看看一开始错误的写法:

  SELECT IFNULL(id,0) from project_menu where code =
(SELECT code FROM menu where id =
(SELECT parent_id from menu where code = #{menuCode} and parent_id != 0))
AND project_id = #{projectId}

通过表的关联查询,得到当前目录的值,由于mybatis返回的值类型为int,所以如果查询到的值为null时,后台会报错,因此使用了IFNULL()函数,当id为null时,默认返回0。

但是这样做,在调试的时候,mybatis却一直报错该语句尝试返回null但定义的返回类型时int。说明这个函数并没有起作用。那为什么没有起作用呢?

那是因为这条语句的查询结果就是空的,也就是说,当传进来的参数是非子菜单时时,下面这条语句的返回值就是null

  (SELECT parent_id from menu where code = #{menuCode} and parent_id != 0) 

当这条语句返回null时,整条语句的返回值都是空的(where分支比select分支优先执行),这时,等价于下面这条语句:

SELECT IFNULL(id,0) from project_menu where code = NULL

这就不是这个当id为空时,用0替换id返回这个概念了,因为当语句本身就是null时,语句中的函数还会起作用吗?

所以,此方法行不通,附上解决方案:

 SELECT
CASE
WHEN (SELECT parent_id from menu where code = #{code}) = 0
THEN 0
ELSE
(SELECT id from project_menu where code =
(SELECT code FROM menu where id =
(SELECT parent_id from menu where code =#{code} ))
AND project_id=#{projectId})
END

使用条件判断选择语句。亲测有效。

关于MySql中使用IFNULL()函数失效的问题。的更多相关文章

  1. mysql中的ifnull()函数判断空值

    我们知道,在不同的数据库引擎中,内置函数的实现.命名都是存在差异的,如果经常切换使用这几个数据库引擎的话,很容易会将这些函数弄混淆. 比如说判断空值的函数,在Oracle中是NVL()函数.NVL2( ...

  2. MySQL中的IFNULL,IF,NULLIF函数

    MySQL中的IFNULL函数和IF函数 MySQL中的IFNULL函数类似于Oracle中的NVL函数,其表达式为:IFNULL(expr1,expr2),含义是:如果第一个参数不为空,则返回第一个 ...

  3. mysql中isnull,ifnull,nullif的用法

    今天用到了MySql里的isnull才发现他和MSSQL里的还是有点区别,现在简单总结一下: mysql中isnull,ifnull,nullif的用法如下: 1. isnull(expr) 的用法: ...

  4. Mysql中常用的函数汇总

    Mysql中常用的函数汇总: 一.数学函数abs(x) 返回x的绝对值bin(x) 返回x的二进制(oct返回八进制,hex返回十六进制)ceiling(x) 返回大于x的最小整数值exp(x) 返回 ...

  5. Mysql中的常用函数:

    Mysql中的常用函数: 1.字符串函数: (1).合并字符串 concat():// concat('M','y',"SQL",'5.5');== MySQL5.5//当传入的参 ...

  6. Mysql中使用find_in_set函数查找字符串

    mysql有个表的字段的存储是以逗号分隔的,如domain字段login.s01.yy.com,s01.yy.com,s02.yy.com.现在要查找s01.yy.com这个.我们用like查找好像不 ...

  7. mysql中的group_concat函数的用法

    本文通过实例介绍了MySQL中的group_concat函数的使用方法,比如select group_concat(name) . MySQL中group_concat函数 完整的语法如下: grou ...

  8. SQLServer 中实现类似MySQL中的group_concat函数的功能

    SQLServer中没有MySQL中的group_concat函数,可以把分组的数据连接在一起. 后在网上查找,找到了可以实现此功能的方法,特此记录下. SELECT a, stuff((SELECT ...

  9. mysql中的substr()函数

    mysql中的substr()函数和hibernate的substr()参数都一样,就是含义有所不同. 用法: substr(string string,num start,num length); ...

随机推荐

  1. java 压缩导出多个excel

    简单介绍下我实现的功能,首先是我的excel上传,它是以blob字段存储在oracel数据库中的,我实现的是循环遍历blob字段并使用io流进行打包下载,如有需要可自行修改 使用技术有,springM ...

  2. tornado之Hello world

    #!/usr/bin/env python26 #-*- coding:utf8 -*- import tornado.httpserver import tornado.ioloop import ...

  3. tornado之子模板

    #!/usr/bin/env python26 #-*- coding:utf8 -*- import tornado.httpserver import tornado.ioloop import ...

  4. PullToRefreshListView插件初次进入页面自动刷新

    只要将PullToRefreshListView源码中的: @Override protected void onRefreshing(final boolean doScroll) { /** * ...

  5. Fielddata is disabled on text fields by default. Set fielddata=true on [gender] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memor

    ES进行如下聚合操作时,会报如题所示错误: ➜ Downloads curl -XPOST 'localhost:9200/bank/_search?pretty' -d ' { "size ...

  6. jquery.form.js+jquery.validation.js实现表单校验和提交

      一.jquery引用 主要用到3个js: jquery.js jquery.form.js jquery.validation.js 另外,为了校验结果提示本地化,还需要引入jquery.vali ...

  7. 《java.util.concurrent 包源码阅读》26 Fork/Join框架之Join

    接下来看看调用ForkJoinTask的join方法都发生了什么: public final V join() { // doJoin方法返回该任务的状态,状态值有三种: // NORMAL, CAN ...

  8. python学习笔记 map&&reduce

    ---恢复内容开始--- 1.map 1)map其实相当对吧运算符进行一个抽象,返回的是一个对象,但是这里不知道为什么不可以对一个map返回变量打印两次,难道是因为回收了? def f(x): ret ...

  9. 《RabbitMQ Tutorial》第 1 章 简介

    本文来自英文官网,其示例代码采用了 .NET C# 语言. <RabbitMQ Tutorial>第 1 章 简介(Introduction) RabbitMQ is a message ...

  10. mybatis运行时拦截ParameterHandler注入参数

    在实现多租户系统时,每个租户下的用户,角色,权限,菜单都是独立的,每张表里都有租户Id字段 (tenantId),每次做数据库操作的时候都需要带上这个字段,很烦. 现在的需求就是在mybatis向sq ...