源码-PL/SQL从入门到精通-第二章-PL/SQL基本概念-Part 2

随书光盘中的源码没有序号,部分找不到或者有bug,调试过程中一并更正。

其中,还有两个彩蛋:“双十九”乘法口诀表和“双九九”加法口诀表的输出(PL/SQL实现),以及一个附加(加薪函数的调用)


代码如下:

--代码2.9 使用嵌套块更新和插入部门表
/*说明:
1.随书源代码中v_deptno前缺少&符号,导致异常处理模块报错“ORA-01400: 无法将 NULL 插入”。
本人调试了半天,才发现问题所在,现已修复。
2.此段代码为手工录入,因为在随书光盘中未找到*/
/*以下为调试过程中使用的sql语句:
create table dept2 as select * from dept;
select * from dept2;
drop table dept2;*/

DECLARE
  v_deptno    NUMBER(2);
  v_deptname  VARCHAR2(14);
BEGIN
  --内部嵌套块
  BEGIN
    SELECT dname
    INTO   v_deptname
    FROM   dept2
    WHERE  deptno = &v_deptno;
    DBMS_OUTPUT.PUT_LINE('您查询的部门名称为:' || v_deptname);
  END;
  --内部嵌套块
  DECLARE
    v_loc VARCHAR2(13) := '上海浦东';
  BEGIN
    UPDATE dept2
    SET    loc = v_loc
    WHERE  deptno = v_deptno;
    DBMS_OUTPUT.PUT_LINE('在内部嵌套块中成功更新部门资料');
    COMMIT;
  END;
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    BEGIN
      INSERT INTO dept2
      VALUES (&v_deptno,'IT开发','全球');
      DBMS_OUTPUT.PUT_LINE('在异常处理嵌套块成功新增部门资料');
      COMMIT;
    EXCEPTION
      WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE(SQLERRM);
    END;
END;

--代码2.10 命名嵌套块(在代码2.9中增加了<<查询与员工名称块>>等三个标签)
DECLARE
  v_deptno    NUMBER(2);
  v_deptname  VARCHAR2(14);
BEGIN
  --内部嵌套块
  <<查询员工名称块>>
  BEGIN
    SELECT dname
    INTO   v_deptname
    FROM   dept2
    WHERE  deptno = &v_deptno;
    DBMS_OUTPUT.PUT_LINE('您查询的部门名称为:' || v_deptname);
  END;
  --内部嵌套块
  <<更新员工记录块>>
  DECLARE
    v_loc VARCHAR2(13) := '上海浦东';
  BEGIN
    UPDATE dept2
    SET    loc = v_loc
    WHERE  deptno = v_deptno;
    DBMS_OUTPUT.PUT_LINE('在内部嵌套块中成功更新部门资料');
    COMMIT;
  END;
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    <<插入员工记录块>>
    BEGIN
      INSERT INTO dept2
      VALUES (&v_deptno,'IT开发','全球');
      DBMS_OUTPUT.PUT_LINE('在异常处理嵌套块成功新增部门资料');
      COMMIT;
    EXCEPTION
      WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE(SQLERRM);
    END;
END;


--代码2.11 PL/SQL变量定义示例
DECLARE
  v_DeptName VARCHAR2(10);        --定义标量变量
  v_LoopCounter BINARY_INTEGER;   --使用PL/SQL类型定义标量变量
  --定义记录类型
  TYPE t_Employee IS RECORD (EmpName VARCHAR2(20),EmpNo NUMBER(7),Job VARCHAR2(20));
  v_Employee t_Employee;          --定义记录类型变量
  TYPE csor IS REF CURSOR;        --定义游标变量
  v_date DATE NOT NULL DEFAULT SYSDATE;--定义变量并指定默认值
BEGIN
 NULL;
END;
/

--代码2.12 使用CASE进行条件判断
CREATE OR REPLACE FUNCTION GetAddSalaryRatioCASE(p_Job VARCHAR2)
RETURN NUMBER AS
  v_Result NUMBER(7,2);
BEGIN  
  CASE p_Job                     --使用CASE WHEN语句进行条件判断
  WHEN 'CLERK' THEN              --职员
    v_Result:=0.10;
  WHEN 'SALESMAN' THEN           --销售
    v_Result:=0.12;
  WHEN 'MANAGER' THEN            --经理
    v_Result:=0.15;
  WHEN 'cont' THEN            --consultant,翻倍
    v_Result:=1;
  END CASE; 
 RETURN v_Result;                --返回值
END;

--代码2.13 使用FOR循环打印九九乘法口诀表
DECLARE
  v_Number1 NUMBER(3);  --外层循环变量
  v_Number2 NUMBER(3);  --内存循环变量
BEGIN  
  FOR v_Number1 IN 1..9 --开始外层循环
  LOOP
    --进行内存循环
    FOR v_Number2 IN 1..v_Number1
    LOOP
      --打印口决内容
      DBMS_OUTPUT.PUT(v_Number1||'*'||v_Number2||'='||v_Number1*v_Number2||'   ');
    END LOOP; 
    --输出换行  
    DBMS_OUTPUT.PUT_LINE('');
  END LOOP;
END;

--彩蛋1 使用FOR循环打印“双十九”乘法口诀表(印度乘法口诀表)
DECLARE
  v_Number1 NUMBER(3);  --外层循环变量
  v_Number2 NUMBER(3);  --内存循环变量
BEGIN  
  FOR v_Number1 IN 1..19 --开始外层循环
  LOOP
    --进行内存循环
    FOR v_Number2 IN 1..v_Number1
    LOOP
      --打印口决内容
      --第十行缩进,使得输出更美观
      DBMS_OUTPUT.PUT  (v_Number1||'*'||v_Number2||'='||v_Number1*v_Number2||'    ');
    END LOOP; 
    --输出换行  
    DBMS_OUTPUT.PUT_LINE('');
  END LOOP;
END;


--彩蛋2 使用FOR循环打印“双九九”加法口诀表
DECLARE
  v_Number1 NUMBER(3);  --外层循环变量
  v_Number2 NUMBER(3);  --内存循环变量
BEGIN  
  FOR v_Number1 IN 1..19 --开始外层循环
  LOOP
    --进行内存循环
    FOR v_Number2 IN 1..v_Number1
    LOOP
      --打印口决内容
      --第十行缩进,使得输出更美观
      DBMS_OUTPUT.PUT  (v_Number1||'+'||v_Number2||'='||(v_Number1+v_Number2)||'    ');
    END LOOP; 
    --输出换行  
    DBMS_OUTPUT.PUT_LINE('');
  END LOOP;
END;

--创建为员工加薪的过程
CREATE OR REPLACE PROCEDURE AddEmpSalary(p_Ratio NUMBER,p_EmpNo NUMBER)
AS
BEGIN
  IF p_Ratio>0 THEN         --判断传入的参数是否大于0
    --如果大于0,则更新Emp表中的数据
    UPDATE scott.emp3 SET sal2=sal2*(1+p_Ratio) WHERE EMPNO=p_EmpNo;
  END IF;
   --提示加薪成功。
  DBMS_OUTPUT.PUT_LINE('加薪成功!');
END;



--附加:调用加薪函数
DECLARE
  v_empno NUMBER(4);
  v_sal2  VARCHAR2(14);
  v_ratio  VARCHAR2(14);
BEGIN
  SELECT sal2
  INTO   v_sal2
  FROM   emp3
  WHERE  empno = &v_empno;
  addempsalary(&v_ratio, &v_empno);
  DBMS_OUTPUT.PUT_LINE('员工'||&v_empno||'已成功加薪百分之'||&v_ratio*100);
  commit;
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    BEGIN
      DBMS_OUTPUT.PUT_LINE('未找到该员工!');
    EXCEPTION
      WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE(SQLERRM);
    END;
END;

update emp3 set sal2=5120000 where empno=7509;

--代码2.15 员工加薪管理保代码
/*包规范定义,不包括实现代码*/
CREATE OR REPLACE PACKAGE EmpSalary 
AS
--执行实际的加薪动作
PROCEDURE AddEmpSalary(p_Ratio NUMBER,p_EmpNo NUMBER);
--使用IF-ELSIF语句得到加薪比率
FUNCTION GetAddSalaryRatio(p_Job VARCHAR2) RETURN NUMBER;
--使用CASE语句得到加薪比率
FUNCTION GetAddSalaryRatioCASE(p_Job VARCHAR2) RETURN NUMBER;
END EmpSalary;
/
/*包体定义*/
CREATE OR REPLACE PACKAGE BODY EmpSalary
AS
   PROCEDURE AddEmpSalary(p_Ratio NUMBER,p_EmpNo NUMBER)
    AS
    BEGIN
      IF p_Ratio>0 THEN         --判断传入的参数是否大于0
        --如果大于0,则更新Emp表中的数据
        UPDATE scott.emp SET sal=sal*(1+p_Ratio) WHERE EMPNO=p_EmpNo;
      END IF;
       --提示加薪成功。
      DBMS_OUTPUT.PUT_LINE('加薪成功!');
    END;
    
    FUNCTION GetAddSalaryRatio(p_Job VARCHAR2)
    RETURN NUMBER AS
      v_Result NUMBER(7,2);
    BEGIN
     IF p_Job='CLERK' THEN                       --如果为职员,加薪10%
       v_Result:=0.10;
     ELSIF p_Job='SALESMAN' THEN                 --如果为销售职员,加薪12%
       v_Result:=0.12;    
     ELSIF p_Job='MANAGER' THEN                  --如果为经理,加薪15%
       v_Result:=0.15;
     END IF;
     RETURN v_Result;   
    END; 
    
    FUNCTION GetAddSalaryRatioCASE(p_Job VARCHAR2)
    RETURN NUMBER AS
      v_Result NUMBER(7,2);
    BEGIN  
      CASE p_Job                     --使用CASE WHEN语句进行条件判断
      WHEN 'CLERK' THEN              --职员
        v_Result:=0.10;
      WHEN 'SALESMAN' THEN           --销售
        v_Result:=0.12;
      WHEN 'MANAGER' THEN            --经理
        v_Result:=0.15;
      END CASE; 
     RETURN v_Result;                --返回值
    END;      
END EmpSalary;


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
谢谢大家的支持,我会陆续上传相关电子书 由于体积较大,本书分两卷压缩,请都下载完再解压! Oracle 11g SQLPL SQL从入门到精通 pdf格式电子书 下载(一) http://download.csdn.net/source/3268267 Oracle 11g SQLPL SQL从入门到精通 pdf格式电子书 下载(二) http://download.csdn.net/source/3268312 内容简介   本书是专门为oracle应用开人员提供的sqlpl/sql编程指南。通过学习本书,读者不仅可以掌握oracle常用工具oracle universal installer、net comfiguration assistant、sql developer、sql*plus的作用及使用方法,而且可以掌握sql语句和pl/sql的各种基础知识和高级特征(记录类型、集合类型、对象类型、大对象类型)。   除了为读者提供编写sql语句和开pl/sql块的方法外,本书还为应用开人员提供了一些常用的pl/sql系统包。通过使用这些pl/sql系统包,应用开人员可以开出功能更强大的数据库应用程序。本书不仅适合sqlpl/sql初学者,也适合于有经验的oracle应用开人员。 前言 第一部分 sqlpl/sql相关工具  第1章 在windows 平台上安装oracle database 11g  第2章 配置网络服务名  第3章 使用sql database  第4章 使用sql*plus 第二部分 sql  第5章 sqlpl/sql综述  第6章 简单查询  第7章 sql单行函数  第8章 操纵数据  第9章 复杂查询  第10章 管理常用对象 第三部分 pl/sql  第11章 pl/sql基础  第12章 访问oracle  第13章 编写控制结构  第14章 使用复合数据类型  第15章 使用游标  第16章 异常处理 . 第17章 本地动态sql  第18章 pl/sql过程  第19章 pl/sql函数  第20章 pl/sql包  第21章 触器  第22章 使用对象类型 第四部分 pl/sql系统包  第23章 使用大对象  第24章 读写os文件  第25章 开多媒体应用  第26章 开web应用  第27章 dbms_sq动态sql  第28章 管理统计  第29章 使用数据库资源管理器  第30章 数据加密和解密  第31章 使用调度程序  第32章 使用flashback  第33章 使用重定义联机表  第34章 修正损坏块  第35章 使用日里民挖掘  第36章 使用管道  第37章 使用精细访问控制  第38章 使用精细审计  第39章 使用预警事件  第40章 转换rowid  第41章 其他常用包 习题答案

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值