理解Mysql语句:insert 表名 select null 及 select last_insert_id()

来源:互联网 发布:java 跨域上传文件 编辑:程序博客网 时间:2024/06/08 08:50

一、问题

看代码的时候,在项目的sqlMap.xml里看到了这样语句:

 <insert id="add">         insert <include refid="tableName"/> select null ;        <selectKey resultClass="long" >           select last_insert_id() as ID ;        </selectKey>     </insert>

1.那个select null是什么鬼?

2.在并发环境下,用:select last_insert_id() as ID 不会有问题吗?


二、结果

1.将表的字段值设置为null,不能把select null放到一起看。

2.不会,Mybatis用了ThreadLocal

三、分析

后来仔细看,其实是这样的:

1.批量插入数据的语法

INSERT INTO 表名(字段1, 字段2) SELECT 字段1的值1, 字段2的值1 UNION SELECT 字段1的值2, 字段2的值2 


2.以上语法中:

关键字INTO可以省略,并且项目中我们只单个插入,故可简写为:

<pre name="code" class="sql">INSERT <span style="font-family: Arial, Helvetica, sans-serif;">表名(字段1, 字段2)  </span><span style="font-family: Arial, Helvetica, sans-serif;">SELECT 字段1的值1, 字段</span><span style="font-family: Arial, Helvetica, sans-serif;">2的值1</span>

3.又项目中的表只有主键一个字段,又可简写为

INSERT 表名 SELECT 主键字段的值

4.于是SQL:
insert <include refid="tableName"/> select null ;

的意思就是:把这个表的主键设置为null


5.我们知道主键是唯一且不为空的,在设置了自动递增后,

如果插入时把主键设置为null,它都会不理你,傲娇的继续自增。


6.总结,项目里这么用应该是为了保证自增的连贯性。保证值不被程序修改。

四、用select last_insert_id()的风险

1.只有在主键设置了自动增长的时候可用

2.select last_insert_id()是返回最后一次插入的Id,如果插入了多条,只返回最后执行插入的那条的ID

3.主键设置了自动增长后,如果插入的ID是手动设置的,则select last_insert_id()不会返回当前插入的id,

而是上次通过自动增长插入成功的ID,如下图:




0 0