zoukankan      html  css  js  c++  java
  • MySQL-5.7 Insert语句详解

    1.语法

    INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
        [INTO] tbl_name
        [PARTITION (partition_name [, partition_name] ...)]
        [(col_name [, col_name] ...)]
        {VALUES | VALUE} (value_list) [, (value_list)] ...
        [ON DUPLICATE KEY UPDATE assignment_list]
    
    INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
        [INTO] tbl_name
        [PARTITION (partition_name [, partition_name] ...)]
        SET assignment_list
        [ON DUPLICATE KEY UPDATE assignment_list]
    
    INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
        [INTO] tbl_name
        [PARTITION (partition_name [, partition_name] ...)]
        [(col_name [, col_name] ...)]
        SELECT ...
        [ON DUPLICATE KEY UPDATE assignment_list]
    
    value:
        {expr | DEFAULT}
    
    value_list:
        value [, value] ...
    
    assignment:
        col_name = value
    
    assignment_list:
        assignment [, assignment] ...
    

    2.三种常用语法示例

    mysql> desc students;
    +---------+-------------+------+-----+---------+----------------+
    | Field   | Type        | Null | Key | Default | Extra          |
    +---------+-------------+------+-----+---------+----------------+
    | sid     | int(11)     | NO   | PRI | NULL    | auto_increment |
    | sname   | varchar(54) | YES  |     | NULL    |                |
    | gender  | varchar(12) | YES  |     | NULL    |                |
    | dept_id | int(11)     | NO   | MUL | NULL    |                |
    +---------+-------------+------+-----+---------+----------------+
    4 rows in set (0.00 sec)
    
    mysql> select * from students;
    +-----+-------+--------+---------+
    | sid | sname | gender | dept_id |
    +-----+-------+--------+---------+
    |   1 | aaa   | 1      |       2 |
    |   2 | bbb   | 2      |       2 |
    |   3 | ccc   | 3      |       2 |
    +-----+-------+--------+---------+
    3 rows in set (0.00 sec)
    
    mysql> insert into students values(4,'aaaa',1,1);
    Query OK, 1 row affected (0.04 sec)
    
    mysql> insert into students set sid=5,sname='ddd',gender=2,dept_id=1;
    Query OK, 1 row affected (0.03 sec)
    
    mysql> insert into students select * from students_bak;
    

    说明:
    insert...values和insert...set两种语句都是将指定的数据插入到现成的表中,而insert....select语句是将另外表中的数据查出来并插入到现成的表中;

    3.属性说明

    1)Partition
    代表可以将数据插入到指定的表分区中

    2)Tbl_name
    代表将数据插入到目标表

    3)Col_name
    代表要插入指定数据的目标列,如果是多列则用逗号隔开,如果目标表中的某些列没有在Insert语句中指定,则这些列会插入默认值,当然可以使用default显示指定插入默认值

    4)LOW_PRIORITY
    INSERT的执行被推迟到没有其他用户正在读取表。在这种情况下,用户必须等到插入语句完成后,如果表频繁使用,它可能花很长时间。这与INSERT DELAYED让用户马上继续正好相反。
    LOW_PRIORITY和HIGH_PRIORITY仅在MyISAM,MEMORY和MERGE三种存储引擎下才生效。

    5)IGNORE
    表中任何复制一个现有PRIMARY或UNIQUE键的行被忽略并且不被插入。如果你不指定IGNORE,插入如果有任何复制现有关键值的行被放弃。
    当违反主键和唯一键约束条件时不报错只产生警告信息,违反的行被丢弃,而不是整个语句回退;在数据类型转换有问题时也是如此。

    6)DELAYED(5.7版本不再支持,语句不会报错,但会产生警告)
    如果用户不能等到INSERT完成,它是很有用的。当你为日志登录使用MySQL时,而且你也周期性地运行花很长时间完成的SELECT语句,这是一个常见的问题。

    当你使用INSERT DELAYED时,用户将马上准备好,并且当表不被任何其他的线程使用时,行将被插入。
    另一个使用INSERT DELAYED的主要好处是从很多用户插入被捆绑在一起并且写进一个块。这比做很多单独的插入要来的快。

    使用DELAYED时有一些限制:

    • INSERT DELAYED仅适用于MyISAM, MEMORY和ARCHIVE表。对于MyISAM表,如果在数据文件的中间没有空闲的块,则支持同时采用SELECT和INSERT语句。在这些情况下,基本不需要对MyISAM使用INSERT DELAYED。
    • INSERT DELAYED应该仅用于指定值清单的INSERT语句。服务器忽略用于INSERT DELAYED...SELECT语句的DELAYED和INSERT DELAYED...ON DUPLICATE UPDATE语句的DELAYED。
    • 因为在行被插入前,语句立刻返回,所以您不能使用LAST_INSERT_ID()来获取AUTO_INCREMENT值。AUTO_INCREMENT值可能由语句生成。
    • 对于SELECT语句,DELAYED行不可见,直到这些行确实被插入了为止。
    • DELAYED在从属复制服务器中被忽略了,因为DELAYED不会在从属服务器中产生与主服务器不一样的数据。

    7)ON DUPLICATE KEY UPDATE
    如果您指定了ON DUPLICATE KEY UPDATE,并且插入行后会导致在一个UNIQUE索引或PRIMARY KEY中出现重复值,则执行旧行UPDATE。
    当您使用ON DUPLICATE KEY UPDATE时,DELAYED选项被忽略。

    --假设a,b为唯一索引,表table没有1,2这样的行是正常插入数据,冲突时,更新c列的值
    INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=3;
    --或者是
    INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=values(c);
    --引用其他列更新冲突的行
    INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6) ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);
    

    向一个已定义为NOT NULL的列中插入NULL。对于一个多行INSERT语句或INSERT INTO...SELECT语句,根据列数据的类型,列被设置为隐含的默认值。对于数字类型,默认值为0;对于字符串类型,默认值为空字符串('');对于日期和时间类型,默认值为“zero”值。

    INSERT INTO...SELECT的ON DUPLICATE KEY UPDATE

    insert into tbl_name1(a,b,c) 
      select col1,col2,col3 from tbl_name2 
    ON DUPLICATE KEY UPDATE c=values(c);
    

    4.注意事项

    1)Values中除了可以指定确定的数值之外,还可以使用表达式expr

    INSERT INTO tbl_name (col1,col2) VALUES(15,col1*2);  正确
    
    INSERT INTO tbl_name (col1,col2) VALUES(col2*2,15);  错误
    

    2)执行结果
    Insert...values和Insert...select语句执行结果如下:

    Records:100 Duplicates:0 Warnings:0
    

    Records代表语句操作了多少行数据,但不一定是多少行被插入的数据,因为如果存在相同行数据且违反了某个唯一性,Duplicates会显示非0数值;
    warnings代表语句执行过程中的一些警告信息;

    Warnings的一些触发情况:

    • 插入NULL到被声明了NOT NULL的列,列被设置为它的缺省值。
    • 将超出列范围的值设置给一个数字列,值被剪切为范围内适当的端点值。
    • 将数字列设成例如'10.34 a'的值,拖尾的垃圾被剥去并仍然是数字部分被插入。如果值根本不是一个数字,列被设置到0。
    • 把一个字符串插入到超过列的最大长度的一个CHAR、VARCHAR、TEXT或BLOB列中。值被截断为列的最大长度。
    • 把一个对列类型不合法的值插入到一个日期或时间列。列被设置为该列类型适当的“零”值。

    3)Insert...select
    当目标表和select语句中的表相同时,则会将select语句的结果存放在临时表中,再插入到目标表中(注意执行顺序)。

    4)INSERT INTO ... SELECT语句满足下列条件

    • 查询不能包含一个ORDER BY子句。
    • INSERT语句的目的表不能出现在SELECT查询部分的FROM子句,因为这在ANSI SQL中被禁止让从你正在插入的表中SELECT。(问题是SELECT将可能发现在同一个运行期间内先前被插入的记录。当使用子选择子句时,情况能很容易混淆)
    • AUTO_INCREMENT列像往常一样工作。
  • 相关阅读:
    外校培训前三节课知识集合纲要(我才不会告诉你我前两节只是单纯的忘了)
    floyd算法----牛栏
    bfs开始--马的遍历
    (DP 线性DP 递推) leetcode 64. Minimum Path Sum
    (DP 线性DP 递推) leetcode 63. Unique Paths II
    (DP 线性DP 递推) leetcode 62. Unique Paths
    (DP 背包) leetcode 198. House Robber
    (贪心 复习) leetcode 1007. Minimum Domino Rotations For Equal Row
    (贪心) leetcode 452. Minimum Number of Arrows to Burst Balloons
    (字符串 栈) leetcode 921. Minimum Add to Make Parentheses Valid
  • 原文地址:https://www.cnblogs.com/tongxiaoda/p/7908840.html
Copyright © 2011-2022 走看看