SQL作业——ATM3(全部完成)

/*---------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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值