LAMP网站开发黄金组合Linux+Apache+MySQL+PHP
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

4.8 数据操纵语言(DML)

为了修改数据库中的数据,SQL的数据操纵语言提供了增(INSERT)、删(DELETE)、改(UPDATE)语句,下面分别介绍。

4.8.1 INSERT语句

插入数据是把新的记录插入到一个存在的表中。插入数据使用语句INSERT INTO,可分为以下几种情况。

1.插入一个新记录

插入一个新元组到表中的语法格式如下:

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

其中,<表名>是指要插入新记录的表,<列名>是可选项,指定待添加数据的列,VALUES子句指定待添加数据的具体值。若没有指定列名表,则VALUES子句值的排列顺序必须和原表的定义相同、个数相等、数据类型一一对应,否则会被系统拒绝。在插入新元组时,会对主键列的值进行主键唯一性检查。

在INSERT INTO语句中可以在表名后面添加列名表,这有两个好处:

● 当插入元组的某列为NULL时,只要在列名表中不列出这个列即可,前提是将列允许改为空;

● 列的次序也不必严格与表的定义语句一致。但是VALUES子句值的排列顺序必须和列名表中的列名排列顺序一致,个数相等,数据类型一一对应。

例如要在STUDENTS表中插入一条学生记录(学号:0406345;姓名:白雾;性别:女;年龄:21;系别:英语系)。SQL语句如下:

    INSERT INTO STUDENTS VALUES ('0406345','白雾','女',21,'English');

★ 注意 ★

必须用逗号将各个数据分开,字符型数据要用单引号括起来。

2.插入记录的部分值

在表中插入记录时,有时可以只插入部分字段的值,有些字段暂时不插入值。例如,在学生选课表SC中插入一条新的选课记录,但没有成绩(学号:0406321;选课号:C003),SQL语句如下:

    INSERT INTO SC (SNO,CNO) VALUES ('0406321','C003');

将VALUES子句中的值按照INTO子句中指定列名的顺序插入到表中,对于INTO子句中没有出现的列,则新插入的记录在这些列上将取空值,如上例的GRADE即赋空值。但在表定义时有NOT NULL约束的属性列不能取空值。

3.插入多行记录

有时要插入一个表中的数据是数据库表中已经有的,可以用一个查询语句作为插入值,此时插入数据可能不止一个元组。插入数据的语法格式如下:

    INSERT INTO <表名> [(<列名1>[,<列名2>…])]
    SELECT子查询;

例如,需要生成一个英语系学生的成绩表ENGGRADE,表中包括SNAME、CNO、GRADE四个属性。首先定义一个新表ENGGRADE,SQL语句如下:

    CREATE TABLE ENGGRADE
    (SNAME VARCHAR(8)NOT NULL,CNO CHAR(4)NOT NULL,GRADE SMALLINT);

然后,在新表中插入有关的数据,SQL语句如下:

    INSERT INTO ENGGRADE SELECT SNAME,STUDENTS.SNO,CNO,GRADE FROM STUDENTS,SC
    WHERE STUDENTS.SNO=SC.SNO AND SDEPT='English';

插入后,表ENGGRADE的内容为如表4-11所示,子查询得到的所有记录都插入了表中。

表4-11 ENGGRADE表的内容

4.8.2 DELETE语句

DELETE语句用来删除表中的一行或多行记录,其语法格式入如下:

    DELETE
    FROM<表名>
    [WHERE <条件>];

其中WHERE子句表示要删除的记录应满足的条件。如果没有WHERE子句,则表示删除表的所有元组(记录),但表本身仍作为一个空表存在。要删除表本身,必须使用DROP TABLE语句。删除数据又可以具体分为删除一个记录,删除多个记录或删除全部记录。

1.删除一条记录

删除记录的个数实际上是由WHERE条件决定的,例如要删除SC表中学号为0406321、课程号为C001的记录,SQL语句如下:

    DELETE
    FROM SC
    WHERE SNO='0406321' AND CNO='C001';

该语句就删除了学生选课表的一条记录,因为符合WHERE子句条件的记录只有一条。

2.删除多条记录

在WHERE子句中可以使用SELECT子查询语句来选择符合条件的记录,进行删除。子查询可能产生多条记录。例如要从学生选课表SC中删除英语系学生的选课记录,SQL语句如下:

    DELETE FROM SC WHERE SNO=
        (SELECT SNO FROM STUDENTS WHERE SDEPT='English');

3.删除所有记录

删除所有记录的方法前面已经提过,在DELETE语句中没有WHERE子句时就表示删除表的所有元组。

4.8.3 UPDATE语句

SQL语言可以使用UPDATE语句对表中的一个或多个元组的某些属性值进行修改,其语法格式为:

    UPDATE <表名>
    SET <列名>=<表达式> [,<列名>=<表达式>]…
    [WHERE <条件>];

其中<表名>是指要修改的表,SET子句给出要修改的列及其修改后的值,WHERE子句指定待修改的记录应当满足的条件,WHERE子句省略时,则修改表中的所有记录。

UPDATE语句一般分为下面4种操作。

1.修改一个记录

例如把学号为0406321的学生的C001课程的成绩改为60,SQL语句如下:

    UPDATE STUDENTS SET GRADE=60
    WHERE SNO='0406321' AND CNO='C001';

2.修改多个记录

例如把所有学生的年龄都增加1,SQL语句如下:

    UPDATE STUDENTS SET SAGE=SAGE+1;

该语句中没有WHERE条件,所以对表中所有记录都执行修改操作。当符合WHERE条件的元组有多个时,对这多个元组进行修改。

例如要把英语系学生的年龄都减1,SQL语句如下:

    UPDATE STUDENTS SET SAGE=SAGE-1
    WHERE SDEPT='English';

3.利用查询子句提供要修改的元组

例如要把英语系学生的选课成绩都加10分,SQL语句如下:

    UPDATE SC
    SET GRADE=GRADE+10 WHERE SNO IN
        (SELECT STUDENTS.SNO FROM STUDENTS,SC WHERE STUDENTS.SNO=SC.TNO
            AND STUDENTS.SDEPT='English');

在这种修改操作中,子查询的作用是查询需要修改的元组;在本例中,子查询提供英语系学生的学号。

4.利用查询子句提供要修改的值

子查询除了能够提供需要修改的元组外,在UPDATE语句中还能用子查询语句提供修改的值。例如,把所有选课的学分改为平均学分数的两倍,SQL语句如下:

    UPDATE COURSE
    SET CCREDIT=
        (SELECT 2*AVG(CCREDIT) FROM COURSE);

在该修改语句中,SELECT查询子句的作用就是提供修改的值。

4.8.4 视图的更新

前面讲过视图的定义、删除以及查询,本节继续介绍SQL语言对于视图的操作。视图的更新必须最终落实到有关基表的更新。视图的更新是一个比较复杂的问题,在理论上可以深入研究,但在实际应用中,都作了简单化处理;或者有的DBMS对视图更新做了严格的限制。一般的限制有:

● 由一个基表定义的视图,只有含有基表的主键或候补键,并且视图中没有用表达式或函数的属性,才允许更新;

● 由多表连接所定义的视图不允许更新;

● 定义中用到GROUP BY子句或聚集函数的视图不允许更新。

以上限制是简化了的、偏向保守的规定。读者用到更新视图时可以参考具体使用的DBMS的规定。对于可以更新的视图,语法与更新有关的基表相同。