模拟银行sql语句学习
来源:互联网 发布:网络教育好毕业吗 编辑:程序博客网 时间:2024/04/28 19:41
--创建表空间
create tablespace bankspace datafile 'E:\bank\bank.dbf' size 10m autoextend on;
--创建用户bankuser
create user bankuser identified by bankuser default tablespace bankspace;
--
drop table tradeinfo;
drop table userInfo;
drop table cardInfo;
drop table Deposit;
--为用户授权
grant connect,resource to bankuser;
--创建用户信息表
create table userInfo --用户信息表
(
customerID number not null,
customerName varchar2(8),
PID varchar2(18) not null,
telephone varchar2(20) not null,
address varchar(50)
);
--创建银行卡信息表
create table cardinfo(
cardid char(19) NOT NULL,
curid varchar(10)NOT NULL,--币种
savingid number NOT NULL,
openDate date NOT NULL,
openMoney number NOT NULL,
balance number NOT NULL,
pass char(6)NOT NULL,
isreportloss number(1)NOT NULL,--判断卡是否挂失
customerID number NOT NULL
);
select * from userInfo;
--创建交易信息表
create table tradeInfo
(
tradeDate DATE NOT NULL,
tradeType Char(4) NOT NULL,
cardID CHAR(19) NOT NULL,
tradeMoney NUMBER NOT NULL,
remark LONG
);
select * from tradeInfo;
--创建存款类型表
create table deposit (
savingID NUMBER NOT NULL,
savingName varchar(20)NOT NULL,
descrip varchar(50)
);
/*为deposit表添加约束*/
alter table deposit add constraint pa_savingID
primary key(savingid);
/*为userInfo添加约束*/
--主键
alter table userinfo add constraint pk_customerID
primary key(customerID);
--check约束,身份证号长度
alter table userinfo add constraint ck_pid
check(length(pid)=18 or length(pid)=15);
--unique唯一约束,身份证号唯一
alter table userinfo add constraint uq_pid unique(pid);
--check约束,电话号码
alter table userinfo add constraint ck_telephone
check(regexp_like(telephone,'(^\d{3,4}-\d{7,8}$)|(^\d{11}$)'));
--查看创建的约束
select * from user_constraints where table_name='DEPOSIT';
select * from user_constraints where table_name='USERINFO';
/*为cardInfo添加约束*/
--主键
alter table cardinfo add constraint pk_cardid
primary key(cardid);
--check约束,卡号
alter table cardinfo add constraint ck_cardID
check(regexp_like(cardid,'1010 3576 \d{4} \d{4}'));
--修改表中字段
alter table cardInfo modify (curid varchar(10) default 'RMB');
alter table cardInfo modify (opendate varchar(10) default sysdate);
--预存金额大于等于1
alter table cardinfo add constraint ck_openmoney
check(openmoney>=1);
--check 约束 ,预存金额大于等于1
alter table cardinfo add constraint ck_balance
check(balance>=1);
--密码检查约束,密码必须是六位数字
alter table cardinfo add constraint ck_pass
check(regexp_like(pass,'^[0-9]{6}$'));
--密码默认6个8
alter table cardinfo modify (pass char(6) default '888888');
--是否挂失默认值0
alter table cardinfo modify (isreportloss number(1) default 0);
--外键约束
alter table cardinfo add constraint fk_customerid
foreign key(customerid)references userInfo(customerid);
--外键约束
alter table cardinfo add constraint fk_savingid
foreign key(savingid)references deposit(savingid);
/*为tradeinfo 表添加约束*/
--交易类型(存入、支取)
alter table tradeinfo add constraint ck_tradetype
check(tradetype in ('存入','支取'));
--外键
alter table tradeinfo add constraint fk_cardID
foreign key(cardid)references cardInfo(cardId);
--交易金额大于0
alter table tradeinfo add constraint ck_tradeMoney
check(tradeMoney>0);
--交易时间
alter table tradeinfo modify (tradeDate date default sysdate);
/***************************************************************************************************/
/* 插入测试数据 */
/***************************************************************************************************/
/*
==========================
测试数据
==========================
*/
--存款类型
INSERT INTO deposit (savingID,savingName,descrip) VALUES (1,'活期','按存款日结算利息');
INSERT INTO deposit (savingID,savingName,descrip) VALUES (2,'定期一年','存款期是1年');
INSERT INTO deposit (savingID,savingName,descrip) VALUES (3,'定期二年','存款期是2年');
INSERT INTO deposit (savingID,savingName,descrip) VALUES (4,'定期三年','存款期是3年');
INSERT INTO deposit (savingID,savingName) VALUES (5,'定活两便');
INSERT INTO deposit (savingID,savingName) VALUES (6,'通知');
INSERT INTO deposit (savingID,savingName,descrip) VALUES (7,'零存整取一年','存款期是1年');
INSERT INTO deposit (savingID,savingName,descrip) VALUES (8,'零存整取二年','存款期是2年');
INSERT INTO deposit (savingID,savingName,descrip) VALUES (9,'零存整取三年','存款期是3年');
INSERT INTO deposit (savingID,savingName,descrip) VALUES (10,'存本取息五年','按月支取利息');
SELECT * FROM DEPOSIT;
SELECT * FROM userinfo;
SELECT * FROM cardinfo;
SELECT * FROM tradeinfo;
INSERT INTO userInfo(customerID,customerName,PID,telephone,address )
VALUES(1,'张三','123456789012345','010-67898978','北京海淀');
INSERT INTO cardInfo(cardID,savingID,openMoney,balance,customerID)
VALUES('1010 3576 1234 5678',1,1000,1000,1);
INSERT INTO userInfo(customerID,customerName,PID,telephone)
VALUES(2,'李四','321245678912345678','0478-44443333');
INSERT INTO cardInfo(cardID,savingID,openMoney,balance,customerID)
VALUES('1010 3576 1212 1134',2,1,1,2);
INSERT INTO userInfo(customerID,customerName,PID,telephone)
VALUES(3,'王五','567891234532124670','010-44443333');
INSERT INTO cardInfo(cardID,savingID,openMoney,balance,customerID)
VALUES('1010 3576 1212 1130',2,1601,1601,3);
INSERT INTO userInfo(customerID,customerName,PID,telephone)
VALUES(4,'丁六','567891321242345618','0752-43345543');
INSERT INTO cardInfo(cardID,savingID,openMoney,balance,customerID)
VALUES('1010 3576 1212 1004',2,1,1,4);
/*
张三的卡号(1010 3576 1234 5678)取款900元,李四的卡号(1010 3576 1212 1134)存款5000元,要求保存交易记录,以便客户查询和银行业务统计。
说明:当存钱或取钱(如300元)时候,会往交易信息表(tradeInfo)中添加一条交易记录,
同时应更新银行卡信息表(cardInfo)中的现有余额(如增加或减少500元)
*/
/*--------------交易信息表插入交易记录--------------------------*/
INSERT INTO tradeInfo(tradeType,cardID,tradeMoney)
VALUES('支取','1010 3576 1234 5678',900) ;
/*-------------更新银行卡信息表中的现有余额-------------------*/
UPDATE cardInfo SET balance=balance-900 WHERE cardID='1010 3576 1234 5678';
/*--------------交易信息表插入交易记录--------------------------*/
INSERT INTO tradeInfo(tradeType,cardID,tradeMoney)
VALUES('存入','1010 3576 1212 1130',300) ;
/*-------------更新银行卡信息表中的现有余额-------------------*/
UPDATE cardInfo SET balance=balance+300 WHERE cardID='1010 3576 1212 1130';
/*--------------交易信息表插入交易记录--------------------------*/
INSERT INTO tradeInfo(tradeType,cardID,tradeMoney)
VALUES('存入','1010 3576 1212 1004',1000) ;
/*-------------更新银行卡信息表中的现有余额-------------------*/
UPDATE cardInfo SET balance=balance+1000 WHERE cardID='1010 3576 1212 1004';
/*--------------交易信息表插入交易记录--------------------------*/
INSERT INTO tradeInfo(tradeType,cardID,tradeMoney)
VALUES('支取','1010 3576 1212 1130',1900) ;
/*-------------更新银行卡信息表中的现有余额--报错-----------------*/
UPDATE cardInfo SET balance=balance-1900 WHERE cardID='1010 3576 1212 1130';
/*--------------交易信息表插入交易记录--------------------------*/
INSERT INTO tradeInfo(tradeType,cardID,tradeMoney)
VALUES('存入','1010 3576 1212 1134',5000) ;
--INSERT INTO tradeInfo(tradeType,cardID,tradeMoney,Tradedate)
--VALUES('存入','1010 3576 1212 1134',5000,to_date('2014-06-01','yyyy-mm-dd')) ;
/*-------------更新银行卡信息表中的现有余额-------------------*/
UPDATE cardInfo SET balance=balance+5000 WHERE cardID='1010 3576 1212 1134';
commit;
/*--------检查测试数据是否正确---------*/
SELECT * FROM cardInfo;
SELECT * FROM tradeInfo;
SELECT * FROM userInfo;
--删除数据
delete from tradeInfo;
delete from cardInfo;
delete from userInfo;
delete from DEPOSIT;
/*
取本周第一天
select trunc (sysdate,'DAY') from dual;
*/
/*---------修改密码-----*/
--1.张三(卡号为1010 3576 1234 5678)修改银行卡密码为123456
--2.李四(卡号为1010 3576 1212 1134)修改银行卡密码为123123
update cardInfo set pass='123456' WHERE cardID='1010 3576 1234 5678' ;
update cardInfo set pass='123123' WHERE cardID='1010 3576 1212 1134' ;
--查询账户信息
SELECT * FROM cardInfo;
/*---------挂失帐号---------*/
--李四(卡号为1010 3576 1212 1134)因银行卡丢失,申请挂失
update cardInfo set IsReportLoss=1 WHERE cardID='1010 3576 1212 1134' ;
SELECT * FROM cardInfo;
--查看修改密码和挂失结果
SELECT cardid 卡号,curID 货币,savingName 储蓄种类,opendate 开户日期,openmoney 开户金额,balance 余额,pass 密码,
case IsReportLoss WHEN 1 THEN '挂失' WHEN 0 THEN '未挂失' ELSE NULL end 是否挂失,
customerName 客户姓名
FROM CardInfo, Deposit, UserInfo
WHERE CardInfo.savingID=Deposit.savingID and CardInfo.customerID = UserInfo.customerID;
/*--------统计银行的资金流通余额和盈利结算------------------------------*/
--统计说明:存款代表资金流入,取款代表资金.假定存款利率为千分之3,贷款利率为千分之8
/*--单一货币RMB--*/
DECLARE
v_inMoney number;
v_outMoney number;
v_profit number;
begin
--SELECT * FROM tradeInfo
SELECT sum(tradeMoney) into v_inMoney FROM tradeInfo WHERE (tradeType='存入');
SELECT sum(tradeMoney) into v_outMoney FROM tradeInfo WHERE (tradeType='支取');
dbms_output.put_line('银行流通余额总计为:'||to_char(v_inMoney-v_outMoney)||'RMB');
v_profit:=v_outMoney*0.008-v_inMoney*0.003;
dbms_output.put_line('盈利结算为:'||to_char(v_profit)||'RMB');
end;
/*--------查询本周开户的卡号,显示该卡相关信息-----------------*/
SELECT c.cardID 卡号,u.customerName 姓名,c.curID 货币,d.savingName 存款类型,c.openDate 开户日期,c.openMoney 开户金额,c.balance 存款余额,
CASE c.IsReportLoss WHEN 0 THEN '正常账户'
WHEN 1 THEN '挂失账户'
ELSE NULL
END 账户状态
FROM cardInfo c INNER JOIN userInfo u ON (c.customerID = u.customerID)
INNER JOIN Deposit d ON (c.savingID = d.savingID )
WHERE openDate between trunc(sysdate,'DAY') and trunc(sysdate,'DAY')+6
/*---------查询本月交易金额最高的卡号----------------------*/
SELECT * FROM tradeInfo;
SELECT DISTINCT cardID
FROM tradeInfo
WHERE tradeMoney=
(SELECT Max(tradeMoney) FROM tradeInfo
WHERE to_char(tradeDate,'yyyy-mm')=to_char(sysdate,'yyyy-mm'));
/*---------查询挂失帐号的客户信息---------------------*/
SELECT customerName as 客户姓名,telephone as 联系电话 FROM userInfo
WHERE customerID IN (SELECT customerID FROM cardInfo WHERE IsReportLoss=1);
/*------催款提醒:例如某种业务的需要,每个月末,如果发现用户帐上余额少于200元,将致电催款。---*/
SELECT customerName as 客户姓名,telephone as 联系电话,balance as 存款余额
FROM userInfo INNER JOIN cardInfo ON userInfo.customerID=cardInfo.customerID
WHERE balance<200;
/*视图查询*/
--1.创建视图:为了向客户显示信息友好,查询各表要求字段全为中文字段名。
create or replace VIEW vw_userInfo --客户信息表视图
AS
select customerID as 客户编号,customerName as 开户名, PID as 身份证号,
telephone as 电话号码,address as 居住地址 from userInfo;
--使用视图
SELECT * FROM vw_userInfo;
--2.创建视图:查询银行卡信息
create or replace VIEW vw_cardInfo --银行卡信息表视图
AS
select c.cardID as 卡号,u.customerName as 客户,c.curID as 货币种类, d.savingName as 存款类型,c.openDate as 开户日期,
c.balance as 余额,c.pass 密码,
case c.IsReportLoss when 0 then '正常'
when 1 then '挂失'
end as 是否挂失
from cardInfo c, deposit d,userinfo u
where c.savingID=d.savingID and c.customerID=u.customerID;
--使用视图
SELECT * FROM vw_cardInfo;
SELECT 客户,余额 FROM vw_cardInfo where 客户='张三';
--3.创建视图:查看交易信息
create VIEW vw_tradeInfo --交易信息表视图
AS
select tradeDate as 交易日期,tradeType as 交易类型, cardID as 卡号,tradeMoney as 交易金额,
remark as 备注 from tradeInfo ;
--使用视图
SELECT * FROM vw_tradeInfo;
--4.根据客户登录名(采用实名制访问银行系统)查询该客户帐户信息的视图
/*trim去掉前后空格*/
create or replace VIEW vw_oneUserInfo
AS
select customerID as 客户编号,customerName as 开户名, PID as 身份证号,
telephone as 电话号码,address as 居住地址
from userInfo
where UPPER(TRIM(customerName)) in (select UPPER(TRIM(username)) from user_users);
select * from user_users;
--使用视图
select * from vw_oneUserInfo;
/*
存储过程
*/
select * from tradeinfo;
select * from cardinfo;
/*--1.取钱或存钱的存储过程*/
create or replace procedure usp_takeMoney
(v_card char, --卡号
v_m number, --存取金额
v_type char, --存取类型
v_inputPass char default NULL) --密码
as
v1 number(1); --临时变量
v_mybalance number; --余额
begin
dbms_output.put_line('交易正进行,请稍后......');
if (v_type='支取') then
SELECT 1 into v1 FROM cardInfo WHERE cardID=v_card and pass=v_inputPass;
end if;
SELECT balance into v_mybalance
FROM cardInfo
WHERE cardID=v_card;
if (v_type='支取') then
if (v_mybalance>=v_m+1) then
update cardInfo set balance=balance-v_m WHERE cardID=v_Card;
else
dbms_output.put_line('卡号'||v_card||' 余额:'||to_char(v_mybalance));
raise_application_error(-20000,'交易失败!余额不足!');
end if;
else
update cardInfo set balance=balance+v_m WHERE cardID=v_card;
end if;
dbms_output.put_line('交易成功!交易金额:'||to_char(v_m));
SELECT balance into v_mybalance FROM cardInfo WHERE cardID=v_card;
dbms_output.put_line('卡号'||v_card||' 余额:'||to_char(v_mybalance));
INSERT INTO tradeInfo(tradeType,cardID,tradeMoney) VALUES(v_type,v_card,v_m);
commit;
exception
when no_data_found then
raise_application_error(-20001,'卡号或密码错误!');
end;
--调用存储过程取钱或存钱 张三取300,
--现实中的取款机依靠读卡器读出张三的卡号,这里根据张三的名字查出考号来模拟
DECLARE
emp_20000 EXCEPTION;
PRAGMA EXCEPTION_INIT(emp_20000, -20000);
emp_20001 EXCEPTION;
PRAGMA EXCEPTION_INIT(emp_20001, -20001);
v_card char(19);
BEGIN
select cardID into v_card
from cardInfo Inner Join userInfo ON cardInfo.customerID=userInfo.customerID
where customerName='张三';
usp_takeMoney(v_card,300 ,'支取','123456');
EXCEPTION
WHEN emp_20000 THEN
DBMS_OUTPUT.PUT_LINE('交易失败!余额不足!');
rollback;
WHEN emp_20001 THEN
DBMS_OUTPUT.PUT_LINE('密码错误!');
rollback;
WHEN no_data_found THEN
DBMS_OUTPUT.PUT_LINE('用户名不存在!');
rollback;
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('出现了其他异常错误');
rollback;
END;
--调用存储过程,李四存500
DECLARE
emp_20000 EXCEPTION;
PRAGMA EXCEPTION_INIT(emp_20000, -20000);
emp_20001 EXCEPTION;
PRAGMA EXCEPTION_INIT(emp_20001, -20001);
v_card char(19);
BEGIN
select cardID into v_card
from cardInfo Inner Join userInfo ON cardInfo.customerID=userInfo.customerID
where customerName='李四';
usp_takeMoney(v_card,500 ,'存入');
EXCEPTION
WHEN emp_20000 THEN
DBMS_OUTPUT.PUT_LINE('交易失败!余额不足!');
rollback;
WHEN emp_20001 THEN
DBMS_OUTPUT.PUT_LINE('密码错误!');
rollback;
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('出现了其他异常错误');
rollback;
END;
select * from vw_cardInfo;
select * from vw_tradeInfo;
/*--2.产生随机卡号的存储过程(dbms_random包来实现) --*/
create or replace procedure usp_randCardID(v_randCardID OUT char)
AS
v_r number(8);
BEGIN
v_r:=round(dbms_random.value(10000000,99999999));--产生这个范围(10000000,99999999)的随机数
v_randCardID:='1010 3576 '||substr(v_r,1,4)||' '||substr(v_r,5,8);--四位一空格
end;
--测试产生随机卡号
DECLARE
v_mycardID char(19) ;
BEGIN
usp_randCardID(v_mycardID);
dbms_output.put_line('产生的随机卡号为:'||v_mycardID);
END;
/*--3.开户的存储过程--*/
select * from userInfo;
CREATE SEQUENCE seq_customerID
START WITH 10
INCREMENT BY 1
NOMAXVALUE
NOCYCLE
CACHE 30;
create or replace procedure usp_openAccount
( v_customerName char,
v_PID char,
v_telephone char,
v_openMoney number,
v_savingName char,
v_address varchar default '' )
AS
v_mycardID char(19);
v_cur_customerID int;
v_savingID int ;
v1 int;
begin
--调用产生随机卡号的存储过程获得随机卡号
usp_randCardID (v_mycardID);
SELECT count(*) into v1 FROM cardInfo WHERE cardID=v_mycardID;
while (v1<>0) loop
usp_randCardID (v_mycardID);
SELECT count(*) into v1 FROM cardInfo WHERE cardID=v_mycardID;
end loop;
dbms_output.put_line('尊敬的客户,开户成功!系统为您产生的随机卡号为:'||v_mycardID);
dbms_output.put_line('开户日期'||to_char(sysdate,'yyyy-mm-dd')||' 开户金额:'||to_char(v_openMoney));
select count(*) into v1 from userInfo where PID=v_PID;
if v1=0 then
INSERT INTO userInfo(customerID,customerName,PID,telephone,address )
VALUES(seq_customerID.nextval,v_customerName,v_PID,v_telephone,v_address) ;
end if;
SELECT savingID into v_savingID FROM deposit WHERE savingName =v_savingName;
select customerID into v_cur_customerID from userInfo where PID=v_PID;
INSERT INTO cardInfo(cardID,savingID,openMoney,balance,customerID)
VALUES(v_mycardID,v_savingID,v_openMoney,v_openMoney,v_cur_customerID);
exception
when no_data_found then
raise_application_error(-20000,'存款类型不正确,请重新输入!');
when others then
raise_application_error(-20001,'其他错误,请重新输入!');
end;
--调用存储过程重新开户
begin
usp_openAccount ('王老五','334456889012678','2222-63598978',1000,'活期','河南新乡');
commit;
end;
--EXEC usp_openAccount('赵小二','213445678912342222','0760-44446666',1,'定期');
select * from vw_userInfo;
select * from vw_cardInfo;
select * from vw_tradeInfo;
GO
/*--4.输入页数和每页显示的记录数,实现分页显示*/
--DROP PROCEDURE usp_pagingDisplay
SELECT tradeDate 交易日期,tradeType 交易类型,cardID 卡号,trademoney 交易金额
FROM (SELECT t.*,rownum rn FROM (SELECT * FROM tradeInfo ) t)
WHERE rn>=4 and rn<=6;
CREATE OR REPLACE PROCEDURE usp_pagingDisplay
( v_page number:= 1,
v_records number:= 10)
AS
v_rec1 number;
v_rec2 number;
v_statement varchar2(200);
TYPE cursor_type IS REF CURSOR;
--声明一个游标变量
c1 CURSOR_TYPE;
v_trade tradeinfo%rowtype;
begin
v_rec1:= (v_page-1)*v_records+1;
v_rec2:= v_page*v_records;
v_statement:='SELECT tradeDate,tradeType,cardID,trademoney,REMARK ';
--SQL语句拼接
v_statement:=v_statement||'FROM (SELECT t.*,rownum rn FROM (SELECT * FROM tradeInfo ) t) ';
v_statement:=v_statement||'WHERE rn>='||v_rec1||' and rn<='||v_rec2;
--dbms_output.put_line(v_statement);
dbms_output.put_line('交易日期 交易类型 卡号 交易金额 ');
dbms_output.put_line('---------------------------------------------------------');
open c1 for v_statement;
LOOP
FETCH c1 INTO v_trade ;
EXIT WHEN c1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(to_char(v_trade.tradeDate,'yyyy-mm-dd')||' '||v_trade.tradeType||' '||v_trade.cardID||' '||v_trade.trademoney);
END LOOP;
CLOSE c1;
END;
BEGIN
usp_pagingDisplay(2,2);
END;
/*---- 5.打印对账单 ----*/
--drop proc usp_CheckSheet
CREATE OR REPLACE PROCEDURE usp_CheckSheet(
v_cardID varchar2,
v_date1 date:=NULL,
v_date2 date:=NULL)
AS
v_custName varchar2(20);
v_curName varchar2(20);
v_savingName varchar2(20);
v_openDate date;
TYPE cursor_type IS REF CURSOR;
--声明一个游标变量
c1 CURSOR_TYPE;
v_trade tradeinfo%rowtype;
v_sqlStr varchar2(2000);
BEGIN
SELECT c.curID, u.customerName,d.savingName ,c.openDate
INTO v_curName,v_custName,v_savingName, v_openDate
FROM cardInfo c inner join userInfo u on c.customerID=u.customerID
inner join deposit d on c.savingID = d.savingID
WHERE cardID = v_cardID; --and u.customerName = user_name()
dbms_output.put_line('卡号:' || v_cardID);
dbms_output.put_line('姓名:' || v_custName);
dbms_output.put_line('货币:' || v_curName);
dbms_output.put_line('存款类型:' || v_savingName);
dbms_output.put_line('开户日期:' || to_char(v_openDate,'yyyy"年"mm"月"dd"日"'));
dbms_output.put_line(' ');
dbms_output.put_line('--------------------------------------------------------------------');
dbms_output.put_line('交易日 '||' 类型 '||' 交易金额 '||' 备注');
v_sqlStr:='SELECT *
FROM tradeInfo
WHERE cardID='''||v_cardID||'''';
IF v_date2 IS NOT NULL THEN
v_sqlStr:=v_sqlStr||' AND tradeDate <=to_date('''||to_char(v_date2,'yyyy-mm-dd')||' 23:59:59'||''',''yyyy-mm-dd hh24:mi:ss'')';
END IF;
IF v_date1 IS NOT NULL THEN
v_sqlStr:=v_sqlStr||' AND tradeDate >=to_date('''||to_char(v_date1,'yyyy-mm-dd')||' 00:00:00'||''',''yyyy-mm-dd hh24:mi:ss'')';
END IF;
v_sqlStr:=v_sqlStr||' ORDER BY tradeDate';
--dbms_output.put_line(v_sqlStr);
open c1 for v_sqlStr;
LOOP
FETCH c1 INTO v_trade ;
EXIT WHEN c1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(to_char(v_trade.tradeDate,'yyyy-mm-dd')||' '||v_trade.tradeType||' '||v_trade.tradeMoney||' '||v_trade.remark);
END LOOP;
CLOSE c1;
END;
--调用
begin
-- Test statements here
usp_CheckSheet('1010 3576 1212 1130',to_date('2012-12-01','yyyy-mm-dd'),to_date('2013-11-01','yyyy-mm-dd'));
end;
/*--6.查询、统计在指定时间段内没有发生交易的账户信息*/
--drop proc usp_getWithoutTrade
create or replace procedure usp_getWithoutTrade(
v_Num out number ,
v_Amount out number ,
v_date1 date := NULL,
v_date2 date := NULL)
AS
v_sd date;
v_ed date;
TYPE cursor_type IS REF CURSOR;
c1 CURSOR_TYPE;
v_cur userInfo%rowtype;
BEGIN
IF v_date1 IS NULL THEN
v_sd:=trunc(sysdate,'month');
END IF;
IF v_date2 IS NULL THEN
v_ed := sysdate;
END IF;
dbms_output.put_line('客户号 '||' 客户姓名'||' 身份证号'||' 电话'||' 地址');
dbms_output.put_line('---------------------------------------------------------------');
open c1 for SELECT distinct u.customerID,u.customerName,u.PID,u.telephone,address
FROM userInfo u
JOIN cardInfo c ON u.customerID = c.customerID
WHERE c.cardID NOT IN (SELECT cardID FROM tradeInfo WHERE tradeDate Between v_sd and v_ed);
LOOP
FETCH c1 INTO v_cur ;
EXIT WHEN c1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_cur.customerID||' '||v_cur.customerName||' '||v_cur.PID||' '||v_cur.telephone||' '||v_cur.address);
END LOOP;
CLOSE c1;
SELECT COUNT(customerID),SUM(balance) into v_Num,v_Amount
FROM cardInfo
WHERE cardID NOT IN (SELECT cardID FROM tradeInfo WHERE tradeDate Between v_sd and v_ed);
end;
--调用存储过程
DECLARE
v_NUM number;
v_Amount number(18,2);
v_date1 date;
v_date2 date;
begin
v_date1:= to_date('2009-1-1','yyyy-mm-dd');
v_date2:= sysdate;
usp_getWithoutTrade(v_NUM, v_Amount);--, @date1, @date2
dbms_output.put_line('统计未发生交易的客户');
dbms_output.put_line( '---------------------------------------');
dbms_output.put_line( '客户人数:' || v_NUM || ' 客户总余额:' || v_Amount);
end;
/*--7.统计银行卡交易量和交易额*/
--drop proc usp_getTradeInfo
create or replace procedure usp_getTradeInfo(
v_Num1 out number,
v_Amount1 out number,
v_Num2 out number,
v_Amount2 out number,
v_date1 date:=trunc(sysdate,'year'),
v_date2 date:=sysdate,
v_address varchar:= NULL)
AS
BEGIN
IF v_address IS NULL THEN
SELECT COUNT(tradeMoney), SUM(tradeMoney) into v_num1,v_Amount1
FROM tradeInfo
WHERE tradeDate BETWEEN v_date1 AND v_date2 AND tradeType='存入';
SELECT COUNT(tradeMoney), SUM(tradeMoney) into v_num2,v_Amount2
FROM tradeInfo
WHERE tradeDate BETWEEN v_date1 AND v_date2 AND tradeType='支取';
ELSE
SELECT COUNT(tradeMoney), SUM(tradeMoney) into v_num1,v_Amount1
FROM tradeInfo JOIN cardInfo ON tradeInfo.cardID = cardInfo.cardID
JOIN userInfo ON cardInfo.customerID = userInfo.customerID
WHERE tradeDate BETWEEN v_date1 AND v_date2 AND tradeType='存入'
AND address Like '%'||v_address||'%';
SELECT COUNT(tradeMoney), SUM(tradeMoney) into v_num2,v_Amount2
FROM tradeInfo JOIN cardInfo ON tradeInfo.cardID = cardInfo.cardID
JOIN userInfo ON cardInfo.customerID = userInfo.customerID
WHERE tradeDate BETWEEN v_date1 AND v_date2 AND tradeType='支取'
AND address Like '%'||v_address||'%';
END IF;
v_num1:=nvl(v_num1,0);
v_num2:=nvl(v_num2,0);
v_Amount1:=nvl(v_Amount1,0);
v_Amount2:=nvl(v_Amount2,0);
end;
--调用
declare
v_CNT1 number;
v_Total1 number(18,2);
v_CNT2 number;
v_Total2 number(18,2);
v_date1 date;
v_date2 date;
begin
v_date1 := to_date('2009-1-1','yyyy-mm-dd');
v_date2 := sysdate;
usp_getTradeInfo (v_CNT1, v_Total1, v_CNT2, v_Total2, v_date1,v_date2,'北京海淀');--, '北京';
dbms_output.put_line('统计银行卡交易量和交易额');
dbms_output.put_line('');
dbms_output.put_line('起始日期:' || to_char(v_date1,'yyyy-mm-dd') || ' 截止日期:' || to_char(v_date2,'yyyy-mm-dd'));
dbms_output.put_line('-----------------------------------------------------------');
dbms_output.put_line('存入笔数:' || v_CNT1 || ' 存入金额:' ||v_Total1);
dbms_output.put_line( '支取笔数:' || v_CNT2|| ' 支取金额:' ||v_Total2);
dbms_output.put_line('-----------------------------------------------------------');
dbms_output.put_line('发生笔数:' || (v_CNT1+v_CNT2)|| ' 结余金额:' || (v_Total1-v_Total2));
end;
/*复杂的业务逻辑*/
--转帐的事务存储过程
-- drop proc usp_tradefer
create or replace procedure usp_tradefer (
v_card1 varchar2,
v_pwd varchar2,
v_card2 varchar2,
v_outmoney number)
AS
v_date1 date:= sysdate;
v_date2 date:= sysdate;
emp_20000 EXCEPTION;
PRAGMA EXCEPTION_INIT(emp_20000, -20000);
emp_20001 EXCEPTION;
PRAGMA EXCEPTION_INIT(emp_20001, -20001);
BEGIN
commit;
dbms_output.put_line('开始转账,请稍后......');
usp_takeMoney(v_card1,v_outmoney ,'支取',v_pwd);
usp_takeMoney(v_card2,v_outmoney ,'存入');
commit;
dbms_output.put_line('转账成功!');
v_date2 := sysdate;
dbms_output.put_line('打印转出账户对账单');
dbms_output.put_line('-------------------');
usp_CheckSheet(v_card1,v_date1,v_date2);
dbms_output.put_line('打印转入账户对账单');
dbms_output.put_line( '-------------------');
usp_CheckSheet(v_card2,v_date1,v_date2);
EXCEPTION
WHEN emp_20000 THEN
DBMS_OUTPUT.PUT_LINE('交易失败!余额不足!转账失败!');
rollback;
WHEN emp_20001 THEN
DBMS_OUTPUT.PUT_LINE('卡号或密码错误! 转账失败!');
rollback;
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('出现了其他异常错误,转账失败!');
rollback;
END;
--测试上述事务存储过程
--从李四的帐户转帐2000到张三的帐户
--同上一样,现实中的取款机依靠读卡器读出张三/李四的卡号,这里根据张三/李四的名字查出考号来模拟
DECLARE
emp_20000 EXCEPTION;
PRAGMA EXCEPTION_INIT(emp_20000, -20000);
emp_20001 EXCEPTION;
PRAGMA EXCEPTION_INIT(emp_20001, -20001);
v_card1 char(19);
v_card2 char(19);
BEGIN
select cardID into v_card1
from cardInfo Inner Join userInfo ON cardInfo.customerID=userInfo.customerID
where customerName='李四';
select cardID into v_card2
from cardInfo Inner Join userInfo ON cardInfo.customerID=userInfo.customerID
where customerName='张三';
usp_tradefer(v_card1,'123123',v_card2,2000);
EXCEPTION
WHEN emp_20000 THEN
DBMS_OUTPUT.PUT_LINE('交易失败!余额不足!转账失败!');
WHEN emp_20001 THEN
DBMS_OUTPUT.PUT_LINE('密码错误!转账失败!');
WHEN no_data_found THEN
DBMS_OUTPUT.PUT_LINE('用户名不存在!转账失败!');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('出现了其他异常错误!');
END;
select * from vw_userInfo;
select * from vw_cardInfo;
select * from vw_tradeInfo;
0 0
- 模拟银行sql语句学习
- 银行模拟
- 模拟银行
- JDBC学习笔记(五):模拟银行转账
- SQl语句学习专题
- SQL语句学习
- sql语句学习!
- 精妙SQL语句学习
- SQL语句的学习
- SQL语句学习
- sql语句学习
- SQL 语句学习
- 数据库SQL语句学习
- SQL 语句学习(二)
- sql语句学习
- sql语句学习
- sql语句学习
- sql语句学习
- C++类对象成员变量与成员函数内存分配问题
- 单目相机标定原理
- 将String数组转换成int数组
- Hadoop集群上检查磁盘使用量和清理相关日志文件脚本
- 简单sql基础语句
- 模拟银行sql语句学习
- poj 1190 dfs+剪枝(生日蛋糕)
- android:screenOrientation属性
- linux传递文件描述符
- 一个关于多线程同步的小练习。
- 异常的学习
- 游标
- 自绘ListCtrl -- 设置行高
- 前端笔试题笔记:在HTML中实现table表头点击升序/降序排序