我在课堂上解释INSERT语句的细微差别以及是否应该使用命名符号或位置符号时,会醒大家注意表中的强制(NOT NULL约束)和可选(可为空)列,以及当语句未将值插入到该列时,语句如何INSERT要求NULL可选列的显式值INSERT。
然后,我问是否有人可以限定不同类型的INSERT陈述;当新的 DBA 决定重构表并在新表结构中使用and列顺序时,如果具有first_nameandlast_name列顺序的表发生变化,会发生什么情况。只有几个学生记得在表名和子句之间使用了列列表,但没有人记得如何编写语句。last_namefirst_nameVALUESINSERT-SET
下面是使用列列表和SET子句插入数据的快速示例。它构建了一个actor表,其中有一actor_id列作为代理键和主键列,以及一个由名字和姓氏列组成的唯一自然键(不是真实世界的唯一性解决方案)。
CREATE TABLE actor
( actor_id int unsigned primary key auto_increment
, first_name varchar ( 30 ) not null
, last_name varchar ( 30 ) not null
, CONSTRAINT actor_uq UNIQUE ( first_name , last_name ) ) ;
接下来,让我们使用列列表方法插入几行。column-list 是一个逗号分隔的列值列表,必须包含所有必需的列,也可能包含可选的列。
INSERT INTO actor
( first_name
, last_name )
VALUES
( 'Harrison' , 'Ford' )
, ( 'Carrie' , 'Fisher' )
, ( 'Mark' , 'Hamill' )
, ( 'Alec' , 'Guinness' ) ;
现在,让我们通过尝试将第二个Harrison Ford插入到 actor 表中来验证对名字和姓氏复合值的唯一约束。
INSERT INTO actor
( first_name , last_name )
VALUES
( 'Harrison' , 'Ford' ) ;
它失败并引发以下错误:
ERROR 1062 (23000): Duplicate entry 'Harrison-Ford' for key 'actor.actor_uq'
下面使用该INSERT-SET语句将Tom Hanks添加到 actor 表中:
INSERT INTO actor
SET first_name = 'Tom'
, last_name = 'Hanks' ;
我相信这INSERT-SET是INSERT语句的名称-值模型的最佳方法。很遗憾只有 MySQL 支持它。actor使用以下内容查询表:
SELECT *
FROM actor
ORDER BY actor_id ;
它返回:
+----------+------------+-----------+
| actor_id | first_name | last_name |
+----------+------------+-----------+
| 1 | Harrison | Ford |
| 2 | Carrie | Fisher |
| 3 | Mark | Hamill |
| 4 | Alec | Guinness |
| 6 | Tom | Hanks |
+----------+------------+-----------+
5 rows in set (0.01 sec)
现在在查询数据时会出现一个间隙,因为第二次添加Harrison Ford 的尝试消耗了内部管理列表中的序列值。当您创建或更改表以包含自动递增列时,该列表是表的属性,例如actor_id. 任何时候尝试插入违反表约束的行时,都会消耗内部管理序列中的值。虽然您可以恢复它并消除差距,但我强烈建议您不要这样做。
与往常一样,我希望这有助于那些尝试学习和试验语法的人。
原文地址:https://blog.mclaughlinsoftware.com/2021/05/24/mysql-insert-set/?xzs




