(1) 创建一个数据库BANK和数据表: CardInfo(cardID char(19), --银行卡号 pass char(6), --密码 balance money --账户余额 ); 输入两条记录: A账户:1234567890123456789 888888 5000 B账户:0123456789123456789 666666 1000 TranInfo(transdate date, --转怅日期 cardID char(19), --银行卡号 transtype char(4), --转账类型:支取和存入 transmoney money --转账金额 );(2) 问题描述。 如果银行A账户转账1000元到B账户,当钱刚从A账户里取出来(还没来得及转入B账户),突然断电了,这时A账尸就莫名其妙的损失了1000 元。事务就是为了避免这种情况发生,只有当A账户减少1000,并且A账户存入1000之后,这个转账才算成功,所以需要将“存款”和“取款”写到一个事务中。 1) 创建存储过程proc_takemoney,完成转账过程中的账户余额变换及存储支取和存入记录。存储过程参数为,转出卡号、密码、金额以及收方卡号。 2) 调用存储过程proc_takemoney,完成从A账户转1000元到B账户。 5、事务保存点 定义一个事务,向课程表Course添加三条记录(X006,通信技术,48,3;H001,网络安全,48,3;H002,通讯协议,48,3),每个插入命令后面均设置一个保存点,使用回滚到保存点,最后提交事务,只能前两条记录添加成功。
时间: 2024-03-01 13:56:18 浏览: 117
(1) 创建数据库BANK和数据表:
```
CREATE DATABASE BANK;
GO
USE BANK;
GO
CREATE TABLE CardInfo (
cardID CHAR(19),
pass CHAR(6),
balance MONEY
);
CREATE TABLE TranInfo (
transdate DATE,
cardID CHAR(19),
transtype CHAR(4),
transmoney MONEY
);
```
输入两条记录:
```
INSERT INTO CardInfo VALUES ('1234567890123456789', '888888', 5000);
INSERT INTO CardInfo VALUES ('0123456789123456789', '666666', 1000);
```
(2) 创建存储过程proc_takemoney,完成转账过程中的账户余额变换及存储支取和存入记录。存储过程参数为,转出卡号、密码、金额以及收方卡号。
```
CREATE PROCEDURE proc_takemoney
@fromcard CHAR(19),
@pass CHAR(6),
@money MONEY,
@tocard CHAR(19)
AS
BEGIN
SET NOCOUNT ON;
-- 检查密码是否正确
DECLARE @pass_correct BIT;
SELECT @pass_correct = CASE WHEN pass = @pass THEN 1 ELSE 0 END
FROM CardInfo
WHERE cardID = @fromcard;
IF @pass_correct = 0
BEGIN
RAISERROR('密码错误', 16, 1);
RETURN;
END
BEGIN TRANSACTION;
-- 检查余额是否充足
DECLARE @balance MONEY;
SELECT @balance = balance
FROM CardInfo
WHERE cardID = @fromcard;
IF @balance < @money
BEGIN
RAISERROR('余额不足', 16, 1);
RETURN;
END
-- 将钱从转出账户扣除
UPDATE CardInfo
SET balance = balance - @money
WHERE cardID = @fromcard;
-- 将钱转入收款账户
UPDATE CardInfo
SET balance = balance + @money
WHERE cardID = @tocard;
-- 记录支取和存入信息
INSERT INTO TranInfo (transdate, cardID, transtype, transmoney)
VALUES (GETDATE(), @fromcard, '支出', @money);
INSERT INTO TranInfo (transdate, cardID, transtype, transmoney)
VALUES (GETDATE(), @tocard, '存入', @money);
COMMIT TRANSACTION;
END;
```
(3) 调用存储过程proc_takemoney,完成从A账户转1000元到B账户。
```
EXEC proc_takemoney '1234567890123456789', '888888', 1000, '0123456789123456789';
```
(4) 事务保存点
```
BEGIN TRANSACTION;
INSERT INTO Course (courseID, courseName, hours, credit)
VALUES ('X006', '通信技术', 48, 3);
SAVE TRANSACTION s1;
INSERT INTO Course (courseID, courseName, hours, credit)
VALUES ('H001', '网络安全', 48, 3);
SAVE TRANSACTION s2;
INSERT INTO Course (courseID, courseName, hours, credit)
VALUES ('H002', '通讯协议', 48, 3);
ROLLBACK TRANSACTION s1;
COMMIT TRANSACTION;
```
以上代码中,我们使用 SAVE TRANSACTION 语句创建了两个保存点 s1 和 s2。在插入第一条记录后,我们创建了保存点 s1,然后插入第二条记录。在插入第三条记录前,我们回滚到了保存点 s1,这样第一条记录和第二条记录就被保留了下来。最后我们提交了整个事务。
阅读全文