• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • INSERT语句

    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)] ...
          |
          VALUES row_constructor_list
        }
        [AS row_alias[(col_alias [, col_alias] ...)]]
        [ON DUPLICATE KEY UPDATE assignment_list]
    
    INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
        [INTO] tbl_name
        [PARTITION (partition_name [, partition_name] ...)]
        [AS row_alias[(col_alias [, col_alias] ...)]]
        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] ...)]
        [AS row_alias[(col_alias [, col_alias] ...)]]
        {SELECT ... | TABLE table_name}
        [ON DUPLICATE KEY UPDATE assignment_list]
    
    value:
        {expr | DEFAULT}
    
    value_list:
        value [, value] ...
    
    row_constructor_list:
        ROW(value_list)[, ROW(value_list)][, ...]
    
    assignment:
        col_name = [row_alias.]value
    
    assignment_list:
        assignment [, assignment] ...
    

    INSERT将新行插入到现有表中。的INSERT ... VALUESINSERT ... VALUES ROW()INSERT ... SET形式的语句插入基于明确指定的值的行。该INSERT ... SELECT表单将插入从另一个表或多个表中选择的行。您还可以INSERT ... TABLE在MySQL 8.0.19和更高版本中使用它来插入单个表中的行。如果要插入的行会导致索引或中的值重复INSERT,则带有ON DUPLICATE KEY UPDATE子句的子句可以更新现有行。在MySQL 8.0.19及更高版本中,具有一个或多个可选列别名的行别名可用于引用要插入的行。UNIQUEPRIMARY KEYON DUPLICATE KEY UPDATE

    有关更多信息INSERT ... SELECT,并INSERT ... ON DUPLICATE KEY UPDATE请参见第13.2.6.1,“INSERT ... SELECT语句”和第13.2.6.2,“INSERT ... ON DUPLICATE KEY UPDATE语句”。

    在MySQL 8.0中,DELAYED关键字被服务器接受但被服务器忽略。因此,请参见“ INSERT DELAYED语句”。

    插入表需要该表的INSERT特权。如果使用了该ON DUPLICATE KEY UPDATE子句,而是使用重复的键导致UPDATE执行,则该语句要求UPDATE特权以更新列。对于已读取但未修改的列,您仅需要SELECT特权(例如,仅在子句中col_name=expr赋值的右侧引用的列ON DUPLICATE KEY UPDATE)。

    当插入分区表时,您可以控制哪些分区和子分区接受新行。该PARTITION选项采用表的一个或多个分区或子分区(或两者)的逗号分隔名称列表。如果给定INSERT语句要插入的任何行与列出的分区之一都不匹配,则该INSERT语句将失败,并显示错误“找到与给定分区集不匹配的行”。有关更多信息和示例,请参见“分区选择”。

    您可以使用REPLACE而不是INSERT覆盖旧行。在处理包含重复的旧行的唯一键值的新行时,REPLACE是与之相对应INSERT IGNORE的:新行替换了旧行,而不是被丢弃。请参见“ REPLACE语句”。

    tbl_name是应在其中插入行的表。指定该语句为其提供值的列,如下所示:

    • 在表名后提供一个用逗号分隔的列名的带括号的列表。在这种情况下,VALUES列表,VALUES ROW()列表或SELECT语句必须为每个命名列提供一个值。对于INSERT TABLE表单,源表中的列数必须与要插入的列数匹配。
    • 如果您没有为INSERT ... VALUES或指定列名列表,INSERT ... SELECTVALUES表,SELECT语句或TABLE语句必须提供表中每列的值。如果您不知道表中各列的顺序,请使用查找。DESCRIBE tbl_name
    • SET子句表示列明确地通过名称,与分配每一个的值一起。

    列值可以通过几种方式给出:

    • 如果未启用严格SQL模式,则任何未明确指定值的列都将设置为其默认值(显式或隐式)。例如,如果指定的列列表未命名表中的所有列,则未命名的列将设置为其默认值。“数据类型默认值”中介绍了默认值分配。另请参见“对无效数据的强制约束”。

      如果启用了严格的SQL模式,则如果INSERT语句没有为没有默认值的每个列指定一个显式值,则该语句将生成错误。请参见“服务器SQL模式”。

    • 如果列列表和VALUES列表都为空,则INSERT创建一行并将每列设置为其默认值:

      INSERT INTO tbl_name () VALUES();
      

      如果未启用严格模式,则MySQL对任何没有明确定义默认值的列都使用隐式默认值。如果启用了严格模式,则任何列都没有默认值都会发生错误。

    • 使用关键字DEFAULT将列明确设置为其默认值。这使编写INSERT为少数几个列分配值的语句更加容易,因为它使您避免编写不完整的VALUES列表,该列表不包含表中每个列的值。否则,您必须提供与列表中每个值相对应的列名VALUES列表。
    • 如果将生成的列显式插入,则唯一允许的值为DEFAULT。有关生成的列的信息,请参见“创建表和生成的列”。
    • 在表达式中,您可以用来生成column的默认值。DEFAULT(col_name)col_name
    • expr如果表达式数据类型与列数据类型不匹配,则可能会进行提供列值的表达式的类型转换。给定值的转换可能导致不同的插入值,具体取决于列类型。例如,将所述字符串'1999.0e-2'INTFLOATDECIMAL(10,6),或YEAR柱插入的值199919.992119.992100,或1999,分别。存储在INTYEAR列中的值为1999因为字符串到数字的转换只看了字符串初始部分的多少,才算是有效的整数或年份。对于FLOATDECIMAL列,字符串到数字的转换将整个字符串视为有效的数值。
    • 表达式expr可以引用值列表中先前设置的任何列。例如,您可以执行此操作,因为的值col2是指向的col1,之前已被分配:

      INSERT INTO tbl_name (col1,col2) VALUES(15,col1*2);
      

      但是以下内容是不合法的,因为for的值col1col2,是在之后分配的col1

      INSERT INTO tbl_name (col1,col2) VALUES(col2*2,15);
      

      包含AUTO_INCREMENT值的列会发生异常。由于AUTO_INCREMENT值是在其他值分配之后生成的AUTO_INCREMENT,因此对分配中列的任何引用都将返回a 0

    INSERT使用VALUES语法的语句可以插入多行。为此,请包括多个用逗号分隔的列值的列表,列表用括号括起来并用逗号分隔。例:

    INSERT INTO tbl_name (a,b,c) 
        VALUES(1,2,3), (4,5,6), (7,8,9);
    

    每个值列表必须包含与每行要插入的值一样多的值。以下语句无效,因为它包含一个九个值的列表,而不是三个三个值的列表:

    INSERT INTO tbl_name (a,b,c) VALUES(1,2,3,4,5,6,7,8,9);
    

    VALUEVALUES在这种情况下是的同义词。既不暗示关于值列表的数量,也不暗示每个列表的值的数量。无论是单个值列表还是多个列表,无论每个列表的值数量如何,都可以使用。

    INSERT使用VALUES ROW()语法的语句也可以插入多行。在这种情况下,每个值列表必须包含在ROW()(行构造器)中,如下所示:

    INSERT INTO tbl_name (a,b,c) 
        VALUES ROW(1,2,3), ROW(4,5,6), ROW(7,8,9);
    

    INSERT可以使用ROW_COUNT()SQL函数或mysql_affected_rows()C API函数获得的受影响行值。请参见“信息函数”和“ mysql_affected_rows()”。

    如果您将INSERT ... VALUESINSERT ... VALUES ROW()与多个值列表一起使用或INSERT ... SELECTINSERT ... TABLE,则该语句以以下格式返回信息字符串:

    Records: N1 Duplicates: N2 Warnings: N3
    

    如果使用的是C API,则可以通过调用该mysql_info()函数来获取信息字符串。参见“ mysql_info()”。

    Records指示语句处理的行数。(这不一定是实际插入的行数,因为Duplicates可以是非零。)Duplicates指示由于它们会复制某些现有唯一索引值而无法插入的行数。Warnings表示尝试插入以某种方式出现问题的列值的次数。在以下任何情况下都可能发生警告:

    • 插入NULL到已声明的列中NOT NULL。对于多行INSERT语句或多行语句INSERT INTO ... SELECT,该列设置为列数据类型的隐式默认值。这0用于数字类型,空字符串('')用于字符串类型,而“零”值用于日期和时间类型。INSERT INTO ... SELECT语句的处理方式与多行插入相同,因为服务器不会检查的结果集SELECT以参见其是否返回单行。(对于单行INSERTNULL将其插入到NOT NULL柱。相反,该语句失败并显示错误。)
    • 将数字列设置为超出列范围的值。该值将被裁剪到范围的最接近端点。
    • '10.34 a'给数字列分配一个值。尾随的非数字文本被去除,其余的数字部分被插入。如果字符串值没有前导数字部分,则该列设置为0
    • 插入一个字符串转换成一个字符串柱(CHARVARCHARTEXT,或BLOB),其超过了列的最大长度。该值将被截断为该列的最大长度。
    • 在数据类型非法的日期或时间列中插入一个值。该列设置为该类型的适当零值。
    • 有关INSERT涉及AUTO_INCREMET列值的示例,请参见“使用AUTO_INCREMENT”。

      如果INSERT将行插入到具有AUTO_INCREMENT列的表中,则可以使用LAST_INSERT_ID()SQL函数或mysql_insert_id()C API函数查找用于该列的值。

      注意

      这两个功能的行为并不总是相同的。“信息功能”和“ mysql_insert_id()”中进一步讨论INSERT了关于AUTO_INCREMENT列的语句行为。

    INSERT语句支持以下修饰符:

    • 如果使用LOW_PRIORITY修饰符,则将INSERT延迟执行,直到没有其他客户端从表中读取为止。这包括在现有客户端正在阅读以及INSERT LOW_PRIORITY语句正在等待时开始阅读的其他客户端。因此,发出INSERT LOW_PRIORITY声明的客户可能要等待很长时间。

      LOW_PRIORITY影响使用仅表级锁定仅存储引擎(如MyISAMMEMORY,和MERGE)。

      注意

      LOW_PRIORITY通常不应与MyISAM表一起使用,因为这样做会禁用并发插入。请参见“并发插入”。

    • 如果指定HIGH_PRIORITY,则--low-priority-updates使用该选项启动服务器时它将覆盖该选项的效果。这还会导致不使用并发插入。请参见“并发插入”。

      HIGH_PRIORITY影响使用仅表级锁定仅存储引擎(如MyISAMMEMORY,和MERGE)。

    • 如果使用IGNORE修饰符,则执行INSERT语句时发生的错误将被忽略。例如,如果不IGNORE使用,则复制表中现有UNIQUE索引或PRIMARY KEY值的行将导致重复键错误,并且该语句将中止。使用IGNORE,该行将被丢弃,并且不会发生错误。被忽略的错误会生成警告。

      IGNORE对没有找到与给定值匹配的分区的分区表中的插入有类似的效果。如果不使用IGNORE,则此类INSERT语句会因错误而中止。当INSERT IGNORE被使用时,插入操作默默地失效含有不匹配的值的行,但是行插入被匹配。有关示例,请参见“列表分区”。

      如果IGNORE未指定,将触发错误的数据转换将中止该语句。使用IGNORE,将无效值调整为最接近的值并插入;产生警告,但该语句不会中止。您可以使用mysql_info()C API函数确定实际向表中插入了多少行。

      有关更多信息,请参见 IGNORE关键字和严格SQL模式的比较。

    • 如果指定ON DUPLICATE KEY UPDATE,行插入,将在导致重复值UNIQUE索引或者PRIMARY KEY,一个UPDATE旧行的发生。如果将行作为新行插入,则每行的受影响行值为1;如果更新了现有行,则为2;如果将现有行设置为其当前值,则为0。如果在连接到mysqldCLIENT_FOUND_ROWSmysql_real_connect()C API函数指定了标志,并且将现有行设置为当前值,则受影响的行值为1(而不是0)。请参见“在双重密钥更新语句中插入......”。
    • INSERT DELAYED在MySQL 5.6中已弃用,并计划最终删除。在MySQL 8.0中,DELAYED修饰符被接受但被忽略。使用INSERT(不带DELAYED)代替。请参见“ INSERT DELAYED语句”。