二级MySQL数据库程序设计(四)

课程目录
第1章 数据库的基本概念与设计方法
第2章 MySQL简介
第3章 数据库和表
第4章 表数据的基本操作
第5章 数据库的查询
第6章 索引
第7章 视图
第8章 数据完整性约束与表维护语句
第9章 触发器
第10章 事件
第11章 存储过程与存储函数
第12章 访问控制与安全管理
第13章 备份与恢复
第14章 PHP和MySQL数据库编程
第15章 开发实例

本章学习流程图

在这里插入图片描述

本章学习大纲

在这里插入图片描述

4.1 插入表数据

数据库与表创建成功以后,需要使用USE语句指定要操作的数据库作为当前数据库,然后向当前数据库中的表插入数据。在MySQL中可以使用INSERT或REPLACE语句向数据库中已有的表插入一行或者多行元组数据。

INSERT语句

INSERT语句有三种语法形式,分别为:

  • INSERT…VALUE语句
  • INSERT…SET语句
  • INSERT…SELECT语句

(1)INSERT VALUE语句

语法格式:

INSERT INTO <表名> [<列名1>[,...<列名n>]] VALUES (1)[...,(值n)];

语法说明:

  • <表名>:指定被操作的表名。
  • <列名>:指定需要插入数据的列名。

如果是向表中所有列插入数据,则全部的列名均可以省略。直接采用INSERT<表名>VALUES(…)即可。这种语法高度依赖表中所有列的定义次序,应该尽量避免使用这种方法,因为列的次序可能会改变,这就很不安全。如果只是向表的部分列插入数据,则必须明确指定这些列的名称,而对于没有被指定的列,它们的值会根据列的默认值或相关属性来确定,处理原则如下:

① 具有默认值的列,其值可通过在INSERT语句中指定关键字DEFAULT将其设为默认值。

② 由于AUTO_INCREMENT属性列的值是在表中其他列被赋值之后生成的,所以在对表中其他列做任何赋值操作时,对该AUTO_INCREMENT属性列的引用只会返回数字0。

③ 没有默认值的列,若允许为空值,则其值可通过在INSERT语句中指定关键字NULL将其设为空值;若不允许为空值,则INSERT语句执行出错。

④ 对于具有标志(IDENTITY)属性的列,系统会自动生成序号值来唯一标志该列。

⑤ 对于类型为TIMESTAMP的列,系统会自动为其赋值。

  • VALUES或VALUE子句:该子句包含要插入的数据清单。数据清单中数据的顺序要和列的顺序相对应。VALUES子句的值可以是如下两种情况:

① 可以是一个常量、变量或表达式,也可以是空值NULL,其值的数据类型要与列的数量类型一致,如果类型不匹配,系统会提示错误。当列值为字符型时,需要用单引号 括起。

②DEFAULT:用于指定此列值为该列的默认值。前提是该列之前已经明确指定了默认值,否则插入语句会出错。

(2)INSERT…SELECT语句

用于快速地从一个或多个表中取出数据,并将这些数据作为行数据插入到另一个表中。SELECT子句返回的是一个查询到的结果集,INSERT语句将这个结果集插入到指定表中,结果集中的每行数据的字段数、字段的数据都必须与被操作的表完全一致。

(3)INSERT…SET语句
用于直接给表中的某些列指定对应的列值,即要插入的数据的列名在SET子句中指定,col_name为指定的列名,等号后面为指定数据,而对于未指定的列,列值会指定为该列的默认值。

由INSERT语句的三种形式可以看出,
使用INSERT…VALUES语句可以向表中插入一行数据,也可以插入多行数据;
使用INSERT…SET语句可以指定插入行中每列的值,也可以指定部分列的值;
使用INSERT…SELECT语句向表中插入其他表的值。

【例】使用INSERT…VALUES语句向数据库my_test的表students中插入这样一行完整数据:
(1320,‘王丽’,‘1’,‘22’,‘计算机专业’,‘138xxxxxx’)。

mysql> set names gbk;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into my_test.students
    -> values(1320,'王丽','1','22','计算机专业','138xxxxxx');
Query OK, 1 row affected (0.54 sec)

mysql> select * from students;
+------------+--------------+-------------+-------------+---------------+-----------------+
| student_id | student_name | student_sex | student_age | student_major | student_contact |
+------------+--------------+-------------+-------------+---------------+-----------------
|       1320 | 王丽         | 1           | 22          | 计算机专业    | 138xxxxxx       |
+------------+--------------+-------------+-------------+---------------+-----------------+
1 row in set (0.00 sec)

注意:Windows操作系统默认使用gb2312字符集,MySQL客户端和服务器默使用latin1,这就导致一个字符集和字符校验不匹配的问题,因此这里采用 SET NAMES GBK 改变字符集,这样才能正确地插入中文。

【例】使用INSERT…VALUES语句向数据库my_test的表students中插入这样一行数据,这行数据值给出student_name, student_major 和 student_age列的信息,对应的值是“李明”,“数学专业”,“22”。其中student_id由系统自动生成,其他采用默认或者不指定值。

mysql> insert into my_test.students
    -> values(0,'李明',default,22,'数学专业',null);
Query OK, 1 row affected (0.58 sec)

mysql> select * from students;
+------------+--------------+-------------+-------------+---------------+-----------------+
| student_id | student_name | student_sex | student_age | student_major | student_contact |
+------------+--------------+-------------+-------------+---------------+-----------------+
|          0 | 李明         | 1           |          22 | 数学专业      | NULL            |
|       1320 | 王丽         | 1           |          22 | 计算机专业    | 138xxxxxx       |
+------------+--------------+-------------+-------------+---------------+-----------------+
2 rows in set (0.00 sec)

通过分析,student_id列的值可不必在INSERT语句的列表清单中列出,由系统自动生成,同时允许NULL列也不必给出,因为系统允许其值为空。只需要给出student_name,student_sex,student_age和student_major列的值,执行如下语句也可以完成数据插入:

mysql> insert into my_test.students
    -> (student_name,student_sex,student_age,student_major)
    -> values('李明',default,22,'数学专业');
ERROR 1364 (HY000): Field 'student_id' doesn't have a default value

警告:按照书中的做法操作会报错,因为student_id为主键,不允许为NULL。

【例】使用INSERT…SET语句来实现上述例子中的数据插入需求。

mysql> insert into my_test.students
    -> set student_id=1321,student_name='李明',student_sex=default,student_age=22,student_major='数学专业';
Query OK, 1 row affected (0.19 sec)

mysql> select * from students;
+------------+--------------+-------------+-------------+---------------+-----------------+
| student_id | student_name | student_sex | student_age | student_major | student_contact |
+------------+--------------+-------------+-------------+---------------+-----------------+
|       1320 | 王丽         | 1           |          22 | 计算机专业    | 138xxxxxx       |
|       1321 | 李明         | 1           |          22 | 数学专业      | NULL            |
+------------+--------------+-------------+-------------+---------------+-----------------+
2 rows in set (0.00 sec)

采用INSERT…SET语句可以向表中插入部分列的值,这种方式更为灵活。INSERT…VALUES语句可以一次插入多条数据,如下例。

【例】使用INSERT…VALUE语句,一次向 my_test 表 students 插入两条数据,数据分别为(1322,‘张三’,‘1’,24,‘化学专业’)和,1323,‘王五’,‘1’,23,‘数学专业’)。

mysql> insert into my_test.students
    -> (student_id,student_name,student_sex,student_age,student_major)
    -> values(1322,'张三','1',24,'化学专业'),
    -> (1323,'王五','1',23,'数学专业');
Query OK, 2 rows affected (0.58 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from students;
+------------+--------------+-------------+-------------+---------------+-----------------+
| student_id | student_name | student_sex | student_age | student_major | student_contact |
+------------+--------------+-------------+-------------+---------------+-----------------+
|       1320 | 王丽         | 1           |          22 | 计算机专业    | 138xxxxxx       |
|       1321 | 李明         | 1           |          22 | 数学专业      | NULL            |
|       1322 | 张三         | 1           |          24 | 化学专业      | NULL            |
|       1323 | 王五         | 1           |          23 | 数学专业      | NULL            |
+------------+--------------+-------------+-------------+---------------+-----------------+
4 rows in set (0.02 sec)

在MySQL中,用单条INSERT语句处理多个插入要比使用多条INSERT语句更快。当使用单挑INSERT语句插入多行数据的时候,只需要将每行数据用圆括号括起来即可。
使用INSERT VALUES和INSERT SET语句可以向表中插入数据。INSERT SELECT语句也可以向表中插入数据。

【例】使用INSERT…VALUE语句,一次向 my_test 表 students 插入两条数据,数据分别为(1322,‘张三’,‘1’,24,‘化学专业’)和,1323,‘王五’,‘1’,23,‘数学专业’)。
我们先设置一个students_copy表,并输入一条信息。

mysql> select * from students_copy;
+------------+--------------+-------------+-------------+---------------+-----------------+
| student_id | student_name | student_sex | student_age | student_major | student_contact |
+------------+--------------+-------------+-------------+---------------+-----------------+
|       1324 | 赵柳         | 1           |          20 | 英语专业      | NULL            |
+------------+--------------+-------------+-------------+---------------+-----------------+
1 row in set (0.00 sec)
mysql> insert into my_test.students
    -> (student_id,student_name,student_sex,student_age,student_major)
    -> select student_id,student_name,student_sex,student_age,student_major
    -> from my_test.students_copy;
Query OK, 1 row affected (0.60 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> select * from students;
+------------+--------------+-------------+-------------+---------------+-----------------+
| student_id | student_name | student_sex | student_age | student_major | student_contact |
+------------+--------------+-------------+-------------+---------------+-----------------+
|       1320 | 王丽         | 1           |          22 | 计算机专业    | 138xxxxxx       |
|       1321 | 李明         | 1           |          22 | 数学专业      | NULL            |
|       1322 | 张三         | 1           |          24 | 化学专业      | NULL            |
|       1323 | 王五         | 1           |          23 | 数学专业      | NULL            |
|       1324 | 赵柳         | 1           |          20 | 英语专业      | NULL            |
+------------+--------------+-------------+-------------+---------------+-----------------+
5 rows in set (0.00 sec)

说明:

  • SELECT语句用于从一个表中检索出要插入的值,而非列出这些值。SELECT语句中列出的每个列对应于待插入表的每一列。如果SELECT语句检索出的数据行数为0,则表示没有行会被插入到待插入表中,此时操作合法,不会报错。
  • INSERT语句与SELECT语句中可使用相同的列名,也可以使用不同的列名,即要求列名完全匹配。MySQL不关心SELECT语句返回的列名,它使用的是列的位置,SELECT语句中的第一列用来填充待插入表中指定的第一个列,第二列用来填充待插入表中的第二个列,如此顺序依次填充。
  • INSERT…SELECT语句中的SELECT子句可以包含WHERE等从句来过滤待插入的数据。
  • 对于student_id这类主键,当出现主键重复时,后续的INSERT操作会出错。此时可以在INSERT…SELECT语句中省略这个列,让该列的值在MySQL导入数据的过程中自动产生新值。

REPLACE语句
如果一个待插入的表存在有 PRIMARY KEY 或者 UNIQUE KEY,而待插入的数据行中包含有与待插入表中已有行的PRIMARY KEY或者UNIQUE KEY列值,换句话说,就是插入的数据主键和已有数据的主键重复,则INSERT语句无法插入此行。此时若需要插入此行数据,则可以使用REPLACE语句来实现。即REPLACE的功能是替换主键重复的行数据。
REPLACE语句有三种语法形式,分别为:

REPLACE…VALUES语句;
REPLACE…SET语句;
REPLACE…SELECT语句。

REPLACE VALUES语法格式:

REPLACE INTO <表名> [<列名1>[,...<列名n>])] VALUES (1)[,(值n)]

【例】使用INSERT语句成功执行后,数据库my_test表students中会存在这样一条数据:(1320,‘王丽’,‘1’,22,‘计算机专业’,‘137xxxxxxxx’)。现在想该表中插入一条新数据:(1320,‘王芳’,‘1’,26,‘会计专业’,‘137xxxxxxxx’)。

mysql> insert into students
    -> values(1320,'王芳','1',26,'会计专业','137xxxxxxxx');
ERROR 1062 (23000): Duplicate entry '1320' for key 'students.PRIMARY'

从系统返回的结果可以看出,该语句不能成功执行,原因在于新插入的行数据的主键和原有数据的主键相同,都为1320。此时如果仍然要插入该数据,可以使用REPLACE语句来替换原来的数据:

mysql> replace into students
    -> values(1320,'王芳','1',26,'会计专业','137xxxxxxxx');
Query OK, 2 rows affected (0.57 sec)

mysql> select * from students;
+------------+--------------+-------------+-------------+---------------+-----------------+
| student_id | student_name | student_sex | student_age | student_major | student_contact |
+------------+--------------+-------------+-------------+---------------+-----------------+
|       1320 | 王芳         | 1           |          26 | 会计专业      | 137xxxxxxxx     |
|       1321 | 李明         | 1           |          22 | 数学专业      | NULL            |
|       1322 | 张三         | 1           |          24 | 化学专业      | NULL            |
|       1323 | 王五         | 1           |          23 | 数学专业      | NULL            |
|       1324 | 赵柳         | 1           |          20 | 英语专业      | NULL            |
+------------+--------------+-------------+-------------+---------------+-----------------+
5 rows in set (0.00 sec)

4.2 删除表数据

在MySQL中,可以使用DELETE语句或TRUNCATE TABLE语句来删除表的一行或者多行数据。

使用DELETE语句从单个表中删除数据
语法格式:

DELETE FROM <表名>[WHERE子句][ORDER BY子句][LIMIT子句]

语法说明:

  • <表名>:指定要删除数据的表名
  • ORDER BY子句:可选项。表示删除时,表中各行将按照子句中指定的顺序进行删除。
  • WHERE子句。可选项。表示为删除操作限定删除条件;若省略该子句,则代表删除该表中的所有行。
  • LIMIT子句:可选项。用于告知服务器在控制命令被返回到客户端前被删除行的最大值。

注意:在不适用WHERE条件的时候,将删除所有数据。

【例】使用DELETE语句删除数据库表students中名字为‘王芳’的学生信息。

mysql> delete from students
    -> where student_name='王芳';
Query OK, 1 row affected (0.66 sec)

mysql> select * from students;
+------------+--------------+-------------+-------------+---------------+-----------------+
| student_id | student_name | student_sex | student_age | student_major | student_contact |
+------------+--------------+-------------+-------------+---------------+-----------------+
|       1321 | 李明         | 1           |          22 | 数学专业      | NULL            |
|       1322 | 张三         | 1           |          24 | 化学专业      | NULL            |
|       1323 | 王五         | 1           |          23 | 数学专业      | NULL            |
|       1324 | 赵柳         | 1           |          20 | 英语专业      | NULL            |
+------------+--------------+-------------+-------------+---------------+-----------------+
4 rows in set (0.00 sec)

使用DELETE语句从多个表中删除数据

语法格式:

DELETE <表名> FROM <1,表2...,表n>[WHERE子句];

语法说明:

  • 该命令删除位于FROM子句之前的表中的数据行。
  • <表1,表2,…表n>:指定多个表的联合。

【例】假设数据库中有三个表tbl1、tbl2和tbl3,它们均含有id列,现在要求删除表tbl1中id值的等于表tbl2的id值的所有行,以及表tbl2中id值等于表tbl3的id值的所有行。

DELETE tbl1,tbl2 FROM tbl1,tbl2,tbl3
WHERE tbl1.id=tbl2.id AND tbl2.id=tbl3.id;

使用TRUNCATE语句删除表数据

如果要从表中删除所有的行,可以使用TRUNCATE语句。TRUNCATE语句可以直接删除指定表的所有数据,执行速度比DELETE语句更快。因为TRUNCATE操作过程是先删除原来的表,并再重新创建一个表,而不是逐行删除表中的数据。因此,TRUNCATE语句又被称为清楚表数据语句。
语法格式:

TRUNCATE TABLE<表名>

语法说明:

  • 使用TRUNCATE后,表中的AUTO_INCRENMENT计数器将被置为该列的初始值。对于参与了索引和视图的表,不能使用TRUNCATE语句删除数据,而应该使用DELETE语句。
  • TRUNCATE操作比DELETE操作占用的系统和事务日志资源更少,因为DELETE每删除一行就会在日志中记录一项,而TRUNCATE是通过释放存储表数据所用的数据页来删除数据的,因此只在日志中记录页的释放。
  • 由于TRUNCATE语句在功能上与不带WHERE子句的DELETE语句相同,它将删除表中的所有数据,且数据无法恢复,因此使用的过程要小心,在确认数据完全不需要的时候,再进行操作。

注意:在需要清空整个表中所有数据的情形下,采用TRUNCATE比采用DELETE更为高效。

事务日志:一个与数据库文件分开的文件。它存储对数据库进行的所有更改,并全部记录插入、更新、删除、提交、回退和数据库模式变化。

4.3 修改表数据

在MySQL中,可以使用UPDATE语句来修改、更新一个或多个表的数据。

使用UPDATE语句修改单个表

语法格式:

UPDATE <表名> SET 字段1=1 [,字段2=2...][WHERE子句][ORDER BY子句][LIMIT子句]

语法说明:

  • <表名>:用于指定要更新的表名称。
  • SET子句:用于指定表中药修改的列名及其列值。其中,每个指定的列值可以是表达式,也可以是该列对应的默认值。如果指定的是默认值,可用关键字DEFAULT表示列值。
  • WHERE子句:可选项。用于限定表中要修改的行。不指定则修改表中所有的行。
  • ORDER BY子句:可选项。用于限定表中的行被修改的次序。
  • LIMIT子句:可选项。用于限定被修改的行数。

【例】使用UPDATE语句将数据库 my_test 的表 students 中姓名为‘张三’的学生的联系方式改为‘139xxxxxxxx’。

mysql> update my_test.students
    -> set student_contact='139xxxxxxxx'
    -> where student_name='张三';
Query OK, 1 row affected (0.60 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from students;
+------------+--------------+-------------+-------------+---------------+-----------------+
| student_id | student_name | student_sex | student_age | student_major | student_contact |
+------------+--------------+-------------+-------------+---------------+-----------------+
|       1321 | 李明         | 1           |          22 | 数学专业      | NULL            |
|       1322 | 张三         | 1           |          24 | 化学专业      | 139xxxxxxxx     |
|       1323 | 王五         | 1           |          23 | 数学专业      | NULL            |
|       1324 | 赵柳         | 1           |          20 | 英语专业      | NULL            |
+------------+--------------+

【例】使用UPDATE语句将数据库 my_test 的表 students 中姓名为‘赵柳’的学生的年龄修改为23,将专业修改为‘物理专业’。

mysql> update my_test.students
    -> set student_age=23,student_major='物理专业'
    -> where student_name='赵柳';
Query OK, 1 row affected (0.55 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from students;
+------------+--------------+-------------+-------------+---------------+-----------------+
| student_id | student_name | student_sex | student_age | student_major | student_contact |
+------------+--------------+-------------+-------------+---------------+-----------------+
|       1321 | 李明         | 1           |          22 | 数学专业      | NULL            |
|       1322 | 张三         | 1           |          24 | 化学专业      | 139xxxxxxxx     |
|       1323 | 王五         | 1           |          23 | 数学专业      | NULL            |
|       1324 | 赵柳         | 1           |          23 | 物理专业      | NULL            |
+------------+--------------+-------------+-------------+---------------+-----------------+
4 rows in set (0.00 sec)

修改一行数据的多个列值,SET子句每个值用逗号分开即可。

使用UPDATE语句修改多个表

语法格式:

UPDATE<1,2,...>SET列名=1[,列名2=2,...][WHERE子句];

语法说明:

  • 对于多个表的修改,UPDATE语句会同时修改<表1,表2,…>中满足限定条件的每个表。注意,在这种修改中不能使用ORDER BY 和 LIMIT 子句。
  • <表1,表2,…>:用于指定多个表的联合,各表之间可用逗号分隔。

【例】假设数据库中有两个表tbl1和tbl2,它们都有两个名为id和name列,其中id列为各自的主键,现在要求当表tbl1和表tbl2中的id值相同时,将表tbl1中name列的值修改为“李明”,将表tbl2中name列的值修改为“王伟”。

update tbl1,tbl2
set tbl1.name='李明',tbl2.name='王伟'
where tbl1.id=tbl2.id
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章