程序员大数据 爬虫Python AI Sql首页投稿(暂停使用,暂停投稿)

学习SQL【5】-数据更新

2017-12-06  本文已影响63人  爱吃西瓜的番茄酱
学习.png

数据的更新处理大体可以分为插入(INSERT)、删除(DELETE)和更新(UPDATE)三类,此外,还会给大家介绍数据库中用来管理数据更新的重要概念—事务。

一:数据的插入(INSERT语句)

1:要学习INSERT语句,我们得首先创建一个名为ProductIns的表。

创建表ProductIns的语句如下:

 CREATE TABLE ProductIns
 ( product_id        CHAR(4)             NOT NULL,
   product_name  VARCHAR(100)  NOT NULL,
   product_type    VARCHAR(32)    NOT NULL,
   sale_price         INTEGER           DEFAULT 0,
   purchase_price INTEGER           ,
   regist_date       DATE                  ,   
   PRIMARY KEY(product_id));

如上所示,这里仅仅是创建了一个表,并没有插入数据。
INSERT语句的基本语法:

INSERT INTO <表名> (列名1, 列名2,...) VALUES (值1, 值2,...);

例,向表ProductIns中插入一行数据:

INSERT INTO ProductIns (product_id, product_name, product_type, sale_price, purchase_price, regist_date) VALUES ('0001', 'T衫', '衣服', 1000, 500, '2017-09-20');

将列名和值用逗号分开,分别括在()内,这种形式成为清单。上面的INSERT语句包含如下两个清单:
列清单:

 (product_id, product_name, product_type, sale_price, purchase_price, regist_date)

值清单:

 ('0001', 'T衫', '衣服', 1000, 500, '2017-09-20')

原则上,执行一次INSERT 语句会插入一行数据。

当然很多RDBMS都支持一次插入多行数据,这样的功能称为多行INSERT。
例,多行INSERT(Oracle除外):

INSERT INTO ProductIns VALUES ('0002', '打孔器', '办公用品', 500, 320, '2017-09-11'),
                               ('0003', '运动T衫', '衣服', 4000, 2800, NULL),
                               ('0004', '菜刀', '厨房用具', 3000, 2800, '2017-09-20');

其次,多行INSERT的语法并不适用于所有的RDBMS,该语法适用于的DB2,SQL,SQL Server,PostgreSQL和MySQL,但不适用于Oracle.

2:列清单的省略

对表进行全列INSERT时,可以省略表名后的列清单。

INSERT INTO ProductIns VALUES ('0005', '高压锅', '厨房用具', 6800, 5000, '2017-01-15');

3:插入NULL

INSERT语句中想要给某一列赋予NULL值时,可以直接在VALUES子句的值清单中写入NULL。
例,向purchase列插入中插入NULL:

INSERT INTO ProductIns (product_id, product_name, product_type, sale_price, purchase_price, regist_date) VALUES ('0006', '叉子', '厨房用具', 500, NULL, '2017-09-20');

但是,想要插入NULL的列一定不能有NOT NULL约束。

4:插入默认值

我们还可以向表中插入默认值。可以通过在创建表的CREATE TABLE语句中设置DEFAULT约束来设置默认值。
我们可以通过“DEFAULT <默认值>”的形式来设定默认值。
例,创建表ProductIns的语句:

```SQL CREATE TABLE ProductIns
 ( product_id        CHAR(4)             NOT NULL,
   product_name  VARCHAR(100)  NOT NULL,
   product_type    VARCHAR(32)    NOT NULL,
   sale_price         INTEGER           DEFAULT 0,   -- 销售单价的默认值设定为0
   purchase_price INTEGER           ,
   regist_date       DATE                  ,   
   PRIMARY KEY(product_id));

默认值的使用方法通常有显示和隐式两种。

通过显示方式设定默认值,在VALUES子句中指定DEFAULT关键字:

INSERT INTO ProductIns (product_id, product_name, product_type, sale_price, purchase_price, regist_date) VALUES ('0007', '擦菜板', '厨房用具', DEFAULT, 790, '2017-04-28');

确认插入的数据行

SELECT * FROM ProductIns WHERE product_id = '0007';

执行结果:

 product_id | product_name | product_type | sale_price | purchase_price | regist_date------------+--------------+--------------+------------+----------------+-------------
 0007       | 擦菜板       | 厨房用具     |          0 |            790 | 2017-04-28
(1 行记录)

通过隐式方法设定默认值,在清单中省略相应的列和值:

INSERT INTO ProductIns (product_id, product_name, product_type, purchase_price, regist_date) VALUES ('0007', '擦菜板', '厨房用具', 790, '2017-09-28');

省略INSERT语句中的列名,就会自动设定为该列的默认值(没有默认值的会设定为NULL)。

5:从其他表中复制数据

要学习该方法,我们首先得创建一张表。
创建ProductCopy表的CREATE TABLE语句:

--用来插入数据的复制表
 CREATE TABLE ProductCopy
 ( product_id  CHAR(4)  NOT NULL,
   product_name  VARCHAR(100)  NOT NULL,
   product_type  VARCHAR(32)  NOT NULL,
   sale_price  INTEGER  ,
   purchase_price  INTEGER  ,
   regist_date  DATE  ,   PRIMARY KEY (product_id));

下面我们就尝试一下将Product表中的数据插入到ProductCopy表中吧。

--将商品表中的数据复制到商品复制表中
 INSERT INTO ProductCopy (product_id, product_name, product_type, sale_price, purchase_price, regist_date) SELECT product_id, product_name, product_type, sale_price,                        purchase_price, regist_date    
   FROM Product;

使用INSERT…SELECT语句可以在关联的表之间传递数据。
下面我们尝试一下使用包含GROUP BY 子句的SELECT语句进行插入:
创建ProductType表的CREATE TABLE语句

--根据商品种类进行汇总的表
 CREATE TABLE ProductType
 ( product_type  VARCHAR(32)  NOT NULL,
   sun_sale_price  INTEGER  ,
   sum_purchase_price  INTEGER  ,   
   PRIMARY KEY (product_type));

下面我们使用INSERT…SELECT语句,从Product表中选取数据插入到这张表中吧:

--插入其他表中数据合计值的INSERT...SELECT语句
 INSERT INTO ProductType (product_type, sun_sale_price,     sum_purchase_price) 
 SELECT product_type, SUM(sale_price), SUM(purchase_price)   
  FROM Product  
  GROUP BY product_type;

确认插入的数据:

SELECT * FROM ProductType;

执行结果

 product_type | sun_sale_price | sum_purchase_price--------------+----------------+--------------------
 衣服         |           5000 |               3300
 办公用品     |            600 |                320
 厨房用具     |          11180 |               8590
(3 行记录)

INSERT 语句的SELECT语句中,可以使用WHERE子句或者GROUP BY子句等任何SQL语法(但使用ORDER BY子句不会产生任何效果)。

二:数据的删除(DELETE语句)

1:DROP TABLE语句和DELETE语句

删除数据的方法大体可以分为以下两种:

① DROP TABLE语句:可以将表完全删除
② DELETE语句:删除表中的全部数据,会留下表(容器)

2:DELETE语句的基本语法

保留数据表,仅删除全部数据行的DELETE语句:

DELETE FROM <表名>;

例如,清空Product表:

DELETE FROM  Product;

DELETE语句删除的对象不是表或者列,而是记录(行)。

3:指定删除对象的DELETE语句

删除部分数据行的DELETE语句如下:

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

例如,删除销售单价大于等于4000日元的数据:

DELETE FROM Product  WHERE sale_price >= 4000;

确认删除后的结果:

SELECT * FROM Product;

执行结果:

 product_id | product_name | product_type | sale_price | purchase_price | regist_date------------+--------------+--------------+------------+----------------+-------------
 0001       | T衫          | 衣服         |       1000 |            500 | 2017-09-20
 0002       | 打孔器       | 办公用品     |        500 |            320 | 2017-09-11
 0004       | 菜刀         | 厨房用具     |       3000 |           2800 | 2017-09-20
 0006       | 叉子         | 厨房用具     |        500 |                | 2017-09-20
 0007       | 擦菜板       | 厨房用具     |        880 |            790 | 2016-04-28
 0008       | 圆珠笔       | 办公用品     |        100 |                | 2017-11-11
(6 行记录)

可以通过WHERE子句指定对象条件来删除部分数据。
与SELECT语句不同的是,DELETE语句中不能使用GROUP BY、HAVING和ORDER BY三类子句,而只能使用WHERE 子句。

三:数据的更新(UPDATE语句)

1:UPDATE语句的基本用法

改变表中数据的UPDATE语句:

UPDATE <表名>   SET <列名> = <表达式>;

例如,将登记日期全部更新为“2017-10-10”:

UPDATE Product   SET regist_date = '2017-10-10';

通过SELECT语句来确认一下更新内容:

--确认更新内容
 SELECT * FROM Product;

执行结果:

 product_id | product_name | product_type | sale_price | purchase_price | regist_date------------+--------------+--------------+------------+----------------+-------------
 0001       | T衫          | 衣服         |       1000 |            500 | 2017-10-10
 0002       | 打孔器       | 办公用品     |        500 |            320 | 2017-10-10
 0004       | 菜刀         | 厨房用具     |       3000 |           2800 | 2017-10-10
 0006       | 叉子         | 厨房用具     |        500 |                | 2017-10-10
 0007       | 擦菜板       | 厨房用具     |        880 |            790 | 2017-10-10
 0008       | 圆珠笔       | 办公用品     |        100 |                | 2017-10-10
(6 行记录)

2:指定条件的UPDATE语句

更新部分数据行的UPDATE语法如下:

UPDATE <表名>    SET <列名> = <表达式> WHERE <条件>;

例如,将商品种类为厨房用具的记录的销售单价更新为原来的十倍:

UPDATE Product   SET sale_price = sale_price * 10
  WHERE product_type = '厨房用具';

确认更新内容:

SELECT * FROM Product ORDER BY product_id;

执行结果:

product_id | product_name | product_type | sale_price | purchase_price | regist_date------------+--------------+--------------+------------+----------------+-------------
 0001       | T衫          | 衣服         |       1000 |            500 | 2017-10-10
 0002       | 打孔器       | 办公用品     |        500 |            320 | 2017-10-10
 0004       | 菜刀         | 厨房用具     |      30000 |           2800 | 2017-10-10
 0006       | 叉子         | 厨房用具     |       5000 |                | 2017-10-10
 0007       | 擦菜板       | 厨房用具     |       8800 |            790 | 2017-10-10
 0008       | 圆珠笔       | 办公用品     |        100 |                | 2017-10-10
(6 行记录)

3:使用NULL进行更新

使用UPDATE也可以将列更新为NULL(该更新俗称为NULL清空)。
例如,将商品编号为0008的数据(圆珠笔)的登记日期更新为NULL:

UPDATE Product   SET regist_date = NULL
  WHERE product_id = '0008';

确认更新内容:

SELECT * FROM Product ORDER BY product_id;

执行结果:

product_id | product_name | product_type | sale_price | purchase_price | regist_date------------+--------------+--------------+------------+----------------+-------------
 0001       | T衫          | 衣服         |       1000 |            500 | 2017-10-10
 0002       | 打孔器       | 办公用品     |        500 |            320 | 2017-10-10
 0004       | 菜刀         | 厨房用具     |      30000 |           2800 | 2017-10-10
 0006       | 叉子         | 厨房用具     |       5000 |                | 2017-10-10
 0007       | 擦菜板       | 厨房用具     |       8800 |            790 | 2017-10-10
 0008       | 圆珠笔       | 办公用品     |        100 |                |
(6 行记录)

如上所示,圆珠笔的登记日期被更新为NULL。
使用UPDATE语句可以将值清空为NULL(但只限于未设置NOT NULL约束的列)。

4:多列更新

UPDATE语句的SET 子句支持同时将多个列作为更新对象。
使用逗号对列进行分隔:

UPDATE Product   SET sale_price = sale_price * 10,
           purchase_price = purchase_price / 2
  WHERE product_type = '厨房用具';

确认更新内容:

SELECT * FROM Product ORDER BY product_id;

执行结果:

product_id | product_name | product_type | sale_price | purchase_price | regist_date------------+--------------+--------------+------------+----------------+-------------
 0001       | T衫          | 衣服         |       1000 |            500 | 2017-10-10
 0002       | 打孔器       | 办公用品     |        500 |            320 | 2017-10-10
 0004       | 菜刀         | 厨房用具     |     300000 |           1400 | 2017-10-10
 0006       | 叉子         | 厨房用具     |      50000 |                | 2017-10-10
 0007       | 擦菜板       | 厨房用具     |      88000 |            395 | 2017-10-10
 0008       | 圆珠笔       | 办公用品     |        100 |                |
(6 行记录)

如上所示,厨房用具的销售单价更新为原来的10倍,进货单价更新为原来一半。

四:事务

1:什么是事务

在RDBMS中,事务是对表中数据进行更新的单位。
例如,更新商品信息的事务:
① 将叉子的销售单价降低1000元

PDATE Product   SET sale_price = sale_price - 1000
  WHERE product_name = '叉子';

② 将T衫的销售单价上浮1000元

UPDATE Product   SET sale_price = sale_price + 1000
  WHERE product_name = 'T衫';

上述两个操作一定要作为同一个处理单元执行。遇到这种需要在同一个处理单元中执行一系列更新操作的情况,一定要使用事务来进行处理。所以,事务是需要在同一个处理单元中执行一系列更新处理的集合。

2:创建事务

在RDBMS中创建事务的语法:

事务开始语句;

     DML语句1;
     DML语句2;
     DML语句3;
...
事务结束语句(COMMIT或者ROLLBACK);

使用事务开始语句和事务结束语句,将一系列的DML语句括起来,就实现了一个事务。

不同的DBMS的事务开始语句各不相同。
● SQL Server PostgreSQL

BEGIN TRANSACTION

● MySQL

START TRANSACTION

● Oracle、DB2

例如,更新商品信息的事务:
● SQL Server PostgreSQL

BEGIN TRANSACTION;

 --将叉子的销售单价降低1000元
 UPDATE Product   SET sale_price = sale_price - 1000
  WHERE product_name = '叉子';UPDATE 1
 --将T衫的销售单价上浮1000元
 UPDATE Product   SET sale_price = sale_price + 1000
  WHERE product_name = 'T衫';UPDATE 1
 COMMIT;

● MySQL

START TRANSACTION;

 --将叉子的销售单价降低1000元
 UPDATE Product   SET sale_price = sale_price - 1000
  WHERE product_name = '叉子';UPDATE 1
 --将T衫的销售单价上浮1000元
 UPDATE Product   SET sale_price = sale_price + 1000
  WHERE product_name = 'T衫';UPDATE 1
 COMMIT;

● Oracle、DB2

 --将叉子的销售单价降低1000元
 UPDATE Product   SET sale_price = sale_price - 1000
  WHERE product_name = '叉子';UPDATE 1
 --将T衫的销售单价上浮1000元
 UPDATE Product   SET sale_price = sale_price + 1000
  WHERE product_name = 'T衫';UPDATE 1
 COMMIT;

● COMMIT—提交处理

COMMIT是提交事务包含的全部更新处理的结束指令,一旦提交,就无法恢复到事务开始前的状态了。所以在事务结束时一定要仔细确认。

● ROLLBACK—取消处理

ROLLBACK是取消事务包含的全部更新处理的结束指令,相当于文件处理中的放弃保存。一旦回滚,数据库就会恢复到事务开始前的状态。
事务回滚的例子(SQL Server PostgreSQL):

BEGIN TRANSACTION;

 --将叉子的销售单价降低1000元
 UPDATE Product   SET sale_price = sale_price - 1000
  WHERE product_name = '叉子';UPDATE 1
 --将T衫的销售单价上浮1000元
 UPDATE Product   SET sale_price = sale_price + 1000
  WHERE product_name = 'T衫';UPDATE 1ROLLBACK;

3:ACID特性

DBMS的事务都遵循四种特性,将这四种特性的首字母结合起来统称为ACID特性。这是所有DBMS都必须遵守的规则。
● 原子性(Atomicity)
原子性是指在事务结束后,其中所包含的更新处理要么全部执行,要么完全不执行。

● 一致性(Consistency)

一致性指的是事务中包含的处理要满足数据库提前设置的约束,如主键约束或者NOT NULL约束等。
一致性也称为完整性。

● 隔离性(Isolation)

隔离性指的是保证不同事务之间互不干扰的特性。

● 持久性(Durability)

持久性也可以成为耐久性,指的是在事务结束后,DBMS能够保证该时间点的数据状态会被保存的特性。
保证持久性的方法根据实现的不同而不同,其中最常见的就是讲事务的执行记录保存到硬盘灯存储介质中(该执行记录称为日志)。当发生故障时,可以通过日志恢复到故障发生前的状态。

每天学习一点点,每天进步一点点。

上一篇 下一篇

猜你喜欢

热点阅读