回到目录
4.1 A使用CREATE TABLE语句创建出一张空的Product表,并执行了如下语句向其插入数据。紧接着,B连接上该数据库,并执行了一条语句。这时B能得到怎样的查询结果?
-- A执行的SQL语句
BEGIN TRANSACTION;
INSERT INTO Product VALUES ('0001', 'T恤', '衣服', 1000, 500, '2009-09-20');
INSERT INTO Product VALUES ('0002', '打孔器', '办公用品', 500, 320, '2009-09-11');
INSERT INTO Product VALUES ('0003', '运动T恤', '衣服', 4000, 2800, NULL);
-- B执行的SQL语句
SELECT * FROM Product;
-- 解答
/*
什么都查询不到。
由于A显式地输入了事务开始指令,则直到A输入事务结束指令commit之前,该事务仍属于未结束状态。
根据事务ACID特性中的隔离性,一个事务在结束之前,对其他事务是不可见的。
而B的SQL语句没有显式输入事务开始结束语句,则根据自动提交模式将该语句括在begin和commit之间。
B的SQL语句就是一个事务,而A中未结束的事务对B的事务是不可见的,因此什么都查询不到。
*/
4.2 如下所示,有一张包含3条记录的Product表。使用如下INSERT语句复制这三行数据,请说出该语句的执行结果。
Product表
![0c7e9114c999090fbdae581bd83a32c1.png](https://i-blog.csdnimg.cn/blog_migrate/163f9561966619b03d37fc9fc417104d.png)
-- INSERT语句
INSERT INTO Product SELECT * FROM Product;
-- 解答
/*
如果能正常执行,表中数据将会变成6行,且新增的3行和原来3行完全一样,相当于复制。
但实际上执行会发生错误,一行数据都插入不了。
因为,插入数据会违反表约束中的主键约束,主键一般为商品编号,则主键列中的值不能重复。
因为主键是用来唯一确定一行记录的,因此不能重复。
这也是事务ACID特性中的一致性,必须满足数据库之前设置的约束,
*/
4.3 以4.2中的Product表为基础,再创建一张包含利润列的新表ProductMargin。创建表的语句如下所示。请写出向新表插入如下数据的SQL语句,利润自行计算。
-- 创建ProductMargin表
CREATE TABLE ProductMargin
(product_id CHAR(4) NOT NULL,
product_name VARCHAR(100) NOT NULL,
sale_price INTEGER,
purchase_price INTEGER,
margin INTEGER,
PRIMARY KEY(product_id));
-- 解答
INSERT INTO ProductMargin-- 全列插入时可省略列清单
SELECT product_id, product_name, sale_price, purchase_price, sale_price - purchase_price
FROM Product;
4.4 对4.3中的ProductMargin表进行如下更改。
-- 更改
/*
1.将运动T恤售价从4000降至3000。
2.然后重新计算运动T恤的利润。
*/
-- 解答
UPDATE ProductMargin
SET sale_price = 3000
WHERE product_name = '运动T恤';
UPDATE ProductMargin
SET margin = sale_price - purchase_price;