某汽车租赁公司建立汽车租赁管理系统,其数据库的部分关系模式如下: 用户: USERS(UserId,Name,Balance),各属性分别表示用户身份证号,姓名,账户余额; 汽车:CARS(CId,CType,CPrice,CStatus),各属性分别表示汽车车牌,汽车型号,日租金,状态。状态0表示未出租,1表示已出租。 租用记录BORROWS(BId,UserId,CId,SDate,EDate,bill)。各属性分别表示租车流水号,用户身份证号,汽车车牌,租用开始时间,归还时间,租车费用。其中已租但尚未还车的记录,其edate和bill均为Null 建表命令如下:*/ create table Users ( UserId char(18) primary key, --身份证 Name varchar(20) not null, --姓名 Balance int check( Balance>=0) --账户余额 ) create table Cars ( CId char(10) primary key, --车牌 CType varchar(30) not null, --汽车型号 CPrice int check(CPrice>=0), --日租金 CStatus tinyint --租车状态,0表示未出租,1表示正在出租 ) create table Borrows ( BId int primary key, -- 租车流水号 UserId char(18) foreign key references Users(UserId), CId char(10) foreign key references Cars(CId), SDate date, -- 租车开始日期 EDate date ,-- 还车日期,未还车则为null Bill int --本次消费金额, 未还车则为null )请在borrows表创建insert触发器,实现复杂约束: 用户试图租车时,如果用户有已经在租,尚未归还的车辆,则不允许租车,输出提示信息:有车尚未归还。如果账户余额小于所租车辆的日租金,则也不允许租车,并输出提示信息:账户余额不足。其他情况,允许租车(即允许该insert命令)
时间: 2023-11-22 08:53:27 浏览: 84
触发器的代码如下:
```sql
CREATE TRIGGER borrow_trigger
BEFORE INSERT ON Borrows
FOR EACH ROW
BEGIN
DECLARE num_rented INT;
DECLARE user_balance INT;
SELECT COUNT(*) INTO num_rented FROM Borrows WHERE UserId = NEW.UserId AND EDate IS NULL;
IF num_rented > 0 THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '有车尚未归还';
ELSE
SELECT Balance INTO user_balance FROM Users WHERE UserId = NEW.UserId;
SELECT CPrice INTO @car_price FROM Cars WHERE CId = NEW.CId;
IF user_balance < @car_price THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '账户余额不足';
END IF;
END IF;
END;
```
该触发器在每次对Borrows表进行插入操作之前执行。首先查询该用户是否有已经在租,尚未归还的车辆,若有,则输出提示信息;否则,查询该用户的账户余额是否小于所租车辆的日租金,若是,则输出提示信息;否则,允许插入数据。注意,触发器中使用了SIGNAL语句输出提示信息,而不是简单的ROLLBACK或者直接抛出异常,这是因为ROLLBACK会导致所有的修改都被回滚,而抛出异常可能会影响到调用该SQL语句的程序。因此,使用SIGNAL语句可以避免这两种情况。
阅读全文