浅谈 Mysql DUAL

235 阅读2分钟

最近一直在完成公司的项目,临近项目上线,老大交代了任务,构建一个初始化的脚步,基于这个脚步创建初始化的管理员角色和用户,然后让系统上线正式使用,于是用到了dual,和大家分享一下。

使用场景

开头想用sql实现插入Admin角色,但是插入之前判断一下这个角色是否存在,如果存在的话就不创建了,下模拟一下表结构:

id(角色id)role_name(角色名称)
1admin
2simple

尝试

所以想当然的开始写sql

insert into role(role_name) values("admin") where not exists(select id from role where role_name = "admin");

所以报错了,并且是语法错误,再where哪里报的,有点不甘心,把where语句部分去掉,发现没有问题了,所以第一个问题出现再where这里,仔细琢磨,没有搞明白,所以就上网查了一下:发现insert values语句本身是没有办法和where语句结合的,因为insert value只是往表里插入一个固定的值,而where代表从数据库当中定位数据,前提是这个数据存在,所以插入的时候是没有办法结合where(个人理解大概是这个意思,欢迎各位大佬指点。),至于update或者select支持where。

了解到这里,结合自己的需求,很显然,update是不可用的,那么剩下的就是select了,如果我可以构建一个和角色表结构一样的表,然后,插入admin是不是可以呢,思路如下:

create table role1 like role;
​
insert into role(role_name) select role_name from role1 where not exists(select id from role where role_name = "admin");

效果有了,但是,发现又有一张新的表role1需要维护,并且在初始化之后role1表就不存在了,基于代码逻辑role1也感觉乖乖的,所以接着琢磨查询,结合查询的案例进行了调整:

insert into role(role_name) select "admin" from dual where not exists(select id from role where role_name = "admin");

结果成了,并且也没有再生成一张叫dual的表。

DUAL

写完脚本,就想着总结一下dual,首先从官方文档翻到了这句话:

You are allowed to specify DUAL as a dummy table name in situations where no tables are referenced:

大(翻)概(译)意(软)思(件)如下:

在没有引用表的情况下,可以将DUAL指定为伪表名:

嗯,明白了,DUAL就是给大家在没有引用表之前做查询的一个虚表,比如之前写过的语句:

select 1*2 
//改写成
select 1*2 from dual

当然在这样的案例常见当中,不是dual也是可以的,但是在我们上面的常见当中,不适用dual锁定数据的来源是没有办法和insert语句以及where语句连用的。

关于dual先总结到这列,欢迎各位大佬多多指点。