首页 项目实战

数据库系统开发综合实践

第一天

绘制E-R图

相关图-E-R图

绘制模型图

相关图-模型图

第二天

创建表

/* 创建数据表 */

/*  创建用户表
     - 用户编号(PK)
     - 用户姓名
     - 用户类型
     - 用户身份证号
     - 用户联系方式
     - 用户通讯地址
     - 用户备注
 */
create table t_user (
    id number(10) primary key,
    name varchar2(20) not null ,
    user_type varchar2(20) not null ,
    id_number varchar2(18) not null ,
    contact number(11) not null ,
    address varchar2(50),
    remark varchar2(50),
    constraint user_id_number_uk unique (id_number)
);

/*  介质表
     - 介质编号(PK)
     - 账户编号
     - 介质备注
     - 介质启用日期时间
     - 介质停用日期时间
 */
create table t_medium (
    id int not null primary key ,
    account_id int not null ,
    remark varchar2(200),
    start_time date,
    end_time date
);

/*  创建账户表
     - 账户编号(PK)
     - 账户密码
     - 账户货币类型
     - 账户余额
     - 卡状态
     - 用户编号(FK)
     - 账户介质编号
     - 账户开户金额
     - 账户开户日期时间
     - 账户备注
 */
create table t_account (
    id varchar2(19) primary key ,
    password varchar2(6) default '000000',
    money_type varchar2(5) default 'RMB',
    balance number(20) not null ,
    card_state varchar2(10) default '正常',
    user_id number(10) not null ,
    media_id number(4),
    create_money number(20) not null ,
    create_time date not null ,
    remark varchar2(200),
    constraint t_account_t_user_id_fk foreign key (user_id) references t_user(id)
);

/*  创建ATM表
     - ATM编号(PK)
     - ATM类型
     - ATM余额
     - ATM地址
     - ATM运行状态
     - ATM备注
 */
create table t_ATM (
    id number(10) primary key ,
    ATM_type varchar2(10) not null ,
    balance number(20) not null ,
    address varchar2(50) not null ,
    state varchar2(20) default '正常',
    remark varchar2(200)
);

/*  创建交易流水表
     - 交易编号(PK)
     - 账户编号(FK)
     - ATM编号(FK)
     - 转入账户(FK)
     - 转出账户(FK)
     - 交易类型
     - 交易金额
     - 交易币种
     - 交易日期
 */
create table transaction_flow (
    id varchar2(20) primary key ,
    account_id varchar2(19),
    ATM_id number(10),
    in_account_id varchar2(19),
    out_account_id varchar2(19),
    transaction_type varchar2(10) not null ,
    transaction_money number(20) not null ,
    money_type varchar2(5) default 'RMB',
    transaction_time date not null ,
    constraint trans_flow_account_id_fk foreign key (account_id) references t_account(id),
    constraint trans_flow_ATM_id_fk foreign key (ATM_id) references t_ATM(id),
    constraint trans_flow_account_id_in_fk foreign key (in_account_id) references t_account(id),
    constraint trans_flow_account_id_out_fk foreign key (out_account_id) references t_account(id)
);

创建序列

/* 创建序列 */
-- 创建序列-产生用户编号
create sequence seq_user
start with 10000
increment by 1
nomaxvalue
nocycle
nocache;

-- 创建序列-产生ATM编号
create sequence seq_atm
start with 10000
increment by 1
nomaxvalue
nocycle
nocache;

-- 创建序列-产生交易流水编号
create sequence seq_trans
start with 10000
increment by 1
nomaxvalue
nocycle
nocache;

插入数据

/* 插入数据 */
-- 用户表
select * from t_user;
-- 插入数据 (用户编号, 用户姓名, 用户类型, 用户身份证号, 用户联系方式, 用户通讯地址, 用户备注)
insert into t_user values (seq_user.nextval, '张三', '普通用户', '370303199602134688', '13506431288', '山东省济南市', null);
insert into t_user values (seq_user.nextval, '李四', '普通用户', '370303199602134684', '13503431271', '山东省烟台市', null);
insert into t_user values (seq_user.nextval, '王五', '普通用户', '370303199104152345', '13506434529', '山东省青岛市', null);
insert into t_user values (seq_user.nextval, '赵六', '普通用户', '370303199609212647', '13506437734', '山东省淄博市', null);
-- 插入数据后的用户表
select * from t_user;

-- 账户表
select * from t_account;
-- 插入数据 (账户编号, 账户密码, 账户货币类型, 账户余额, 卡状态, 用户编号, 账户介质编号, 账户开户金额, 账户开户日期时间, 账户备注)
insert into t_account values ('6217002270001648485', '123456', 'RMB', '10000', '正常', '10000', null, '10000', sysdate, null);
insert into t_account values ('6217002270001647203', '123456', 'RMB', '50000', '正常', '10001', null, '50000', to_date('2017-10-10', 'yyyy-mm-dd'), null);
insert into t_account values ('6217002270001648486', '123456', 'RMB', '10000', '正常', '10002', null, '10000', to_date('2010-10-10', 'yyyy-mm-dd'), null);
insert into t_account values ('6217002270001648106', '123456', 'RMB', '10000', '冻结', '10003', null, '10000', to_date('2008-01-10', 'yyyy-mm-dd'), null);
-- 插入数据后的账户表
select * from t_account;

-- ATM表
select * from t_ATM;
-- 插入数据 (ATM编号, ATM类型, ATM余额, ATM地址, ATM运行状态, ATM备注)
insert into t_ATM values (seq_atm.nextval, '户外', 500000, '山东省济南市槐荫区', '正常', null);
insert into t_ATM values (seq_atm.nextval, '户外', 700000, '山东省济南市长清区', '正常', null);
insert into t_ATM values (seq_atm.nextval, '户外', 800000, '山东省济南市市中区', '正常', null);
insert into t_ATM values (seq_atm.nextval, '户外', 600000, '山东省济南市莱芜区', '正常', null);
insert into t_ATM values (seq_atm.nextval, '户外', 500000, '山东省烟台市莱山区', '正常', null);
-- 插入数据后的ATM表
select * from t_ATM;

编写事务

1 取款

/** 1. 取款
 取款要求:
    1. 开始取款流程,输入卡号与密码进行身份验证。需注意是否为冻结账号。
    2. 输入取款金额。这里必须是100的整数,且大于0不大于5000。
    3. 验证本卡号本日全虚拟柜员累计取款金额,如超过20000则禁止取款。
    4. 验证取款机内余额是否够取款金额。
    5. 货币种类默认为人民币。
    6. 交易类型默认为取款。
    7. 取赦成功或失败。
    8. 结束取款流程,输出对应相关信息。
  输入参数:
   卡号、密码、取款金额、货币种类、ATM编号
 */
create or replace procedure drawing_money(i_account_id t_account.id%type, v_password t_account.password%type,
                                          i_money t_account.balance%type,
                                          i_money_type t_account.money_type%type default 'RMB',
                                          i_ATM_id t_ATM.id%type)
    is
    v_right_password      t_account.password%type;
    v_card_state          t_account.card_state%type;
    v_drawing_money_today t_account.balance%type;
    v_ATM_balance         t_ATM.balance%type;
    v_account_balance     t_account.balance%type;
begin
    select password into v_right_password from t_account where id = i_account_id;
    if v_password = v_right_password then
        select card_state into v_card_state from t_account where id = i_account_id and money_type = i_money_type;
        if v_card_state <> '冻结' then
            if (i_money mod 100 = 0) and (i_money >= 0) and (i_money <= 5000) then
                select sum(transaction_money)
                into v_drawing_money_today
                from transaction_flow
                where account_id = i_account_id
                  and trunc(transaction_time) = trunc(sysdate)
                  and transaction_type = '取款';
                DBMS_OUTPUT.PUT_LINE('今日取款:' || v_drawing_money_today);
                if (v_drawing_money_today is null or v_drawing_money_today + i_money <= 20000) then
                    select balance into v_ATM_balance from t_ATM where id = i_ATM_id;
                    if v_ATM_balance >= i_money then
                        select balance
                        into v_account_balance
                        from t_account
                        where id = i_account_id
                          and money_type = i_money_type;
                        if v_account_balance >= i_money then
                            update t_account set balance = balance - i_money where id = i_account_id;
                            update t_ATM set balance = balance - i_money where id = i_ATM_id;
                            insert into transaction_flow (id, account_id, ATM_id, transaction_type, transaction_time,
                                                          money_type, transaction_money)
                            values (seq_trans.nextval, i_account_id, i_ATM_id, '取款', sysdate, i_money_type, i_money);
                            commit;
                            DBMS_OUTPUT.PUT_LINE('取款成功!');

                        else
                            DBMS_OUTPUT.PUT_LINE('卡内余额不足!');
                        end if;
                    else
                        DBMS_OUTPUT.PUT_LINE('ATM余额不足!');
                    end if;
                else
                    DBMS_OUTPUT.PUT_LINE('本日取款超过20000,禁止取款!');
                end if;
            else
                DBMS_OUTPUT.PUT_LINE('请输入正确的取款金额!(必须是100的整数,大于0且小于5000)');
            end if;
        else
            DBMS_OUTPUT.PUT_LINE('对不起,本账户已冻结!');
        end if;
    else
        DBMS_OUTPUT.PUT_LINE('对不起,账号或密码错误!');
    end if;
exception
    when no_data_found then
        DBMS_OUTPUT.PUT_LINE('无相应数据信息!');
        rollback;
    when others then
        DBMS_OUTPUT.PUT_LINE('发生错误,操作失败!');
        rollback;
end;

2 存取款结合

/** 2. 存取款结合
  取款要求:
  1. 开始取款流程,输入卡号与密码进行身份验证。需注意是否为冻结账号。
  2. 输入取款金额。这里必须是100的整数,大于0且不大于5000。
  3. 验证本卡号本日全虚拟柜员累计取款金额,如超过20000则禁止取款。
  4. 验证取款机内余额是否够取款金额。
  5. 货币种类默认为人民币。
  6. 交易类型默认为取款。
  7. 取赦成功或失败。
  8. 结束取款流程,输出对应相关信息。
  存款要求:
  1. 开始存款流程,输入卡号与密码进行身份验证。需注意是否为冻结账号。
  2. 输入存款金额。这里必须是100的整数,且不大于10000。
  3. 验证取款机内余额是否还够容纳人民币纸钞的存放。存款金额与ATM机内余额之和不能超过100万。
  4. 货币种类默认为人民币。
  5. 交易类型默认为存款。
  6. 存款成功或失败。
  7. 结束存款流程,输出对应相关信息。

  操作流程:
  1. 输入卡号与密码进行身份验证
  2. 需注意是否为冻结账号
  3. 判断交易类型选择取款或存款
  4. 取款操作
    4.1 判断取款金额为100的整数,大于0且不大于5000
    4.2 判断本卡号本日累计取款金额是否超过20000
    4.3 判断ATM余额是否支持取款
    4.4 判断卡内余额是否支持取款
    4.5 执行取款操作
  5. 存款操作
    5.1 判断取款金额为100的整数,大于0且不大于10000
    5.3 判断ATM余额是否支持存款(存放金额 + ATM金额 <= 1000000)
    5.5 执行取款操作

  输入参数:(自身卡号, 密码, 交易类型, 金额, 货币种类, ATM编号)
 */
create or replace procedure atm_transaction(i_account_id t_account.id%type,
                                            i_password t_account.password%type,
                                            i_transaction_type transaction_flow.transaction_type%type,
                                            i_money t_account.balance%type,
                                            i_money_type t_account.money_type%type default 'RMB',
                                            i_ATM_id t_ATM.id%type)
    is
    v_right_password      t_account.password%type;
    v_card_state          t_account.card_state%type;
    v_drawing_money_today t_account.balance%type;
    v_ATM_balance         t_ATM.balance%type;
    v_account_balance     t_account.balance%type;
begin
    -- 1. 身份验证
    select password into v_right_password from t_account where id = i_account_id;
    if i_password = v_right_password then
        -- 2. 判断卡状态
        select card_state into v_card_state from t_account where id = i_account_id and money_type = i_money_type;
        if v_card_state <> '冻结' then
            -- 3. 判断交易类型
            if i_transaction_type = '取款' then
                -- 4. 取款操作
                -- 4.1 判断取款金额为100的整数,大于0且不大于5000
                if (i_money mod 100 = 0) and (i_money >= 0) and (i_money <= 5000) then
                    -- 4.2 判断本卡号本日累计取款金额是否超过20000
                    select sum(transaction_money)
                    into v_drawing_money_today
                    from transaction_flow
                    where account_id = i_account_id
                      and trunc(transaction_time) = trunc(sysdate)
                      and transaction_type = i_transaction_type;
                    if (v_drawing_money_today is null or v_drawing_money_today + i_money <= 20000) then
                        -- 4.3 判断ATM余额是否支持取款
                        select balance into v_ATM_balance from t_ATM where id = i_ATM_id;
                        if v_ATM_balance >= i_money then
                            -- 4.4 判断卡内余额是否支持取款
                            select balance
                            into v_account_balance
                            from t_account
                            where id = i_account_id
                              and money_type = i_money_type;
                            if v_account_balance >= i_money then
                                -- 4.5 执行取款操作
                                update t_account set balance = balance - i_money where id = i_account_id;
                                update t_ATM set balance = balance - i_money where id = i_ATM_id;
                                insert into transaction_flow (id, account_id, ATM_id, transaction_type,
                                                              transaction_time, money_type, transaction_money)
                                values (seq_trans.nextval, i_account_id, i_ATM_id, i_transaction_type, sysdate,
                                        i_money_type, i_money);
                                commit;
                                DBMS_OUTPUT.PUT_LINE('取款成功!');

                            else
                                DBMS_OUTPUT.PUT_LINE('卡内余额不足!');
                            end if;

                        else
                            DBMS_OUTPUT.PUT_LINE('ATM余额不足!');
                        end if;

                    else
                        DBMS_OUTPUT.PUT_LINE('本日取款超过20000,禁止取款!');
                    end if;

                else
                    DBMS_OUTPUT.PUT_LINE('请输入正确的取款金额!(必须是100的整数,大于0且小于5000)');
                end if;

            else
                if i_transaction_type = '存款' then
                    -- 5. 存款操作
                    -- 5.1 判断取款金额为100的整数,大于0且不大于10000
                    if (i_money mod 100 = 0) and (i_money >= 0) and (i_money <= 10000) then
                        -- 5.3 判断ATM余额是否支持存款(存放金额 + ATM金额 <= 1000000)
                        select balance into v_ATM_balance from t_ATM where id = i_ATM_id;
                        if v_ATM_balance + i_money <= 1000000 then
                            -- 5.5 执行存款操作
                            update t_account set balance = balance + i_money where id = i_account_id;
                            update t_ATM set balance = balance + i_money where id = i_ATM_id;
                            insert into transaction_flow (id, account_id, ATM_id, transaction_type, transaction_time,
                                                          money_type, transaction_money)
                            values (seq_trans.nextval, i_account_id, i_ATM_id, i_transaction_type, sysdate,
                                    i_money_type, i_money);
                            commit;
                            DBMS_OUTPUT.PUT_LINE('存款成功!');

                        else
                            DBMS_OUTPUT.PUT_LINE('对不起,本ATM没有足够的空间存放本数量的纸钞!');
                        end if;

                    else
                        DBMS_OUTPUT.PUT_LINE('请输入正确的存款金额!(必须是100的整数,大于0且小于10000)');
                    end if;

                end if;
            end if;

        else
            DBMS_OUTPUT.PUT_LINE('对不起,本账户已冻结!');
        end if;

    else
        DBMS_OUTPUT.PUT_LINE('对不起,账号或密码错误!');
    end if;

exception
    when no_data_found then
        DBMS_OUTPUT.PUT_LINE('无相应数据信息!');
        rollback;
    when others then
        DBMS_OUTPUT.PUT_LINE('发生错误,操作失败!');
        rollback;
end;

第三天

继续编写事务

3 查询

/** 3. 查询
  查询要求:
  1. 开始查询流程,输入卡号与密码进行身份验证。需注意是否为冻结账号。
  2. 选择查询币种。
  3. 查询成功或失败。
  4. 结束存款流程,输出对应相关信息。

  操作流程:
  1. 输入卡号与密码进行身份验证
  2. 需注意是否为冻结账号
  3. 根据币种,执行查询操作

  输入参数:(卡号, 密码, 货币种类)
 */
create or replace procedure find(i_account_id t_account.id%type, 
                                 i_password t_account.password%type,
                                 i_money_type t_account.money_type%type default 'RMB')
    is
    v_right_password  t_account.password%type;
    v_card_state      t_account.card_state%type;
    v_name            t_user.name%type;
    v_account_balance t_account.balance%type;
begin
    -- 1. 身份验证
    select password into v_right_password from t_account where id = i_account_id;
    if i_password = v_right_password then
        -- 2. 判断卡状态
        select card_state into v_card_state from t_account where id = i_account_id and money_type = i_money_type;
        if v_card_state <> '冻结' then
            -- 3. 根据币种,执行查询操作
            select t_user.name, t_account.balance
            into v_name, v_account_balance
            from t_account,
                 t_user
            where t_account.user_id = t_user.id
              and t_account.id = i_account_id
              and t_account.money_type = i_money_type;

            DBMS_OUTPUT.PUT_LINE('尊敬的客户,您的账户信息为:');
            DBMS_OUTPUT.PUT_LINE('客户名称:' || v_name);
            DBMS_OUTPUT.PUT_LINE('账户编号:' || i_account_id);
            DBMS_OUTPUT.PUT_LINE('货币种类:' || i_money_type);
            DBMS_OUTPUT.PUT_LINE('账户余额:' || v_account_balance);

        else
            DBMS_OUTPUT.PUT_LINE('对不起,本账户已冻结!');
        end if;

    else
        DBMS_OUTPUT.PUT_LINE('对不起,账号或密码错误!');
    end if;

exception
    when no_data_found then
        DBMS_OUTPUT.PUT_LINE('无相应数据信息!');
        rollback;
    when others then
        DBMS_OUTPUT.PUT_LINE('发生错误,操作失败!');
        rollback;
end;

4.1 现金转账

/** 4.1 现金转账
  现金转账要求:
  1. 开始现金转账流程,输入转入卡号进行身份验证。需注意是否为冻结账号。
  2. 输入转账金额。这里必须是100的整数,且不大于10000。
  3. 验证取款机内余额是否还够容纳人民币纸钞的存放。存款金额与ATM机内余额之和不能超过100万。
  4. 货币种类默认为人民币。
  5. 交易类型默认为转账入和转账出。
  6. 现金转账成功或失败。
  7. 结束现金转账流程,输出对应相关信息。

  操作流程:
  1. 输入卡号与密码进行身份验证
  2. 注意自身账户是否为冻结账号
  3. 注意交易账户是否为冻结账号
  4. 判断交易金额为100的整数,大于0且不大于10000
  5. 判断ATM余额是否支持纸钞存放(存放金额 + ATM金额 <= 1000000)
  6. 执行现金转账操作

  输入参数:(自身卡号, 密码, 交易类型, 交易卡号, 金额, 货币种类, ATM编号)
 */
create or replace procedure atm_transfer(i_account_id t_account.id%type,
                                         i_password t_account.password%type,
                                         i_transaction_type transaction_flow.transaction_type%type,
                                         i_transaction_id t_account.id%type,
                                         i_money t_account.balance%type,
                                         i_money_type t_account.money_type%type,
                                         i_ATM_id t_ATM.id%type)
    is
    v_right_password t_account.password%type;
    v_my_card_state  t_account.card_state%type;
    v_to_card_state  t_account.card_state%type;
    v_ATM_balance    t_ATM.balance%type;
begin
    -- 1. 身份验证
    select password into v_right_password from t_account where id = i_account_id;
    if i_password = v_right_password then
        -- 2. 判断自身卡状态
        select card_state into v_my_card_state from t_account where id = i_account_id and money_type = i_money_type;
        if v_my_card_state <> '冻结' then
            -- 3. 判断交易卡状态
            select card_state
            into v_to_card_state
            from t_account
            where id = i_transaction_id
              and money_type = i_money_type;
            if v_to_card_state <> '冻结' then
                -- 4. 判断交易金额为100的整数,大于0且不大于10000
                if (i_money mod 100 = 0) and (i_money >= 0) and (i_money <= 10000) then
                    -- -- 5. 判断ATM余额是否支持纸钞存放(存放金额 + ATM金额 <= 1000000)
                    select balance into v_ATM_balance from t_ATM where id = i_ATM_id;
                    if v_ATM_balance + i_money <= 1000000 then
                        -- -- 6. 执行现金转账操作
                        update t_account set balance = balance + i_money where id = i_transaction_id;
                        update t_ATM set balance = balance + i_money where id = i_ATM_id;
                        insert into transaction_flow (id, account_id, in_account_id, out_account_id, ATM_id,
                                                      transaction_type, transaction_time,
                                                      money_type, transaction_money)
                        values (seq_trans.nextval, i_account_id, i_account_id, i_transaction_id, i_ATM_id,
                                i_transaction_type, sysdate,
                                i_money_type, i_money);
                        commit;
                        DBMS_OUTPUT.PUT_LINE('现金转账成功!');

                    else
                        DBMS_OUTPUT.PUT_LINE('对不起,本ATM没有足够的空间存放本数量的纸钞!');
                    end if;

                else
                    DBMS_OUTPUT.PUT_LINE('请输入正确的存款金额!(必须是100的整数,大于0且小于10000)');
                end if;

            else
                DBMS_OUTPUT.PUT_LINE('对不起,交易账户已冻结!');
            end if;
        else
            DBMS_OUTPUT.PUT_LINE('对不起,本账户已冻结!');
        end if;

    else
        DBMS_OUTPUT.PUT_LINE('对不起,账号或密码错误!');
    end if;

exception
    when no_data_found then
        DBMS_OUTPUT.PUT_LINE('无相应数据信息!');
        rollback;
    when others then
        DBMS_OUTPUT.PUT_LINE('发生错误,操作失败!');
        rollback;
end;

4.2 电子转账

/** 4.2 电子转账
  电子转账要求:
  1. 开始电子转账流程。输入转出卡号与密码进行身份验证。需注意是否为冻结账号。
  2. 验证本卡号本日累计转账金额,如超过20000则禁止转账。
  3. 输入转入卡号进行身份验证。需注意是否为冻结账号。
  4. 输入转账金额。这里必须是100的整数,且不大于10000。
  5. 电子转账成功或失败。
  6. 结束电子转账流程,输出对应相关信息。

  操作流程:
  1. 输入卡号与密码进行身份验证
  2. 注意自身账户是否为冻结账号
  3. 判断本卡号本日累计电子转账金额是否超过20000
  4. 注意交易账户是否为冻结账号
  5. 判断交易金额为100的整数,大于0且不大于10000
  6. 执行电子转账操作

  输入参数:(自身卡号, 密码, 交易类型, 交易卡号, 金额, 货币种类)
 */
create or replace procedure eft(i_account_id t_account.id%type,
                                i_password t_account.password%type,
                                i_transaction_type transaction_flow.transaction_type%type,
                                i_transaction_id t_account.id%type,
                                i_money t_account.balance%type,
                                i_money_type t_account.money_type%type default 'RMB')
    is
    v_right_password  t_account.password%type;
    v_my_card_state   t_account.card_state%type;
    v_to_card_state   t_account.card_state%type;
    v_eft_money_today t_account.balance%type;
begin
    -- 1. 身份验证
    select password into v_right_password from t_account where id = i_account_id;
    if i_password = v_right_password then
        -- 2. 判断自身卡状态
        select card_state into v_my_card_state from t_account where id = i_account_id and money_type = i_money_type;
        if v_my_card_state <> '冻结' then
            -- 3. 判断本卡号本日累计电子转账金额是否超过20000
            select sum(transaction_money)
            into v_eft_money_today
            from transaction_flow
            where account_id = i_account_id
              and trunc(transaction_time) = trunc(sysdate)
              and transaction_type = i_transaction_type;
            if (v_eft_money_today is null or v_eft_money_today + i_money <= 20000) then
                -- 4. 判断交易卡状态
                select card_state
                into v_to_card_state
                from t_account
                where id = i_transaction_id
                  and money_type = i_money_type;
                if v_to_card_state <> '冻结' then
                    -- 5. 判断交易金额为100的整数,大于0且不大于10000
                    if (i_money mod 100 = 0) and (i_money >= 0) and (i_money <= 10000) then
                        -- -- 6. 执行电子转账操作
                        update t_account set balance = balance - i_money where id = i_account_id;
                        update t_account set balance = balance + i_money where id = i_transaction_id;
                        insert into transaction_flow (id, account_id, in_account_id, out_account_id,
                                                      transaction_type, transaction_time,
                                                      money_type, transaction_money)
                        values (seq_trans.nextval, i_account_id, i_account_id, i_transaction_id,
                                i_transaction_type, sysdate,
                                i_money_type, i_money);
                        commit;
                        DBMS_OUTPUT.PUT_LINE('现金转账成功!');

                    else
                        DBMS_OUTPUT.PUT_LINE('请输入正确的存款金额!(必须是100的整数,大于0且小于10000)');
                    end if;

                else
                    DBMS_OUTPUT.PUT_LINE('对不起,交易账户已冻结!');
                end if;
            end if;

        else
            DBMS_OUTPUT.PUT_LINE('对不起,本账户已冻结!');
        end if;

    else
        DBMS_OUTPUT.PUT_LINE('对不起,账号或密码错误!');
    end if;

exception
    when no_data_found then
        DBMS_OUTPUT.PUT_LINE('无相应数据信息!');
        rollback;
    when others then
        DBMS_OUTPUT.PUT_LINE('发生错误,操作失败!');
        rollback;
end;

5 密码修改

/** 5. 密码修改
  密码修改要求:
  1. 开始密码修改流程。输入卡号与密码进行身份验证。需注意是否为冻结账号。
  2. 输入新密码两次,要求两次一致。
  3. 密码修改成功或失败。
  4. 结束密码修改流程,输出对应相关信息。

  操作流程:
  1. 输入卡号与密码进行身份验证
  2. 注意自身账户是否为冻结账号
  3. 判断第一次输入的密码是否与第二次输入的密码相同
  4. 判断密码是否与原密码相同
  5. 执行密码修改操作

  输入参数:(卡号, 第一次输入的密码, 第二次输入的密码)
 */
create or replace procedure password_change(i_account_id t_account.id%type,
                                            i_password t_account.password%type,
                                            i_change_password t_account.password%type,
                                            i_re_change_password t_account.password%type)
is
    v_right_password t_account.password%type;
    v_card_state t_account.card_state%type;
begin

    -- 1. 身份验证
    select password into v_right_password from t_account where id = i_account_id;
    if i_password = v_right_password then
        -- 2. 判断自身卡状态
        select card_state into v_card_state from t_account where id = i_account_id;
        if v_card_state <> '冻结' then
            -- 3. 判断第一次输入的密码是否与第二次输入的密码相同
            if i_change_password = i_re_change_password then
                -- 4. 判断密码是否与原密码相同
                if i_re_change_password != v_right_password then
                    -- 5. 执行密码修改操作操作
                    update t_account set password=i_re_change_password where id=i_account_id;
                    commit;
                    DBMS_OUTPUT.PUT_LINE('密码修改成功!');
                else
                    DBMS_OUTPUT.PUT_LINE('密码与原密码相同!');
                end if;
            else
                DBMS_OUTPUT.PUT_LINE('第一次输入的密码与第二次输入的密码不同!');
            end if;

        else
            DBMS_OUTPUT.PUT_LINE('对不起,本账户已冻结!');
        end if;

    else
        DBMS_OUTPUT.PUT_LINE('对不起,账号或密码错误!');
    end if;

exception
    when no_data_found then
        DBMS_OUTPUT.PUT_LINE('无相应数据信息!');
        rollback;
    when others then
        DBMS_OUTPUT.PUT_LINE('发生错误,操作失败!');
        rollback;
end;

6 密码强制修改

/** 6. 用户密码强行修改
  密码修改要求:
  1. 本流程需先验证用户是否为管理员用户,然后由用户提交身份证号与卡号。
  2. 确定此身份证号与卡号是否在数据库中存有数据。
  3. 如验证成功则直接重置此用户的密码。

  操作流程:
  1. 根据管理员编号与管理员身份证后四位验证管理员身份
  2. 根据身份证号和账户号进行账户验证
  3. 注意账户是否为冻结账号
  4. 判断第一次输入的密码是否与第二次输入的密码相同
  5. 判断密码是否与原密码相同
  6. 执行密码修改操作

  输入参数:(管理员编号, 管理员身份证号后四位(密码), 用户身份证号, 账户号, 第一次输入的密码, 第二次输入的密码)
 */
create or replace procedure password_force_change(i_admin_id t_user.id%type,
                                                  i_admin_password t_user.id_number%type,
                                                  i_user_id_number t_user.id_number%type,
                                                  i_account_id t_account.id%type,
                                                  i_change_password t_account.password%type,
                                                  i_re_change_password t_account.password%type)
is
    v_user_type t_user.user_type%type;
    v_user_right_id_number t_account.id%type;
    v_right_password t_account.password%type;
    v_card_state t_account.card_state%type;
begin

    -- 1. 根据管理员编号与管理员身份证后四位验证管理员身份
    select user_type into v_user_type from t_user where id = i_admin_id and id_number like ('%'||i_admin_password);
    if v_user_type = '管理员' then
        -- 2. 根据身份证号和账户号进行账户验证
        select t_user.id_number into v_user_right_id_number from t_user, t_account where t_user.id = t_account.user_id and t_account.id = i_account_id;
        if v_user_right_id_number = i_user_id_number then
            -- 3. 判断自身卡状态
            select card_state into v_card_state from t_account where id = i_account_id;
            if v_card_state <> '冻结' then
                -- 4. 判断第一次输入的密码是否与第二次输入的密码相同
                if i_change_password = i_re_change_password then
                    -- 5. 判断密码是否与原密码相同
                    select password into v_right_password from t_account where id=i_account_id;
                    if i_re_change_password != v_right_password then
                        -- 6. 执行密码修改操作操作
                        update t_account set password=i_re_change_password where id=i_account_id;
                        commit;
                        DBMS_OUTPUT.PUT_LINE('密码修改成功!');
                    else
                        DBMS_OUTPUT.PUT_LINE('密码与原密码相同!');
                    end if;
                else
                    DBMS_OUTPUT.PUT_LINE('第一次输入的密码与第二次输入的密码不同!');
                end if;

            else
                DBMS_OUTPUT.PUT_LINE('对不起,本账户已冻结!');
            end if;

        else
            DBMS_OUTPUT.PUT_LINE('用户身份证号与账户号不匹配!');
        end if;

    else
        DBMS_OUTPUT.PUT_LINE('用户编号与身份证号不符或非管理员用户!');
    end if;

exception
    when no_data_found then
        DBMS_OUTPUT.PUT_LINE('无相应数据信息!');
        rollback;
    when others then
        DBMS_OUTPUT.PUT_LINE('发生错误,操作失败!');
        rollback;
end;

7 用户信息修改

/** 7. 用户信息修改
  修改要求:
  1. 本流程需先验证用户是否为管理员用户,然后由用户提交身份证号与卡号。
  2. 确定此身份证号与卡号是否在数据库中存有数据。
  3. 如验证成功则直接按照身份证号与卡号修改其他信息类数据。

  操作流程:
  1. 根据管理员编号与管理员身份证后四位验证管理员身份
  2. 根据身份证号和账户号进行账户验证
  3. 注意账户是否为冻结账号
  4. 执行信息修改操作

  输入参数:(管理员编号, 管理员身份证号后四位(密码), 用户身份证号, 账户号, 用户姓名, 用户类型, 联系方式, 联系地址, 备注)
 */
create or replace procedure user_info_change(i_admin_id t_user.id%type,
                                             i_admin_password t_user.id_number%type,
                                             i_user_id_number t_user.id_number%type,
                                             i_account_id t_account.id%type,
                                             i_user_name t_user.name%type,
                                             i_user_type t_user.user_type%type,
                                             i_user_contact t_user.contact%type,
                                             i_user_address t_user.address%type,
                                             i_user_remark t_user.remark%type)
is
    v_user_type t_user.user_type%type;
    v_user_right_id_number t_account.id%type;
    v_card_state t_account.card_state%type;
begin

    -- 1. 根据管理员编号与管理员身份证后四位验证管理员身份
    select user_type into v_user_type from t_user where id = i_admin_id and id_number like ('%'||i_admin_password);
    if v_user_type = '管理员' then
        -- 2. 根据身份证号和账户号进行账户验证
        select t_user.id_number into v_user_right_id_number from t_user, t_account where t_user.id = t_account.user_id and t_account.id = i_account_id;
        if v_user_right_id_number = i_user_id_number then
            -- 3. 判断自身卡状态
            select card_state into v_card_state from t_account where id = i_account_id;
            if v_card_state <> '冻结' then
                -- 4. 更新用户信息
                update t_user set name=i_user_name, user_type=i_user_type, contact=i_user_contact, address=i_user_address, remark=i_user_remark where id_number=i_user_id_number;
                commit;
                DBMS_OUTPUT.PUT_LINE('用户信息修改成功!');

            else
                DBMS_OUTPUT.PUT_LINE('对不起,本账户已冻结!');
            end if;

        else
            DBMS_OUTPUT.PUT_LINE('用户身份证号与账户号不匹配!');
        end if;

    else
        DBMS_OUTPUT.PUT_LINE('用户编号与身份证号不符或非管理员用户!');
    end if;

exception
    when no_data_found then
        DBMS_OUTPUT.PUT_LINE('无相应数据信息!');
        rollback;
    when others then
        DBMS_OUTPUT.PUT_LINE('发生错误,操作失败!');
        rollback;
end;

9 ATM钞票调度

/** 9. ATM钞票调度
  修改要求:
  1. 验证用户编号是否是管理员。
  2. 当余额在atm机钱箱最大值的50%~80%之间,不进行任何操作,
     如atm余额超过钱箱最大80%时,钞票调度,将atm余额更新到钱箱的最大值的60%,
     如atm余额不足钱箱最大的50%时,钞票调度,将atm余额增加到钱箱最大值的60%。

  操作流程:
  1. 根据管理员编号与管理员身份证后四位验证管理员身份
  2. 执行ATM钞票调度操作

  输入参数:(管理员编号, 管理员身份证号后四位(密码))
 */
create or replace procedure ATM_scheduling(i_admin_id t_user.id%type,
                                          i_admin_password t_user.id_number%type)
is
    v_max_balance constant t_ATM.balance%type := 1000000;
    v_user_type t_user.user_type%type;
begin

    -- 1. 根据管理员编号与管理员身份证后四位验证管理员身份
    select user_type into v_user_type from t_user where id = i_admin_id and id_number like ('%'||i_admin_password);
    if v_user_type = '管理员' then
        -- 2. 执行调度操作
        for record in (select * from t_ATM)
        loop
            if (record.balance < v_max_balance * 0.5) or (record.balance > v_max_balance * 0.8) then
                DBMS_OUTPUT.PUT_LINE('编号为' || record.id || '的ATM余额为' || record.balance || ',现已调整为' || v_max_balance*0.6);
                update t_ATM set balance=v_max_balance*0.6 where id=record.id;
            end if;
        end loop;
        commit;
        DBMS_OUTPUT.PUT_LINE('调度成功!');

    else
        DBMS_OUTPUT.PUT_LINE('用户编号与身份证号不符或非管理员用户!');
    end if;

exception
    when no_data_found then
        DBMS_OUTPUT.PUT_LINE('无相应数据信息!');
        rollback;
    when others then
        DBMS_OUTPUT.PUT_LINE('发生错误,操作失败!');
        rollback;
end;

10 用户强制冻结

** 10. 用户账户强制冻结
  修改要求:
  1. 输入用户编号,看是否为系统管理员。
  2. 如是系统管理里员则输入要冻结的卡号。
  3. 直接更新卡号对应卡状态字段。

  操作流程:
  1. 根据管理员编号与管理员身份证后四位验证管理员身份
  2. 执行冻结操作

  输入参数:(管理员编号, 管理员身份证号后四位(密码), 用户身份证号, 账户号)
 */
create or replace procedure account_froze(i_admin_id t_user.id%type,
                                          i_admin_password t_user.id_number%type,
                                          i_account_id t_account.id%type)
is
    v_user_type t_user.user_type%type;
begin

    -- 1. 根据管理员编号与管理员身份证后四位验证管理员身份
    select user_type into v_user_type from t_user where id = i_admin_id and id_number like ('%'||i_admin_password);
    if v_user_type = '管理员' then
        -- 2. 执行冻结操作
        update t_account set card_state='冻结' where id=i_account_id;
        commit;
        DBMS_OUTPUT.PUT_LINE('冻结成功!');
    else
        DBMS_OUTPUT.PUT_LINE('用户编号与身份证号不符或非管理员用户!');
    end if;

exception
    when no_data_found then
        DBMS_OUTPUT.PUT_LINE('无相应数据信息!');
        rollback;
    when others then
        DBMS_OUTPUT.PUT_LINE('发生错误,操作失败!');
        rollback;
end;



文章评论

目录