也许,年少时不能遇见太过惊艳的人,就像你不能做我的诗,而我无法成为你的梦!
一、实验目的
学习实体完整性的建立,以及实践违反实体完整性的结果。学习建立外键,以及利用Foreign key…references子句以及各种约束保证参照完整性。学习用户自定义约束,并实践用户完整性,利用短语not null,unique,check保证用户定义完整性。
二、实验内容
1. 问题描述
2. 数据库设计
(1)利用create语句分别创建四个表,同时要注意标注实体完整性。
(2)使用insert语句插入初始数据。
(3)事务操作要在事务操作之下完成,数据库对象的begin transaction、commit transaction方法分别用来启动、提交事务。
(4)①使用delete语句删除Products表中的一条数据,但由于设置了NO ACTION,最终拒绝删除;
②使用delete语句删除Categories表中的一条数据,但由于多重级联删除失败。可修改原级联关系,改为级联删除操作;
③使用update语句来更新Categories的主键。出错原因:由于在设置外键的时候没有显示声明更新操作,则数据库会使用默认的no action操作,导致无法更新;可以声明更新操作时级联更新。
(5)通过add constraint 语句使主键取值大于0,Products表中的price列取值大于0;也可创建触发器使插入记录的prod_id值大于表中已知数据的最大prod_id值。
3. 程序实现与测试
(1)建表SQL语句如下:
create table Categories(
cate_id int not null,
cate_name char(20) not null,
description text null,
primary key(cate_id)
);
create table Products(
prod_id int not null,
prod_name char(20) not null,
category_id int null,
price money null,
primary key(prod_id)
);
create table Orders(
order_id int not null,
customer_id int null,
order_date datetime null,
modify_date datetime null,
product_id int not null,
quantity int not null,
primary key(order_id)
);
create table Customer(
cust_id int not null,
cust_name char(20) not null,
address char(100) null,
telephone char(15) null,
primary key(cust_id)
);
运行结果:
(2)插入SQL语句如下:
①INSERT INTO Categories VALUES
(1,'食品',NULL),
(2,'生活用品',NULL),
(3,'家用电器',NULL),
(4,'科技产品',NULL),
(5.'学习用品',NULL);
②INSERT INTO Products VALUES
(01,'可乐',1,3),
(02,'洗发水',2,20),
(03,'微波炉',3,100),
(04,'智能手表',4,500),
(05,'签字笔',5,2);
③INSERT INTO Orders VALUES
(001,0001,'2020-01-02','2020-01-03',01,4),
(002,0002,'2020-02-02','2020-02-03',02,2),
(003,0003,'2020-02-02',NULL,03,1),
(004,0004,'2020-05-04',NULL,04,1),
(005,0005,'2020-03-06',NULL,05,8);
④INSERT INTO Customer VALUES
(0001,'张三','起义路号','020-39330001'),
(0002,'李四','中山路号','020-84110013'),
(0003,'王五','新港西路号','020-84111593'),
(0004,'马六','翔宇路号','020-84117089'),
(0005,'王五','华中路号','020-39330021');
(3)SQL语句如下:
USE Shop
SET XACT_ABORT ON
BEGIN TRANSACTION T1
INSERT INTO Products VALUES(14,'牛奶',1,2.5);
INSERT INTO Products VALUES(15,'香皂',2,5);
INSERT INTO Products VALUES(16,'饼干',1,5.5);
SELECT * FROM Products
COMMIT TRANSACTION T1;
运行结果:
(4)满足如下级联关系:
--①
USE Shop
ALTER TABLE Products
ADD CONSTRAINT P1 FOREIGN KEY (Category_id) REFERENCES Categories (cate_id)
ON DELETE CASCADE;
--②
ALTER TABLE Orders
ADD CONSTRAINT O1 FOREIGN KEY (Product_id) REFERENCES Products (prod_id)
ON DELETE NO ACTION;
--③
ALTER TABLE Orders
ADD CONSTRAINT O2 FOREIGN KEY (Customer_id) REFERENCES Customer (cust_id)
ON DELETE SET NULL;
进行如下操作:
--①
USE Shop
DELETE FROM Products
WHERE prod_id=1;
--②
USE Shop
DELETE FROM Categories
WHERE cate_id=1;
--修改原级联关系:
ALTER TABLE Orders
DROP CONSTRAINT O1;
ALTER TABLE Orders
ADD CONSTRAINT O1 FOREIGN KEY (Product_id) REFERENCES Products(prod_id)
ON DELETE CASCADE;
--再次执行删除后,查看各表删除后的情况:
SELECT * FROM Categories;
SELECT * FROM Products;
SELECT * FROM Orders;
--③
USE Shop
UPDATE Categories
SET cate_id=1
WHERE cate_id=3;
--增加更新操作时级联更新的约束条件:
ALTER TABLE Products
ADD CONSTRAINT P2 FOREIGN KEY (Category_id) REFERENCES Categories (cate_id)
ON UPDATE CASCADE;
--再次更新后查询两个表的变化:
SELECT * FROM Categories;
SELECT * FROM Products;
--(5)SQL语句如下:
ALTER TABLE Categories
ADD CONSTRAINT C1 CHECK(cate_id>0);
ALTER TABLE Products
ADD CONSTRAINT P3 CHECK(prod_id>0);
ALTER TABLE Products
ADD CONSTRAINT P4 CHECK(price>0);
ALTER TABLE Orders
ADD CONSTRAINT O3 CHECK(order_id>0);
ALTER TABLE Customer
ADD CONSTRAINT Cu1 CHECK(cust_id>0);
--创建触发器:
USE Shop
GO
CREATE TRIGGER T1 ON Products
FOR INSERT,UPDATE
AS
IF(SELECT prod_id FROM INSERTED)<3
BEGIN
PRINT 'prod_id must be more than 3!Transaction fail'
ROLLBACK TRANSACTION
END;
--插入prod_id小于3的数据:
INSERT INTO Products VALUES(1,'牙刷',2,25);