第四章 数据更新
4.1 数据的插入(INSERT语句的使用方法)
4.1.1 什么是INSERT
CREATE TABLE只是创建了表,如同一个空箱子,用来装入数据的SQL就是INSERT(插入)。
代码1.创建ShohinIns表的CREATE TABLE语句
CREATE TABLE ShohinIns (shohin_id CHAR(4) NOT NULL, shohin_mei VARCHAR(100) NOT NULL, shohin_bunrui VARCHAR(32) NOT NULL, hanbai_kanta INTEGER DEFAULT 0, shiire_tanka INTEGER , torokubi DATE , PRIMARY KEY (shohin_id));
输出结果:
创建了表但是表中没有数据,接下来需要向ShohinIns表中插入数据
4.1.2 INSERT语句的基本语法
代码2. INSERT基本语法
INSERT INTO <列1,列2,列3,列4,......> VALUES (值1,值2,值3,值4,......);
代码3.向表中插入一行数据
INSERT INTO ShohinIns (shohin_id,shohin_mei,shohin_bunrui,hanbai_tanka,shiire_tanka,torokubi) VALUES ('0001','T恤衫','衣服',1000,500,'2009-09-20');
输出结果:
列名和值用逗号隔开,分别括在()内,这种形式称为清单。INSERT语句中包含了两个清单:
列清单-> (shohin_id,shohin_mei,shohin_bunrui,hanbai_tanka,shiire_tanka,torokubi)
值清单-> ('0001','T恤衫','衣服',1000,500,'2009-09-20')
列数不一致时无法插入数据
插入多行数据时需要循环使用INSERT语句
4.1.3 列清单的省略
对表进行全列INSERT时,可以省略表名后的列清单,这是VALUES子句的值会默认按照从左往右的顺序赋给每一列
代码4.省略列清单
--包含列清单 INSERT INTO ShohinIns(shohin_id,shohin_mei,shohin_bunrui,hanbai_tanka,shiire_tanka,torokubi) VALUES ('0005','高压锅','厨房用具‘,6800,5000,'2009-01-15'); --省略列清单 INSERT INTO ShohinIns VALUES('0005','高压锅','厨房用具',6800,5000,'2009-01-15');
输出结果:
4.1.4插入NULL
INSERT语句中想要给某一列赋予NULL值,可以直接在VALUES子句的值清单中写入NULL。
代码5.向shiire_tanka列中插入NULL
INSERT INTO ShohinIns (shohin_id,shohin_mei,shohin_bunrui,hanbai_tanka,shiire_tanka,torokubi) VALUES ('0006','叉子','厨房用具‘,500,NULL,'2009-09-20');
输出结果:
但是想要插入NULL的列一定不能设置NOT NULL约束。插入失败是指希望通过INSERT语句插入的数据无法正常插入到表中,但之前插入的数据并不会破坏。
4.1.5 插入默认值
默认值的设定可以通过在创建表的CREATE TABLE语句中设置DEFAULT约束来实现。可以通过“DEFAULT<默认值>”的形式来设置默认值。
如果在创建表时设定了默认值,就可以在INSERT语句中自动为列赋值了。默认赋值的使用方法通常有显示和隐示两种。
1.通过显示的方法插入默认值
在VALUES子句中指定DEFAULT关键字
代码6.通过显示的方法设定默认值
INSERT INTO ShohinIns (shohin_id,shohin_mei,shohin_bunrui,hanbai_tanka,shiire_tanka,torokubi) VALUES('0007','擦菜板','厨房用具',DEFAULT,790,'2009-04-28');
输出结果:
代码7.我们可以通过SELECT语句来确认通过INSERT语句插入的数据行
SELECT * FROM ShohinIns WHERE shohin_id='0007';
输出结果;
因为hanbai_tanka列的默认值是0,所以hanbai_tanka列被赋了值0.
2.通过隐示的方法来插入默认值
插入默认值时也可以不使用DEFAULT关键字。只要在列清单和VALUES中省略设定默认值的列就行了
代码8.通过隐示方法设定默认值
INSERT INTO ShohinIns (shohin_id,shohin_mei,shohin_bunrui,shiire_tanka,torokubi) VALUES('0007','擦菜板','厨房用具',790,'2009-04-28');
输出结果:
如果省略了没有设定默认值的列的话,该列的值就会被设置成NULL。因此,如果省略的是设置了NOT NULL约束列的话,INSERT语句就会出错。
4.1.6 从其他表中复制数据
代码9.要学习该方法首先要创建一张表
--用来插入数据的商品复制表 CREATE TABLE ShohinCopy (shohin_id CHAR(4) NOT NULL, shohin_mei VARCHAR(100) NOT NULL, shohin_bunrui VARCHAR(32) NOT NULL, hanbai_kanta INTEGER , shiire_tanka INTEGER , torokubi DATE , PRIMARY KEY (shohin_id));
输出结果:
ShohinCopy表的结构与之前使用的Shohin表完全一样
代码10.INSERT......SELECT语句
--将商品表中的数据复制到商品复制表中(复制) INSERT INTO ShohinCopy (shohin_id,shohin_mei,shohin_bunrui,hanbai_tanka,shiire_tanka,torokubi) SELECT shohin_id,shohin_mei,shohin_bunrui,hanbai_tanka,shiire_tanka,torokubi FROM Shohin;
输出结果:
INSERT......SELECT语句可以在需要进行数据备份时使用。
多种多样的SELECT语句:该INSERT语句中的SELECT语句,也可以使用WHERE子句或者GROUP BY子句等。
我们尝试一下使用包含GROUP BY子句的SELECT语句进行INSERT
代码11.创建ShohinBunrui表的CREATE TABLE 语句
--用来汇总商品种类的表; CREATE TABLE ShohinBunrui (shohin_bunrui VARCHAR(32) NOT NULL, sum_hanbai_tanka INTEGER, sum_shiire_tanka INTEGER, PRIMARY KEY (shohin_bunrui));
输出结果;
这张表是用来储存根据商品种类(shohin_bunrui)计算出的销售单价合计及进货单价合计值表。
代码12.插入其他表中数据合计值的INSERT.....SELECT语句
INSERT INTO ShohinBunrui (shohin_bunrui,sum_hanbai_tanka,sum_shiire_tanka) SELECT shohin_bunrui,SUM(hanbai_tanka),SUM(shiire_tanka) FROM Shohin GROUP BY shohin_bunrui;
输出结果;
代码13.通过SELECT语句对插入结果进行确认
SELECT * FROM ShohinBunrui;
输出结果;
4.2 数据的删除(DELETE语句的使用方法)
4.2.1 DROP TABLE语句和DELETE语句
DROP TABLE 语句可以将表完全删除
DELETE 语句会留下表(容器),而删除表中的全部数据
4.2.2 DELETE语句的基本语法
代码14.保留数据表,仅删除全部数据行的DELETE语句
DELETE FROM <表名>;
执行该语句可删除指定表中的全部数据行
代码15.清空Shohin表
DELETE FROM Shohin;
DELETE语句的删除对象不是表或列,而是记录(行)
4.2.3 指定删除对象的DELETE语句(搜索型DELETE)
代码16.删除部分数据行的搜索型DELETE
DELETE FROM <表名> WHERE <条件>;
代码17. 删除销售单价大于等于4000元的数据
DELETE FROM Shohin WHERE hanbai_tanka>=4000;
输出结果:
WHERE子句的书写方式与此前介绍的SELECT语句完全一样
代码18.通过SELECT语句确认
SELECT * FROM Shohin;
输出结果:
与SELECT语句的不同的是,DELETE 语句中不能使用GROUP BY,HAVING和ORDER BY三类子句,而只能使用WHERE子句。
4.3 数据的更新(UPDATE语句的使用方法)
4.3.1 UPDATE语句的基本语法
使用UPDATE可以更改(更新)表中的数据。
代码19.UPDATE 语法
UPDATE <表名> SET <l列名> = <表达式>;
代码20.将登记日期全部改为‘2009-10-10’
UPDATE Shohin SET torokubi='2009-10-10';
输出结果:
代码21.
--确认更新内容 SELECT * FROM Shohin ORDER BY shohin_id;
输出结果:
结果显示连原本为NULL的数据行的值也要更新为2009-10-10
4.3.2 指定条件的UPDATE语句(搜索型UPDATE)
更新数据时,也可以像DELETE语句那样使用WHERE子句。
代码22.更新部分数据行的搜索型UPDATE
UPDATE <表名> SET <列名> = <表达式> WHERE <条件>;
代码23.将商品种类为厨房用具的记录的销售单价更新为原来10倍
UPDATE Shohin SET hanbai_tanka = hanbai_tanka*10 WHERE shohin_bunrui='厨房用具';
输出结果:
SET子句中赋值表达式的右边不仅可以是单纯值,还可以是包含列的表达式
代码24.
--确认更新内容 SELECT * FROM Shohin ORDER BY shohin_id;
输出结果:
4.3.3 使用NULL进行更新
使用UPDATE也可以将列更新为NULL(俗称NULL清空),但是只局限于未设置NOT NULL约束的列。
代码25.将商品编号为0008的数据登记日期更改为NULL
UPDATE Shohin SET torokubi = NULL WHERE shohin_id = '0008';
输出结果:
代码26.
--确认更新内容 SELECT * FROM Shohin ORDER BY shohin_id;
输出结果:
4.3.4 多列更新
UPDATE语句的SET子句支持同时设置多个列作为更新对象。
代码27.方法1:将代码合并为一条UPDATE语句
--使用逗号将列分隔排列 UPDATE Shohin SET hanbai_tanka=hanbai_tanka*10, shiire_tanka = shiire_tanka/2 WHERE shohin_bunrui='厨房用具';
输出结果:
代码28.方法2:将代码处理合并为一条UPDATE语句
--将列用()括起来的列表形式 UPDATE Shohin SET (hanbai_tanka,shiire_tanka) =(hanbai_tanka*10,shiire_tanka/2) WHERE shohin_bunrui='厨房用具';
输出结果;
代码29.执行上面两条语句会得到相同的结果
--确认更新内容 SELECT * FROM Shohin ORDER BY shohin_id;
输出结果:
4.4 事务
4.4.1 什么是事务
事务就是需要在同一个处理单元中执行的一系列更新处理的集合。通过使用事务,可以对数据库中的数据更新处理的提交和取消管理。
4.4.2 创建事务
代码30.事务的语法
事务开始语句; DML语句1; DML语句2; DML语句3; . . . 事务结束语句(COMMIT或者ROLLBACK);
使用事务开始语句和事务结束语句,将一系列DML语句(INSERT/UPDATE/DELETE语句)括起来,就实现了一个事务处理。
这时需要注意事务开始语句。在标准SQL中并没有定义事务的开始语句,而是由各个DBMS自己来定义。
SQL Server、PostgreSQL: BEGIN TRANSACTION
MySQL: START TRANSACTION
Oracle、DB2:无
代码31.更新商品信息的事务
--SQL、PostgreSQL BEGIN TRANSACTION; --将运动T恤的销售单价降低1000元 UPDATE Shohin SET hanbai_tanka = hanbai_tanka -1000 WHERE shohin_mei='运动T恤'; --将T恤的销售单价上浮1000元 UPDATE Shohin SET hanbai_tanka = hanbai_tanka + 1000 WHERE shohin_mei = 'T恤衫'; COMMIT; --MySQL START TRANSACTION; --将运动T恤的销售单价降低1000元 UPDATE Shohin SET hanbai_tanka = hanbai_tanka -1000 WHERE shohin_mei='运动T恤'; --将T恤的销售单价上浮1000元 UPDATE Shohin SET hanbai_tanka = hanbai_tanka + 1000 WHERE shohin_mei = 'T恤衫'; COMMIT; --Oracle、DB2 --将运动T恤的销售单价降低1000元 UPDATE Shohin SET hanbai_tanka = hanbai_tanka -1000 WHERE shohin_mei='运动T恤'; --将T恤的销售单价上浮1000元 UPDATE Shohin SET hanbai_tanka = hanbai_tanka + 1000 WHERE shohin_mei = 'T恤衫';
COMMIT;
输出结果(仅展示PostgreSQL):
COMMIT——提交处理
COMMIT是提交事务包含的全部更新处理的结束指令。相当于文件处理中的覆盖保存。一旦提交,就无法恢复到事务开始之前的状态了。因此,提交前一定要确认是否需要这些更新。
ROLLBACK——取消处理
ROLLBACK是取消事务包含的全部更新处理的结束指令,相当于文件处理中的放弃保存。一旦回滚,数据库就会回复到事务开始之前的状态。通常回滚不会像提交那样造成大规模的数据损失。
代码32.事务回滚的例子
SQL Server、PostgreSQL BEGIN TRANSACTION; --将运动T恤的销售单价降低1000元 UPDATE Shohin SET hanbai_tanka = hanbai_tanka -1000 WHERE shohin_mei='运动T恤'; --将T恤的销售单价上浮1000元 UPDATE Shohin SET hanbai_tanka = hanbai_tanka + 1000 WHERE shohin_mei = 'T恤衫'; ROLLBACK;
输出结果:
4.4.3 ACID特性
原子性(Atomicity):是指在事务结束时,其中所包含的更新处理要么全部执行,要么完全不执行的特性。
一致性(Consistency):是指事务中所包含的处理,要满足数据库提前设置的约束,如主键约束或者NOT NULL约束等。
隔离性(Isolation):是指保证不同事务之间互不干扰的特性。该特性保证了事务之前不会互相嵌套。
持久性(Durability):是指事务一旦结束,DBMS就会保证该时点的数据状态得以保存的特性。xit
习题:
4.1
B先生看不到结果,因为A先生没有使用COMMIT;语句来确定更新。
4.2
会报错,出现如下错误;
4.3
INSERT INTO ShohinSaeki (shohin_id,shohin_mei,hanbai_tanka,shiire_tanka,saeki) SELECT shohin_id,shohin_mei,hanbai_tanka,shiire_tanka,hanbai_tanka-shiire_tanka FROM Shohin;
4.4
第一问:
UPDATE ShohinSaeki SET hanbai_tanka=3000 WHERE shohin_id='0003';
第二问:
UPDATE ShohinSaeki SET saeki=hanbai_tanka-shiire_tanka WHERE shohin_id='0003';