MySQL插入/更新数据时,要求不重复


一、插入数据时

当插入数据时,要求数据表的某一列(比如name)不重复,语法如下:

INSERT INTO TABLE (field1, field2, fieldn) SELECT
    'field1',
    'field2',
    'fieldn'
FROM
    DUAL
WHERE
    NOT EXISTS (
        SELECT
            field
        FROM
            TABLE
        WHERE
            field = ?
    )

注意:DUAL就是固定的参数,不是某一个表的名字,DUAL表示一张虚拟表!!!可以参考:insert not exists的问题

实战:

insert into user (id, name, age) 
select 11, "lisi", 45 from DUAL 
where not exists (select name from user where name="lisi"); 

 其中,select name from 也可以改为select 1 from,理由见篇尾

由于user表中,之前就有 name = "lisi",所以执行上面的SQL语句之后,结果为:

显示为,并没有执行插入操作。

二、更新操作时

更新操作时,如下:

update user
    <set>
        <if test="name != null">
            `name` = #{name,jdbcType=VARCHAR},
        if>
        <if test="age != null">
            age = #{age,jdbcType=INTEGER}
        if>
    set>
    where id = #{id,jdbcType=INTEGER}
        <if test="name != null">
            AND NOT EXISTS (select 1 from (select 1 from user where `name`=#{name,jdbcType=VARCHAR}) a)
        if>

至于为啥要在 where中用两层 select,是因为:

  MySql的特性:若需要修改某个表,则不能再拿这个表作为子查询的条件(同一个sql语句中,其实可以理解,保证不会读到脏数据)。这句话再通俗点说,修改的表和后面子查询的表是同一张表的话,将被判定异常。
??我们通过嵌套一层,让mysql识别后面子查询的表是“a”,而不是“user”表,那么mysql就不会判定异常!

注:select 1 from 中的1是一常量(可以为任意数值),查到的所有行的值都是它,但从效率上来说,1>xxx>*,因为不用查字典表。

从作用上来说:

select 1 from table;
select xxx(表集合中的任意一行) from table;
select * from table

三者是没有差别的,都是查看是否有记录,一般是作条件查询用的,结果: