本章介绍如何利用 SQL 的 INSERT 语句将数据插入表中。
15.1 数据插入
除了 SELECT 以为,还有其他 3 个经常使用 的 SQL 语句。
第一个就是 INSERT,用来插入(或添加)行到数据库表的,插入可以用几种方式使用:
- 插入完整的行
- 插入行的一部分
- 插入某些查询的结果
插入及系统安全:使用 INSERT 语句可能需要客户机/服务器 DBMS 中的特定安全权限。
15.1.1 插入完整的行
把数据插入表中的最简单的方法是使用基本的 INSERT 语法,它要求指定表名和被插入到新行中的值。
例 1:
INSERT INTO Customers
VALUES ('1000000006', 'Toy Land', '123 Any Street', 'New York', 'NY',
'11111', 'USA', NULL, NULL);
此例子插入一个新客户到 Customers 表。存储到每个表列中的数据在 VALUES 子句中给出,对每个列必须提供一个值。
如果某个列没有值,应该使用 NULL 值。
各个列必须以它们在表定义中出现的次序填充。
INTO 关键字:在某些 SQL 实现中,跟在 INSERT 之后的 INTO 关键字是可选的。
但是,即使不一定需要,最好还是提供这个关键字。这样做将保证 SQL 代码在 DBMS 之间的可移值。
P.S. 在自己写测试数据的时候可以不写关键字,但在写成 DML 脚本的时候最好写上,方便别人阅读,也方便自己检查
例 2,编写 INSERT 语句的更安全(不过更烦琐)的方法如下:
INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state,
cust_zip, cust_country, cust_contact, cust_email)
VALUES ('1000000006', 'Toy Land', '123 Any Street', 'New York', 'NY',
'11111', 'USA', NULL, NULL);)
因为提供了列名,VALUES 必须以其指定的次序匹配指定的列名,不一定按各个列出现在时间表中的次序。
优点:即使表结构改变,此 INSERT 语句仍然能正确工作。
例 3,下面的 INSERT 语句填充所有列,但以一种不同的次序填充。因为给出了列名,所以插入结果仍然正确:
INSERT INTO Customers(cust_id, cust_contact, cust_email, cust_name, cust_address,
cust_city, cust_state, cust_zip)
VALUES ('1000000006', NULL, NULL, 'Toy Land', '123 Any Street', 'New York', 'NY',
'11111');
仔细给出值:不管使用哪种 INSERT 语法,都必须给出数目正确的值。
如果不提供列名,则必须给每个表列提供一个值。
如果提供列名,则必须对每个列出的列给出一个值,如果不这样,将产生一条错误消息,相应的行插入不成功。
15.1.2 插入部分行
使用 INSERT 的推荐方法是明确给出表的列名。
使用这种语法,还可以省略列,这表示可以只给某些列提供值,给其他列不提供值。
例 4:
INSERT INTO Customers (cust_id, cust_name, cust_city, cust_state, cust_zip, cust_country)
VALUES ('1000000006', 'Toy Land', '123 Any Street', 'New York', 'NY', '11111', 'USA');
省略列:如果表的定义允许,则可以在 INSERT 操作中省略某些列。省略的列必须满足以下某个条件:
- 该列定义为允许 NULL 值(无值或空值)
- 在表定义中给出默认值,这表示如果不给出值,将使用默认值
15.1.3 插入检索出的数据
INSERT 一般用来给表插入一个指定列值的行。
但是,INSERT 还存在另一种形式,可以利用它将一条 SELECT 语句的结果插入表中,这就是 INSERT SELECT。
例 5,从另一表中合并客户列表到你的 Customers 表:
INSERT INTO Customers (cust_id, cust_contact, cust_email, cust_name, cust_address, cust_city,
cust_state, cust_zip, cust_country)
SELECT cust_id, cust_contact, cust_email, cust_name, cust_address, cust_city,
cust_state, cust_zip, cust_country
FROM CustNew;
INSERT SELECT 中的列名:为了简单起见,例 5在 INSERT 和 SELECT 语句中使用了相同的列名。但是,不一定要求列名匹配。
DBMS 甚至不关心 SELECT 返回的列名。它使用的是列的位置,因此 SELECT 中的第一列(不管其列名)将用来填充表列中指定的第一个列,以此类推。
INSERT SELECT 中的 SELECT 语句可包含 WHERE 子句以过滤插入的数据。
插入多行:INSERT 通常只插入一行。为了插入多行,必须执行多个 INSERT 语句(除了 INSERT SELECT)。
15.2 从一个表复制到另一个表
有一种不使用 INSERT 语句的数据插入。
为了将一个表的内容复制到一个全新的表(在运行中创建的表),可使用 SELECT INTO 语句。
与 INSERT SELECT 增补数据到一个已经存在的表不同,SELECT INTO 将复制数据到一个新表。
例 6:
SELECT *
INTO CustCopy
FROM Customers;
在使用 SELECT INTO 时:
- 任何 SELECT 选项和子句都可以使用,包括 WHERE 和 GROUP BY
- 可利用联结从多个表插入数据
- 不管从多少个表中检索数据,数据都只能插入到单个表中
然而,在 MySQL 以及 Oracle 中,不能使用 SELECT INTO,而是使用
CREATE TABLE TABLE_NAME AS SELECT:
CREATE TABLE CustCopy AS
SELECT *
FROM Customers;