/*---------1.创建E-R图(另用Visio完成)---------*/
/*---------------2.创建数据库--------------*/
set nocount on --关闭提示信息
--以下过程是启用外围配器--
-- To allow advanced options to be changed.
EXEC sp_configure 'show advanced options', 1
GO
-- To update the currently configured value for advanced options.
RECONFIGURE
GO
-- To enable the feature.
EXEC sp_configure 'xp_cmdshell', 1
GO
-- To update the currently configured value for this feature.
RECONFIGURE
GO
--在D盘下创建目录bank
exec xp_cmdshell 'mkdir d:\bank', no_output
go
--如果数据库中已有数据库bankDB,则删除
use master
go
if exists(select * from sysdatabases where name='bankDB')
drop database bankDB
go
--建库
create database bankDB
on primary(
name='bankDB_data',
filename='d:\bank\bankDB_data.mdf',
size=3mb,
maxsize=5mb,
filegrowth=15%
)
log on(
name='bankDB_log',
filename='d:\bank\bankDB_log.mdf',
size=1mb,
maxsize=3mb,
filegrowth=15%
)
go
/*---------------3.创建表--------------*/
--1.创建userInfo用户信息表
use bankDB
go
create table userInfo
(
customerID int IDENTITY(1,1) primary key, --顾客编号
customerName varchar(10) not null, --开户名
PID varchar(18) not null, --身份证号
telephone varchar(13) not null, --联系电话
address varchar(50) --居住地址
)
go
--2.创建cardInfo银行卡信息表
create table cardInfo
(
cardID char(19) primary key, --卡号
curType varchar(5) not null, --货币种类
savingType varchar(8) not null, --存款类型
openDate datetime not null, --开户日期
openMoney money not null, --开户金额
balance money not null, --余额
pass char(6) not null, --密码
IsReportLoss bit not null, --是否挂失
customerID int not null --顾客编号,外键
)
go
--3.创建transInfo交易信息表
create table transInfo
(
transDate datetime not null, --交易日期
cardID char(19) not null, --卡号,外键
transType char(4) not null, --交易类型
transMoney money not null, --交易金额
remark text --备注
)
go
/*------------4.为每个表添加约束 5.创建关系(其实也是约束)--------------*/
alter table userInfo
add constraint CK_PID check(len(PID)=15 or len(PID)=18),
constraint UQ_PID unique (PID),
constraint CK_telephone check (telephone like '[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
or telephone like '[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
or telephone like '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]')
alter table cardInfo
add constraint CK_cardID check (cardID like '1010 3576 [0-9][0-9][0-9][0-9] [0-9][0-9][0-9][0-9]'),
constraint DF_curType default 'RMB' for curType,
constraint CK_savingType check (savingType in ('活期','定活两便','定期')),
constraint DF_openDate default (getdate()) for openDate,
constraint CK_openMoney check (openMoney>=1),
constraint CK_balance check (balance>=1),
constraint CK_pass check (pass like '[0-9][0-9][0-9][0-9][0-9][0-9]'),
constraint DF_pass default 888888 for pass,
constraint DF_IsReportLoss default 0 for IsReportLoss,
constraint FK_customerID foreign key (customerID) references userInfo(customerID)
alter table transInfo
add constraint PK_transDate_cardID primary key (transDate,cardID),
constraint DF_transDate default (getdate()) for transDate,
constraint FK_cardID foreign key (cardID) references cardInfo(cardID),
constraint CK_transType check (transType in ('存入','支取')),
constraint CK_transMoney check (transMoney>0)
go
/*---------------6. 插入数据--------------*/
-- 1.张三开户; 2.李四开户; 3.张三支取900,李四存入5000
insert into userInfo (customerName,PID,telephone,address)
values ('张三','123456789012345','010-67898978','北京海淀')
insert into cardInfo
values ('1010 3576 1234 5678',default,'活期',default,1000,1000,default,default,1)
-------------------------------------------------------------------------------------
insert into userInfo (customerName,PID,telephone,address)
values ('李四','321245678912345678','0478-44443333',default)
insert into cardInfo
values ('1010 3576 1212 1134',default,'活期',default,1,1,default,default,2)
-------------------------------------------------------------------------------------
insert into transInfo
values (default,'1010 3576 1234 5678','支取',900,default)
update cardInfo set balance=balance-900 where cardId='1010 3576 1234 5678'
insert into transInfo
values (default,'1010 3576 1212 1134','存入',5000,default)
update cardInfo set balance=balance+5000 where cardId='1010 3576 1212 1134'
/*---------------7. 常规业务模拟--------------*/
print ''
print '-----7.常规业务模拟-----'
print ''
--1.张三的密码改为123456,李四的密码改为123123
update cardInfo set pass=123456 where cardId='1010 3576 1234 5678'
update cardInfo set pass=123123 where cardId='1010 3576 1212 1134'
--2.李四的银行卡挂失
update cardInfo set IsReportLoss=1 where cardId='1010 3576 1212 1134'
--3.统计银行的资金流通余额和盈余结算
declare @inMoney money --总存入量
declare @outMoney money --总支取量
select @inMoney=sum(transMoney) from transInfo where transType='存入'
select @outMoney=sum(transMoney) from transInfo where transType='支取'
print '银行流通余额总计为:'+convert(varchar(20),@outMoney*0.008-@inMoney*0.003)+'RMB'
--4.查询本周开户的卡号,显示该卡的相关信息
print '-----7.(4.1)查询本周开户的卡号-----'
select * from cardInfo where datediff(week,openDate,getdate())=0 --注意:不需要判断年份
print '-----7.(4.2)查询7天内开户的卡号-----'
select * from cardInfo where abs(datediff(day,openDate,getdate()))<=7
--5.查询本月交易金额最高的卡号
print '-----7.(5.1)查询本月交易金额最高的卡号-----'
select top 1 cardID as 本月交易金额最高的卡号 from transInfo --注意:不需要判断年份
where datediff(month,transdate,getdate())=0 order by transMoney desc
print '-----7.(5.2)查询30天内交易金额最高的卡号-----'
select top 1 cardID as 本月交易金额最高的卡号 from transInfo
where abs(datediff(month,transdate,getdate()))<=30
order by transMoney desc
--6.查询挂失账号的客户信息
select customerName as 挂失用户姓名,PID as 身份证号,telephone as 电话号码,address as 地址
from userInfo where customerID in
(select customerID from cardInfo where IsReportLoss=1)
--7.催款提醒业务
select customerName as 需催款提醒用户姓名 from userinfo where customerID in
(select customerID from cardInfo where balance<200)
/*---------------8. 创建索引和视图--------------*/
print ''
print '-----8.(1)(2)创建索引并用索引查询张三的交易记录-----'
print ''
use bankDB
go
--检测是否存在索引(索引存放在系统表sysindexes中),如果存在索引则删除
if exists (select name from sysindexes where name ='IX_transInfo_cardID')
drop index transInfo.IX_transInfo_cardID
--1.为transInfo表的cardID列创建重复索引,填充因子为70%
create nonclustered index IX_transInfo_cardID on transInfo(cardID)
with fillfactor=70
go
--2.用创建的索引查询张三的交易记录
select customerName as 开户名,transInfo.cardID as 卡号,
transDate as 交易日期,transType as 交易类型,transMoney as 交易金额
from transInfo with (index=IX_transInfo_cardID) inner join cardInfo
on transInfo.cardID=cardInfo.cardID inner join userInfo
on userInfo.customerID=cardInfo.customerID where customerName='张三'
go
print ''
print '-----8.(3)为3个表创建3个视图,要求字段名全为中文字段名,并用视图查询-----'
print ''
go
--3.为3个表创建3个视图,要求字段名全为中文字段名
if exists (select * from sysobjects where name='view_userInfo')
drop view view_userInfo
if exists (select * from sysobjects where name='view_cardInfo')
drop view view_cardInfo
if exists (select * from sysobjects where name='view_transInfo')
drop view view_transInfo
go
create view view_userInfo
as
select customerID as 客户编号,customerName as 开户姓名,PID as 身份证号码,
telephone as 电话号码,address as 居住地址
from userInfo
go
create view view_cardInfo
as
select cardID as 卡号,curType as 货币类型,savingType as 存款类型,openDate as 开户日期,
balance as 余额,pass as 密码,IsReportLoss as 是否挂失,customerID as 客户编号
from cardInfo
go
create view view_transInfo
as
select transDate as 交易日期,transType as 交易类型,cardID as 卡号,transMoney as 交易金额,remark as 备注
from transInfo
go
select * from view_userInfo
select * from view_cardInfo
select * from view_transInfo
/*---------------9. 创建存储过程--------------*/
print ''
print '-----9.(1)取钱或存钱的存储过程-----'
print ''
--9.(1)取钱或存钱的存储过程
use bankDB
go
--如已存在需建的存储过程,则删除
if exists (select * from sysobjects where name='proc_takeMoney')
drop procedure proc_takeMoney
go
--创建存储过程
create procedure proc_takeMoney
@card char(19), --卡号
@m money, --钱的数量
@type char(4), --交易的类型
@inputPass char(6), --输入密码
@fail int output --输出参数
as
set @fail=0
print '交易正在进行,请稍候......'
declare @balance money --用户交易之前的余额
select @balance=balance from cardInfo where cardID=@card
if(@type='支取')
begin
if (@inputPass=(select pass from cardInfo where cardID=@card))
begin
if (@m+1>@balance)
begin
set @fail=1
raiserror ('交易失败!余额不足!',16,1)
end
else
begin
update cardInfo set balance=balance-@m where cardID=@card
set @balance=@balance-@m
print '交易成功!交易金额:'+convert(varchar(10),@m)
end
end
else
begin
set @fail=1
print '密码输入错误!'
end
end
else --程序中一般会限定用户只能输入限定的情况,故简化处理
begin
update cardInfo set balance=balance+@m where cardID=@card
set @balance=@balance+@m
print '交易成功!交易金额:'+convert(varchar(10),@m)
end
print '卡号'+@card+' 余额:'+convert(varchar(10),@balance)
go
--执行存储过程前的用户及卡上的信息
select customerName as 开户名,cardID as 卡号,balance as 余额,pass as 密码
from cardInfo inner join userInfo on cardInfo.customerID=userInfo.customerID
--执行存储过程
declare @fail int
print '张三的卡号支取300:'
exec proc_takeMoney '1010 3576 1234 5678',300,'支取','123456',@fail output
print ''
print '李四的卡号存入500:'
exec proc_takeMoney '1010 3576 1212 1134',500,'存入','123123',@fail output
go
---------------------------------------------------------------------------------
print ''
print '-----9.(2)产生随机卡号的存储过程-----'
print ''
--9.(2)产生随机卡号的存储过程
--如已存在需建的存储过程,则删除
if exists (select * from sysobjects where name='proc_randCardID')
drop procedure proc_randCardID
go
--创建存储过程
create procedure proc_randCardID @randCardID char(19) output
as
declare @r numeric(15,8) --15位数,保留8位小数
select @r=rand((datepart(mm,getdate())*100000)+ -- 当前的月份*100000 (注:它们只是随机因子而已,得数并无太大意义)
(datepart(ss,getdate())*1000)+ -- +当前的秒数*1000
(datepart(ms,getdate()))) -- +当前的毫秒
--print '随机产生的数为:'+convert(char(10),@r)
set @randCardID='1010 3576 '+substring(convert(char(10),@r),3,4)+' '+
substring(convert(char(10),@r),7,4)
go
--测试:产生随机卡号
declare @mycardID char(19)
exec proc_randCardID @mycardID output
print '产生的随机卡号为:'+@mycardID
---------------------------------------------------------------------------------
print ''
print '-----9.(3)开户的存储过程-----'
print ''
go
if exists (select * from sysobjects where name='proc_openAccount')
drop proc proc_openAccount
go
create procedure proc_openAccount
@customerName varchar(10), --开户名
@PID varchar(18), --身份证号
@telephone varchar(13), --电话
@openMoney money, --开户金额
@savingType varchar(8), --开户类型
@address varchar(50)='' --地址
as
declare @mycardID char(19),@customerID int
while(1=1) --循环产生随机卡号, 直到cardInfo表中没有与随机卡号相同的才退出
begin
exec proc_randCardID @mycardID output --调用上一个存储过程产生随机卡号
if not exists(select * from cardInfo where cardID=@mycardID)
break
end
--如果以前没有开过户, 才插入用户表记录(同一身份证号在用户表中只有一条记录)
if not exists(select * from userinfo where pid =@pid)
begin
insert into userInfo (customerName,PID,telephone,address)
values (@customerName,@PID,@telephone,@address)
end
select @customerID= customerID from userinfo where pid =@PID --取得用户编号
--在卡信息表中插入记录
insert into cardInfo (cardID,savingType,openMoney,balance,customerID)
values (@mycardID,@savingType,@openMoney,@openMoney,@customerID)
print '尊敬的客户,开户成功!系统为您产生的随机卡号为:'+@mycardID
print '开户日期:'+convert(varchar(12),getdate(),111)+' 开户金额:'+convert(varchar(12),@openMoney)
go
--调用此存储过程开户
exec proc_openAccount '王五','334456889012678','2222-63598978',1000,'活期','河南新乡'
exec proc_openAccount '赵二','213445678912342222','0760-44446666',1,'定期'
---------------------------------------------------------------------------------
print ''
print '-----10.创建事务-----'
print ''
if exists(select * from sysobjects where name='proc_transfer')
drop proc proc_transfer
go
create procedure proc_transfer @card1 char(19),@card2 char(19),@outmoney money
as
begin transaction --开始事务
print '开始转账,请稍候......'
declare @sumError int,@fail int
set @sumError=0
exec proc_takeMoney @card1,@outmoney,'支取','123123',@fail output
set @sumError=@sumError+@@error+@fail
if (@sumError>0)
begin
print '转账失败,回滚事务!'
rollback transaction
return
end
exec proc_takeMoney @card2,@outmoney,'存入','123456',@fail output
set @sumError=@sumError+@@error+@fail
if (@sumError>0)
begin
print '转账失败,回滚事务!'
rollback transaction
end
else
begin
print '转账成功,提交事务!'
commit transaction
end
go
--测试上面的事务
declare @money money --定义好转账的金额,方便修改
set @money=20000
print '李四转'+convert(char(8),@money)+'元给张三'
print '转账前的情况:'
select customerName as 开户名,cardID as 卡号,balance as 余额 from userInfo
inner join cardInfo on userInfo.customerID =cardInfo.customerID
where customerName in ('张三','李四')
declare @card1 char(19),@card2 char(19)
select @card1=cardID from cardInfo where customerID=
(select customerID from userInfo where customerName='李四')
select @card2=cardID from cardInfo where customerID=
(select customerID from userInfo where customerName='张三')
exec proc_transfer @card1,@card2,@money
print ''
print '转账后的情况:'
select customerName as 开户名,cardID as 卡号,balance as 余额 from userInfo
inner join cardInfo on userInfo.customerID =cardInfo.customerID
where customerName in ('张三','李四')
---------------------------------------------------------------------------------
print ''
print '-----11.创建登录账号和数据库用户-----'
print ''
use master
go
if exists (select * from syslogins where name='sysAdmin1')
exec sp_droplogin @loginame='sysAdmin1' --删除登录名
exec sp_addlogin 'sysAdmin1','1234' --创建SQL登录账号
exec sp_grantdbaccess 'sysAdmin1','sysAdminDBUser' --创建数据库用户
--将三个表的增、删、改、查权限授予数据库用户sysAdminDBUser
grant insert,delete,update,select on userInfo to sysAdminDBUser
grant insert,delete,update,select on cardInfo to sysAdminDBUser
grant insert,delete,update,select on transInfo to sysAdminDBUser
exec sp_droplogin @loginame='sysAdmin1' --删除登录名
exec sp_dropuser 'sysAdminDBUser' --删除数据库用户
use bankDB
go
SQL作业——ATM3(全部完成)
最新推荐文章于 2022-10-06 15:10:01 发布