一、插入數據時
當插入數據時,要求數據表的某一列(比如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語句之后,結果為:
顯示為,並沒有執行插入操作。
附:(mapper.xml)
<insert id="save" parameterType="com.test.DataSourceTemporaryGroup" useGeneratedKeys="true" keyProperty="id"> insert into data_source_temporary_group(name, jimdb_id, jimdb_name, jimdb_type, creator, modifier, create_time, modify_time) select #{name,jdbcType=VARCHAR}, #{jimdbId,jdbcType=BIGINT}, #{jimdbName,jdbcType=VARCHAR}, #{jimdbType,jdbcType=VARCHAR}, #{creator,jdbcType=VARCHAR}, #{creator,jdbcType=VARCHAR}, now(), now() from DUAL where not exists (select 1 from data_source_temporary_group where name = #{name,jdbcType=VARCHAR}) </insert>
二、更新操作時
更新操作時,如下:
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
三者是沒有差別的,都是查看是否有記錄,一般是作條件查詢用的,結果: