Oracle之 第三篇 PL/SQL基础

目录

Oracle之  第三篇  PL/SQL基础

PL/SQL程序块

 PL/SQL语言

PL/SQL的基本结构 

 PL/SQL块分类

   一、PL/SQL语言

二、PL/SQL 常量 、变量   

合法字符

数据类型

LOB  数据类型 

属性类型

  运算符

常量

   PL/SQL常量

1 、变量的声明

       2、属性类型

% type

变量赋值

%type和%rowtype区别

RECORD 复合数据类型

总结

PL/SQL语言篇--结构化程序设计

PL/SQL结构化语句

条件结构

分支结构

多分支结构

带临时变量的多分支结构

 多分支结构CASE(四种—重点)

Select 语句中的case :

分支语句—case 用法3

 分支语句—case 用法4

  循环结构

1.  LOOP-EXIT-WHEN-END循环

2.  WHILE-LOOP-END循环

1、异常概述

异常的捕获与处理:

异常概述:

1 、异常的类型


Oracle之  第三篇  PL/SQL基础


PL/SQL程序块

  • 理解PL/SQL程序块的结构
  • 数据类型 (掌握数据类型%type%rowtype的定义和应用)
  • PL/SQL语言基本的输入和输出和变量的赋值方式(select into 赋值方式).

 PL/SQL语言

         SQL 语言只是访问、操作数据库的语言,并不是一种具有流程控制的程序设计语言,而只有程序设计语言才能用于应用软件的开发。

          PL /SQL 是一种高级数据库程序设计语言, 该语言专门用于在各种环境下对 ORACLE 数据库进行访问。

            由于该语言集成于数据库服务器中,所以PL/SQL 代码可以对数据进行快速高效的处理。除此之外,可以在 ORACLE 数据库的某些客户端工具中,使用 PL/SQL 语言也是该语言的一个特点。

PL/SQL的基本结构 

---示例程序块
---set serveroutput on
Declare example_text   varchar2(100);
beginexample_text:='欢迎来到PL/SQL世界,本例子为程序块示例!';dbms_output.put_line(example_text);
exception
when others thendbms_output.put_line('出现异常了!');end;
  • PL/SQL语言以为单位,块中可以嵌套子块。
  • PL/SQL语言的组成、嵌套和执行
  • 1 一个基本的PL/SQL块由3部分组成:
  • 声明(DECLARE
  • 可执行部分(BEGIN
  • 异常处理部分(EXCEPTION
  • 声明部分
  • 声明部分以关键字DECLARE开始,BEGIN结束。主要用于声明变量、常量、数据类型、游标、异常处理名称以及本地(局部)子程序定义等。
  • 可执行部分
  • 以关键字BEGIN开始,EXCEPTIONEND结束(该部分通过变量赋值、流程控制、数据查询、数据操纵、事务控制、游标处理等实现块的功能。
  • 异常处理部分
  • 异常处理部分以关键字EXCEPTION,该部分用于处理该块执行过程中产生的异常。
  • 注意:

     PL/SQL块中的每一条语句都必须以分号结束,SQL语句可以多行,但分号表示该语句的结束。一行中可以有多条SQL语句,他们之间以分号分隔。

执行部分是必需的,而声明部分和异常部分是可选的 ;可以在一个块的执行部分或异常处理部分嵌套其他的 PL/SQL 块;
每一个PL / SQL块由BEGIN或DECLARE开始,以 END;” 结束。注释由 /* 注释文本  * / 或‘ - - 注释文本’ 形式表示
PL/SQL 不能 在屏幕上显示 SELECT 语句的输出,数据定义语言 (Data Definition language) 不能在执行部分中使用 .

 PL/SQL块分类

  • PL/SQL程序块可以是一个命名的程序块也可以是一个匿名程序块,匿名程序块可以用在服务器端也可以用在客户端
  • 1、匿名块
  • 2命名块
  • 函数(function)
  • 存储过程(procedure)
  • (package)
  • 触发器(trigger)
  • 3.块的执行
  • SQL*PLUS中匿名的PL/SQL块的执行是在PL/SQL块后输入/来执行
  • 命名的程序与匿名程序的执行不同,执行命名的程序块必须使用execute关键字

   一、PL/SQL语言

/*示例程序块2   重要*/DECLAREv_xm varchar2(8):='Jame';v_zym varchar2(10):='计算机';v_zxf number(2):=45;    /*定义变量类型*/BEGINUPDATE XS  SET zxf=v_zxfWHERE xm=v_xm;IF SQL%NOTFOUND THENDBMS_OUTPUT.PUT_LINE('没有该人,需要插入该人');INSERT INTO XS(XH,XM,ZYM,ZXF)          VALUES('007',v_xm,v_zym,v_zxf);END IF;
end;      /*注意区分字段变量和普通变量*/

/*示例程序块3  重要  */DECLARErow_id ROWID;info VARCHAR2(100);
BEGINUPDATE scott.dept SET deptno=90 WHERE DNAME='RESEARCH'RETURNING rowid, dname||':'||to_char(deptno)||':'||locINTO row_id, info;DBMS_OUTPUT.PUT_LINE('ROWID:'||row_id);DBMS_OUTPUT.PUT_LINE(info);
END;
RETURNING 子句用于检索被修改行的信息。 
  • RETURNING 子句用于检索 INSERT 语句中所影响的数据行数,当 INSERT 语句使用 VALUES 子句插入数据时,RETURNING 字句还可将列表达式、ROWID REF 值返回到输出变量中。几点限制:
1 .不能与 DML 语句和远程对象一起使用;
2 .不能检索 LONG 类型信息;
3 .当通过视图向基表中插入数据时,只能与单基表视图一起使用。
/*示例程序块3  重要*/DECLARERow_id ROWID;info VARCHAR2(40);
BEGINdelete from scott.dept where deptno=70RETURNING rowid, dname||':'||to_char(deptno)||':'||locINTO row_id, info;DBMS_OUTPUT.PUT_LINE('ROWID:'||row_id);DBMS_OUTPUT.PUT_LINE(info);
END;
RETURNING 子句用于检索被修改行的信息。 
/*示例程序块3  重要*/DECLARERow_id ROWID;info VARCHAR2(40);
BEGININSERT INTO scott.dept VALUES (12, '财务室', '海口')RETURNING rowid, dname||':'||to_char(deptno)||':'||locINTO row_id, info;DBMS_OUTPUT.PUT_LINE('ROWID:'||row_id);DBMS_OUTPUT.PUT_LINE(info);
END;

二、PL/SQL 常量 、变量   

合法字符

     在使用PL/SQL进行程序设计时,可以使用的有效字符包括以下3类:

  • 所有的大写和小写英文字母;
  • 数字09
  • 符号() + - * / < > = ! ~ ;:. @  % ,  # ^ & _ { } ? [ ]

     PL/SQL标识符必须以字母开头,后面可以跟多个字母、数字、$、下划线和#。最大长度为30个字符,不区分大小写

数据类型

PL/SQL 支持的内置数据类型:

LOB  数据类型 
  • 用于存储大文本、图像、视频剪辑和声音剪辑等非结构化数据。
  • LOB 数据类型可存储最大 4GB的数据。
  • LOB 类型包括:
  • BLOB   将大型二进制对象存储在数据库中
  • CLOB   将大型字符数据存储在数据库中
  • BFILE     将大型二进制对象存储在操作系统文件中
属性类型
  • 用于引用数据库列的数据类型,以及表示表中一行的记录类型
  • 属性类型有两种:
  • %TYPE  -  引用变量和数据库列的数据类型
  • %ROWTYPE  -  提供表示表中一行的记录类型
  • 使用属性类型的优点:
  • 不需要知道被引用的表列的具体类型。
  • 如果被引用对象的数据类型发生改变,PL/SQL 变量的数据类型也随之改变。
  运算符

Oracle提供了三类运算符:算术运算符、关系运算符和逻辑运算符。

1.  算术运算符

算术运算符执行算术运算。算术运算符有:

+(加)、-(减)、*(乘)、/(除)

连接运算符:(连接)

其中﹢()﹣()运算符也可用于对DATE(日期)数据类型的值进行运算。

 

PL/SQL为支持编程,还使用其他一些符号。表5.4列出了部分符号,它们是最常用的,也是使用PL/SQL的所有用户都必须了解的。

 5.4 部分其他常用符号

常量
  • 声明常量时需要使用constant关键字,并且必须在声明时就为该常量赋值,在程序其它部分不能改变该常量的值。
  • 常量名称 constant  常量类型:=;
   PL/SQL常量
DECLAREv1 constant  varchar2(4):='示例';v2 constant varchar2(10):='常量';
BEGINDBMS_OUTPUT.PUT_LINE(v2||' '||v1);
END;PL/SQL程序块的赋值符号是   :=

  变量

1.  变量的声明

     数据在数据库与PL/SQL程序之间是通过变量进行传递的。变量通常是在PL/SQL块的声明部分定义的。

     变量名必须是一个合法的标识符,变量命名规则如下:

(1)变量必须以字母(AZ)开头

(2)其后跟可选的一个或多个字母、数字(09)或特殊字符$# 或_

(3)变量长度不超过30个字符

(4)变量名中不能有空格

 5.5是否合法的变量名

1 、变量的声明

     在使用变量前,首先要声明变量。变量定义的基本格式为:

    <变量名><数据类型>[(宽度):=<初始值>]

例如:定义一个长度为10byte的变量count,其初始值为1,是varchar2类型。

  count varchar2(10) :=‘1’;

       2、属性类型
  • 用于引用数据库列的数据类型,以及表示表中一行的记录类型
  • 属性类型有两种:
  • %TYPE  -  引用变量和数据库列的数据类型
  • %ROWTYPE  -  提供表示表中一行的记录类型
  • 使用属性类型的优点:
  • 不需要知道被引用的表列的具体类型。
  • 如果被引用对象的数据类型发生改变,PL/SQL 变量的数据类型也随之改变。
% type
  • 声明一个变量,使它的类型与某个变量或数据库基本表中某个列的数据类型一致,可以使用%TYPE复合数据类型。
  • 语法:
  • 变量名  表名.列名%type;
  • 示例

declare

v_empno  emp.empno%TYPE;

使用%TYPE声明具有以下两个优点:

①  不必知道XH列的确切的数据类型;

②  如果改变了XH列的数据库定义,my_xh的数据类型在运行时会自动进行修改。 

 pl/sql程序,显示输出scott.emp表中的部分数据

declareemp_number  constant number(4):=7876;emp_name  varchar2(10);emp_job  varchar2(9);emp_sal  number(7,2);
beginselect ename,job,salinto emp_name,emp_job,emp_salfrom scott.emp where empno=emp_number;dbms_output.put_line('查询的员工号为'||emp_number);dbms_output.put_line('该员工的姓名为'||emp_name);dbms_output.put_line('该员工的职位为'||emp_job);dbms_output.put_line('该员工的工资为'||emp_sal);
end;

declareemp_number  constant number(4):=7900;emp_name  scott.emp.ename%type;emp_job  scott.emp.job%type;emp_sal  scott.emp.sal%type;
beginselect ename,job,salinto emp_name,emp_job,emp_salfrom scott.emp where empno=emp_number;dbms_output.put_line('查询的员工号为'||emp_number);dbms_output.put_line('该员工的姓名为'||emp_name);dbms_output.put_line('该员工的职位为'||emp_job);dbms_output.put_line('该员工的工资为'||emp_sal);
end;

%TYPE使用举例

declare

  emp_name  scott.emp.ename%type;

  emp_job  scott.emp.job%type;

  emp_sal  scott.emp.sal%type;

注意:

不同schema对象的描述

     Scott.emp

     System.xs

如果细化到列则为

    Scott.emp.empno

    System.xs.xh

变量赋值

       SELECT  INTO 赋数用法

       SELECT...INTO 语句可以给多个值同时赋值且两边的数量和类型必须相等。

       必须有where 子句,使得select 语句从数据库表中选出的记录有且仅有一条。

    select * from 表名 可能有三种情况

  • 无值  (产生异常)
  • 多值  (游标)
  • 唯一值

 %TYPE使用举例

declareemp_number  constant number(4):=7900;emp_name  scott.emp.ename%type;emp_job  scott.emp.job%type;emp_sal  scott.emp.sal%type;
beginselect ename,job,salinto emp_name,emp_job,emp_salfrom scott.emp where empno=emp_number;dbms_output.put_line('查询的员工号为'||emp_number);dbms_output.put_line('该员工的姓名为'||emp_name);dbms_output.put_line('该员工的职位为'||emp_job);dbms_output.put_line('该员工的工资为'||emp_sal);
end;

变量的常用赋值方式

:=

  • SELECT INTO 变量集   (注意必须有where 子句,使得选出的记录有且仅有一条)
  •  FETCH INTO    变量集

赋值语句练习一

要求:使用PL/SQL语言,统计xs表中同学的个数并显示出来。

declarev_1  number;
begin  select count(*) into v_1 from xs;dbms_output.put_line(v_1);
exceptionwhen others then dbms_output.put_line('出现异常了');
end;

 PL/SQL中常用的基本数据类型

常用数据类型

  • %用于表示属性提示符
  • 复合数据类型
  • --1 .使用 %type 定义变量
  • --2. %rowtype获得整个记录的数据类型。

%ROWTYPE复合数据类型:

declare
one_emp  scott.emp%rowtype;beginselect  *into one_empfrom scott.emp where empno=7900;dbms_output.put_line('该员工的职位为'||one_emp.job);dbms_output.put_line('该员工的工资为'||one_emp.sal);
end;

注意:如何通过点记法取%rowtype类型的值
 

declareemp_number  constant scott.emp.empno%type:=7900;one_emp  scott.emp%rowtype;beginselect *into one_empfrom scott.emp where empno=emp_number;dbms_output.put_line('查询的员工号为'||emp_number);dbms_output.put_line('该员工的姓名为'||one_emp.ename);dbms_output.put_line('该员工的职位为'||one_emp.job);dbms_output.put_line('该员工的工资为'||one_emp.sal);
end;
%type%rowtype区别
  • 使用%type可以使变量获得字段的数据类型,使用%rowtype可以使变量获得整个记录的数据类型。

--比较两者定义的不同:

  • 变量名 数据表.列名%type
  • 变量名 数据表%rowtype

%rowtype%type类型使用举例:

DECLAREv_emp emp%ROWTYPE;v_ename emp.ename%type;v_sal   emp.sal%type;
BEGIN
SELECT * INTO v_emp FROM emp WHERE ename='SMITH';DBMS_OUTPUT.PUT_LINE(v_emp.empno||' '||v_emp.sal);select ename,sal INTO v_ename,v_sal FROM emp WHERE empno=7900;DBMS_OUTPUT.PUT_LINE(v_ename||' '||v_sal);
END; 

%rowtype%type类型使用举例

要求:使用PL/SQL语言,中的%type%rowtype 定义xs表中的变量,显示007同学的信息。

DECLAREv_student_name xs.name%TYPE;v_student_age xs.age%TYPE;v_student_gender xs.gender%TYPE;v_student_row xs%ROWTYPE;
BEGIN-- 使用%type定义变量SELECT name, age, gender INTO v_student_name, v_student_age, v_student_genderFROM xsWHERE student_id = '007';-- 使用%rowtype定义变量SELECT *INTO v_student_rowFROM xsWHERE student_id = '007';-- 显示变量值DBMS_OUTPUT.PUT_LINE('Using %type:');DBMS_OUTPUT.PUT_LINE('Name: ' || v_student_name);DBMS_OUTPUT.PUT_LINE('Age: ' || v_student_age);DBMS_OUTPUT.PUT_LINE('Gender: ' || v_student_gender);DBMS_OUTPUT.PUT_LINE('Using %rowtype:');DBMS_OUTPUT.PUT_LINE('Name: ' || v_student_row.name);DBMS_OUTPUT.PUT_LINE('Age: ' || v_student_row.age);DBMS_OUTPUT.PUT_LINE('Gender: ' || v_student_row.gender);
END;
/

        在上述示例中,定义了三个变量v_student_name、v_student_age和v_student_gender,它们分别与表"xs"中的"name"、"age"和"gender"列具有相同的数据类型。使用%type关键字,可以避免硬编码数据类型,使代码更加灵活和可维护。

        另外,使用%rowtype定义了一个变量v_student_row,它与表"xs"的行结构具有相同的字段和数据类型。通过将整行数据直接赋值给该变量,可以方便地访问表中所有列的值。

        最后,使用DBMS_OUTPUT.PUT_LINE函数将变量的值输出到控制台显示。运行该示例,即可显示"xs"表中"007"同学的信息。

RECORD 复合数据类型
DECLARE--定义与 hr.employees 表中的这几个列相同的记录数据类型TYPE RECORD_TYPE_EMPLOYEES IS RECORD(f_name hr.employees.first_name%TYPE,h_date hr.employees.hire_date%TYPE,j_id hr.employees.job_id%TYPE);--声明一个该记录数据类型的记录变量v_emp_record RECORD_TYPE_EMPLOYEES;
BEGINSELECT first_name, hire_date, job_id INTO v_emp_recordFROM hr.employees WHERE employee_id = &emp_id;DBMS_OUTPUT.PUT_LINE('雇员名称:'||v_emp_record.f_name||' 雇佣日期:'||v_emp_record.h_date||' 岗位:'||v_emp_record.j_id);
END;
一个记录类型的变量只能保存从数据库中查询出的一行记录,若查询出了多行记录,就会出
现错误。

本节要点:

  • 理解PL/SQL程序块的结构
  • 数据类型 (掌握数据类型%type%rowtype的定义和应用)
  • PL/SQL语言基本的输入和输出和变量的赋值方式。

总结

  • 5.1 PL/SQL语言基本结构(PL/SQL块的组成)
  • 5.2 PL/SQL字符集
  • 5.3 变量、常量和数据类型

PL/SQL语言篇--结构化程序设计

PL/SQL结构化语句

  • IF 语句根据条件执行一系列语句,有三种形式:IF-THENIF-THEN-ELSE IF-THEN-ELSIF
条件结构

1.  IF逻辑结构

     (1)  IF-THEN-ENDIF结构

     (2)  IF-THEN-ELSE-ENDIF结构

     (3)  IF-THEN-ELSIF结构

     (4)  CASE结构

1.  IF逻辑结构

(3)  IF-THEN-ELSIF-THEN-ELSE

语法格式:

     IF 条件 1 THEN       

  Run_expression1             

  ELSIF条件  2 THEN  

  Run_expression2              

  ELSE

  Run_expression3              

  END IF

分支结构

1、要求:向学生表中添加 记录,值为’007’ ‘Jame’ ‘计算机’ 45,并说明是否成功

DECLAREv_xm varchar2(8):='Jame';v_zym varchar2(10):='计算机';v_zxf number(2):=45;    /*定义变量类型*/BEGININSERT INTO XS(XH,XM,ZYM,ZXF)        VALUES('007',v_xm,v_zym,v_zxf);IF SQL%FOUND THENDBMS_OUTPUT.PUT_LINE('操作成功');
ELSEDBMS_OUTPUT.PUT_LINE('没有插入该人');END IF;
END; 

    要求:针对scott.emp表,计算7788号雇员的应交税金情况,薪金>=3000,应缴税金为薪金的0.08,薪金在15003000之间,应缴薪金的0.06,其它应缴0.04.

declare v_sal  scott.emp.sal%type;v_tax   scott.emp.sal%type;
beginselect sal into v_sal  from  scott.emp  where empno=7788;if  v_sal>=3000  thenv_tax:=v_sal*0.08;elsif  v_sal>=1500  then  v_tax:=v_sal*0.06;elsev_tax:=v_sal*0.04;end if;  DBMS_OUTPUT.PUT_LINE('应缴税金:'||v_tax);end; 

多分支结构

3 要求:涉及表为scott.emp,输入一个员工号,修改该员工的工资,如果该员工为10号部门(deptno),则要求工资增加100;若为20号部门,要求工资增加150;若为30号部门,工资增加200;否则增加300

分析:
首先搭好程序块的框架( declare    begin   exception  end;
输入一个员工号 ------ 使用临时变量
找出根据那个变量值的不同来做分支结构: 部门号 v_deptno
Select into 语句求此变量,部门号 v_deptno
分支结构求工资增加量
Update 语句修改工资
DECLAREv_deptno scott.emp.deptno%type;v_zj NUMBER(4); v_empno  scott.emp.empno%type;
BEGINv_empno:='7788';SELECT deptno INTO v_deptno FROM scott.emp WHERE empno=v_empno;IF        v_deptno=10          THEN v_zj:=100;ELSIF v_deptno=20          THEN v_zj:=150;ELSIF v_deptno=30          THEN v_zj:=200;ELSE    v_zj:=300;END IF; UPDATE scott.emp SET sal=sal+v_zj  WHERE empno='7788';
END;

带临时变量的多分支结构
declare v_deptno  scott.emp.deptno%type;v_zl  scott.emp.sal%type;
beginselect deptno into v_deptno  from  scott.emp  where empno=&&a;if v_deptno=10 thenv_zl:=100;elsif   v_deptno=20 thenv_zl:=150;elsif   v_deptno=30 thenv_zl:=200;elsev_zl:=300;end if; UPDATE scott.emp SET sal=sal+v_zl  WHERE empno=&a;end;

多分支结构

  • 临时变量&&a  &a
 多分支结构CASE四种重点)

四种CASE语句

1. 简单型 CASE
2. 搜索型 CASE
3. 嵌入到 SELECT 语句执行复杂任务的 CASE
4. 嵌入到 PL/SQL 程序语句(如赋值语句)的 CASE

1、搜索型CASE语句

语法格式:

  CASE   变量名

       WHEN  变量值   THEN     处理语句 1

       WHEN 变量值   THEN     处理语句2

      ELSE      处理语句n+1 

  END CASE;

5.4 PL/SQL基本程序结构

: 关于成绩等级制和百分制的相互转换。

---例: 关于成绩等级制和百分制的相互转换。
---简单case表达式
declare grade  varchar2(4):='良好';
begincase gradewhen '优秀' then dbms_output.put_line('大于等于90');when '良好' then dbms_output.put_line('大于等于80,小于90');when '及格' then dbms_output.put_line('大于等于60,小于80');else dbms_output.put_line('不及格');end case;
end;    

等值比较的CASE语句:

DECLAREv_deptno emp.deptno%type;v_increment NUMBER(4);v_empno  emp.empno%type;
BEGINv_empno:=&x;SELECT deptno INTO v_deptno FROM emp WHERE empno=v_empno;CASE v_deptno  WHEN 10 THEN v_increment:=100;WHEN 20 THEN v_increment:=150;WHEN 30 THEN v_increment:=200;ELSE  v_increment:=300;
END CASE;
UPDATE emp SET sal=sal+v_increment WHERE empno=v_empno; 
END; 
  • 完善程序
  • Update语句之后追加如下语句:
  • if SQL%FOUND then
  •  dbms_output.put_line('更改成功');
  • select sal into v_sal from scott.emp where empno='7788';
  •  dbms_output.put_line(v_sal);
  • end  if;

1.  搜索型CASE语句

语法格式:

  CASE  

       WHEN   关系表达式THEN     处理语句 1

       WHEN   关系表达式THEN     处理语句2

      ELSE      处理语句n+1 

  END CASE;

比较与简单型case的区别

5.4 PL/SQL基本程序结构和语句

: 关于成绩等级制和百分制的相互转换。

---例: 关于成绩等级制和百分制的相互转换。
---搜索case表达式
declare score  int:=91;
begincase when score>=90 then dbms_output.put_line('优秀');when score>=80 then dbms_output.put_line('良好');when score>=60 then dbms_output.put_line('及格');else dbms_output.put_line('不及格');end case;
end; 	

3、嵌入到SELECT语句执行复杂任务的CASE

    if 语句不同,case 语句可以用在select语句中,用于在检索数据的同时对数据进行判断并返回判断结果。

    如下图通过case语句显示每一位同学的获得学分情况。

嵌入到SELECT语句执行复杂任务的CASE

  预备知识(注意列表中别名的用法)

select  xh,xm,zxf   from xs ;
select  xh,xm,zxf   as 总学分  from xs ;
select  xh,xm,zxf  总学分 from xs ;

----构建需求列

select  xh,xm,zxf ,' 获得学分情况 ' from xs ;

----- ,‘获得学分情况列需要分情况处理(case

  • select  xh,xm,zxf, (case 分支语句)  as '获得学分情况’  from xs;

Select 语句中的case :

实现:

  • select  xh,xm,zxf,
(case
   when zxf >50 then ' gao '
     when zxf >=40 then ' zhong '
        else ' 学分不够,需继续 '
end) as
获得学分情况  from xs ;

注意:

    1.  整个case 语句没有标点符号

     2.  case 语句的结束用end 而非end case

     3.  then 之后没有dbms_output.put_line().

     4.  as 之后无引号.

思考:如何把上例的结果保存起来(以表的形式)        

  • create table t01 as select xh,xm,zym,
    (casewhen zxf>50 then 'gao'when zxf>=40 then 'zhong'else '学分不够,需继续'
    end) as
    获得学分情况  from xs;
    
Select 语句中的case :
  • 对于学生借阅图书项目,检验图书是否过期:
  • 要求具体说明:
  • 过期
  • 没过期
  • 或者有借阅图书     三种具体情况
  • 可以用带日期型的表替代借阅日期列(scott.emp
    SQL> select Months_Between(sysdate,to_date('20151001','yyyymmdd')) from dual;MONTHS_BETWEEN(SYSDATE,TO_DATE
    ------------------------------1.04413045101553SQL> select trunc(sysdate-to_date('20181001','yyyymmdd')) 天数 from dual;

分支语句—case 用法3

检验图书是否过期:

select empno,ename,job,hiredate,

(case

    when trunc(sysdate-HIREDATE)>360  then '过期'

    when hiredate is null then '没借书'

     else  '没过期'

    end)

   as 是否过期 from scott.emp;

思考:如何在显示是否过期的同时,显示根据过期天数确立的罚款数。

 分支语句—case 用法4
  • 嵌入到PL/SQL程序语句(如赋值语句)的CASE

FOR循环

LOOP-EXIT-END LOOP循环

WHILE循环

  循环结构
1.  LOOP-EXIT-WHEN-END循环

  LOOP

  Run_expression                 

  EXIT WHEN Boolean_expression     

END LOOP;

5.10】10的阶乘。

---【例5.10】求10的阶乘。DECLARE s NUMBER:=1;n  NUMBER:=2;BEGINLOOPs:=s*n;n:=n+1;exit when n>10;END LOOP;dbms_output.put_line(to_char(s));END;
2.  WHILE-LOOP-END循环

语法格式:

     WHILE Boolean_expression

  LOOP

  Run_expression               

  END LOOP;

5.11】WHILE-LOOP-END循环结构求10的阶乘。

---【例5.11】用WHILE-LOOP-END循环结构求10的阶乘。
DECLARE s NUMBER:=1;n NUMBER:=2;BEGINwhile n<=10LOOPs:=s*n;n:=n+1;end LOOP;dbms_output.put_line(to_char(s));END;

结构化设计之循环结构

4.  FOR-IN-LOOP-END循环

语法格式:

  FOR count IN count_1..count_n     /*定义跟踪循环的变量*/

  LOOP

     /*执行循环体*/

  END LOOP;

5.12】FOR-IN-LOOP-END循环结构求10的阶乘。

---【例5.12】用FOR-IN-LOOP-END循环结构求10的阶乘。
DECLARE s NUMBER:=1;n NUMBER:=2;BEGINfor n in 2..10Loops:=s*n;end loop;dbms_output.put_line(to_char(s));END;

For 循环中的逆序:

DECLARE s NUMBER:=1;n NUMBER:=2;beginfor n in reverse 1..10loops:=s*n;end loop;dbms_output.put_line(to_char(s));END;

水仙花数

--- 水仙花数
declarei int;a int;b int;c int;
begin  for i in 100..999loopa:= trunc(i/100);b:=trunc(i/10) mod 10;c:=i mod 10;-- dbms_output.put_line(a||' '||b||' '||c);if (i=a*a*a+b*b*b+c*c*c) thendbms_output.put_line(i);end if;end loop;   
end;

TRUNC(x,y)
功能: 计算截尾到y位小数的x. y缺省为0,结果变为一个整数值.

习题:

  • 习题:针对xs_kc,表如何通过select语句显示学生信息时,显示每个学生的成绩所属的级别?示例查询结果如下

1、异常概述

  • Oracle错误处理机制
  • 一个优秀的程序都应该能够正确处理各种出错情况,并尽可能从错误中恢复。任何 ORACLE 错误(ORA-xxxxx 形式的 Oracle 错误号)
ORACLE 提供异常情况 (EXCEPTION) 和异常处理 (EXCEPTION HANDLER) 来实现错
误处理 。

当异常产生时抛出相应的异常,并被异常处理器捕获,程序控制权传递给异常处理器,由异常处理器来处理运行时错误。

异常的捕获与处理:
  • 异常处理器的基本形式为
  • EXCEPTION
  •  WHEN 异常OR  异常2      THEN   语句1;
  • WHEN 异常3                        THEN   语句2;

      ……

WHEN  OTHERS  THEN  语句 n ;
END;

  • 注意:
  • 一个异常处理器可以捕获多个异常,只需要在WHEN子句中用OR连接即可;
  • 当数据库或PL/SQL在运行时发生错误时,一个异常被PL/SQL自动抛出。
  • 一个异常只能被一个异常处理器捕获,并进行处理。
异常概述:
1 、异常的类型
  • 预定义的Oracle异常
  • 用户定义的异常

异常处理部分 : 

下面是一个异常处理的例子:

SET SERVEROUTPUT ON;
DECLAREx NUMBER;
BEGINx:= 'aa123';
EXCEPTIONWHEN VALUE_ERROR THENDBMS_OUTPUT.PUT_LINE('数据类型错误');
END;

预定义的异常 p213

 与数据库有关的一段异常:查找“李明”同学的学号 :


---与数据库有关的一段异常:查找“李明”同学的学号 ★
DECLAREv_result xs.xm%TYPE;BEGINSELECT xh INTO v_resultFROM xs WHERE xm='李明';DBMS_OUTPUT.PUT_LINE('The student number is '||v_result);EXCEPTIONWHEN TOO_MANY_ROWS THENDBMS_OUTPUT.PUT_LINE('There has TOO_MANY_ROWS error');WHEN NO_DATA_FOUND THENDBMS_OUTPUT.PUT_LINE('There has NO_DATA_FOUND error');WHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('错误情况不明');END;

查询名为SMITH的员工工资,如果该员工不存在,则输出“There is not such an employee!”;如果存在多个同名的员工,则输出'There has too_many_rows error!”

declare v_sal scott.emp.sal%type;
beginselect sal into v_sal from scott.emp where ename='SMITH';DBMS_OUTPUT.PUT_LINE(v_sal);EXCEPTIONWHEN NO_DATA_FOUND THENDBMS_OUTPUT.PUT_LINE(‘没有返回数据');WHEN TOO_MANY_ROWS THENDBMS_OUTPUT.PUT_LINE(‘返回多行匹配数据');end;
  • 注意:使用others异常可以借助两个函数来说明捕捉到的异常的类型-----SQLCODESQLERRM
DECLAREv_result number;BEGINSELECT xm INTO v_resultFROM xs WHERE xh='010010';DBMS_OUTPUT.PUT_LINE('The student name is'||v_result);EXCEPTIONWHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('the sqlcode is'||SQLCODE);DBMS_OUTPUT.PUT_LINE('the sqlERRM is'||SQLERRM);END;

用户自定义的异常

  • 异常中涉及的步骤
  •    -  声明异常
  •    -  引发异常
  •    -  处理异常
  • 用户自定义异常必须声明部分进行声明。
  • 当异常发生时,系统不能自动触发,需要用户使用RAISE语句。
  • 在异常处理部分捕捉并处理异常。

2.  用户定义异常

   语法格式:

   delcare

         异常处理名称   exception;

 begin

   …..

  EXCEPTION

      WHEN 异常处理名称 THEN

            语句1;

        WHEN THEN

           语句2;

      WHEN OTHERS THEN

             语句3;

  END;

【例】修改7844员工的工资(增加1000),保证修改后工资不超过6000。

---修改7844员工的工资(增加1000),保证修改后工资不超过6000。
DECLAREe_1 EXCEPTION;v_sal scott.emp.sal%TYPE;
BEGINUPDATE scott.emp SET sal=sal+1000 WHERE empno=7844 ;select sal into v_sal from scott.emp  where empno=7844;--- 取出更新后的工资IF v_sal>4000 THEN RAISE e_1;END IF;EXCEPTIONWHEN e_1 THENDBMS_OUTPUT.PUT_LINE('The salary is too large!');ROLLBACK;
END; 

异常处理练习:

练习:更新scott.emp7788员工的工资,若没有成功,请抛出异常。

declarev_empno  scott.emp.empno%type;no_result  EXCEPTION;
Beginv_empno:=&a;update scott.emp  set sal=sal+100 where empno=v_empno;if  SQL%NOTFOUND   thenraise no_result;end if;
exceptionwhen  no_result thendbms_output.put_line('数据没有更新');when others thendbms_output.put_line(sqlcode||'   '||sqlerrm);
end;

习题 :

显示学生借书系统,是否借书过期,如过期,请给出需要缴纳的罚款数。

select deptno,empno,sal,hiredate ,(casewhen trunc(sysdate-hiredate)>5000 then ‘过期'when hiredate is null then '没借书'else ''end)  as 是否借书,(casewhen trunc(sysdate-hiredate)>5000 then    trunc(sysdate-hiredate)*0.1else 0end) as  罚款from scott.emp;

异常处理练习

--- 练习:更新scott.emp中7788员工的工资,若没有成功,请抛出异常。declarev_empno  scott.emp.empno%type;no_result  EXCEPTION;
Beginv_empno:=&a;update scott.emp  set sal=sal+100 where empno=v_empno;if _______then
___________________end if;
exception
_________________
dbms_output.put_line('数据没有更新');when others thendbms_output.put_line(sqlcode||'   '||sqlerrm);
end;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/610336.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NR cell配置带宽时,如何设置carrierBandwidth?

NR中带宽在38.101中有规定。 如上是FR1 38.101-1中与带宽设定有关的table&#xff0c;协议中根据SCS规定的传输带宽和可以配置的RB 数如上表&#xff0c;也就是说在实网下或者lab测试配置带宽时要根据上表内容去配置&#xff0c;举例如下。 如上图分别是几种带宽的配置参数&…

Matlab绘制双纵轴图(yyaxis函数)

一、方法一yyaxis函数 x linspace(0,pi); y1 cos(x); yyaxis left; % 激活左边的轴 plot(x,y1) xlabel(X-axis); ylabel(left Y-axis); % 给左y轴添加轴标签hold on yyaxis right; % 激活右边的轴 y2 cos(2*x); plot(x,y2) ylim([-1,1]); % 设置右y轴的界限 ylabel(right Y…

【前端】前后端的网络通信基础操作(原生ajax, axios, fetch)

概述 前后端网络请求工具 原生ajaxfetch apiaxios GET和POST请求 get只能发纯文本 post可以发不同类型的数据&#xff0c;要设置请求头&#xff0c;需要告诉服务器一些额外信息 测试服务器地址 有一些公共的测试 API 可供学习和测试用途。这些 API 允许你发送 HTTP 请求…

24年全国31省份教师资格笔试报名时间汇总报名材料❗

✅教资报考必备材料&#xff1a;个人证件照、个人证件照材料、个人证件照。 &#x1f550;全国各地区报名时间汇总&#xff1a; 北京 1月12日-15日15:00 广东 1月12日9:30至15日16:00 山东 1月12日-15日15:00 江苏 1月12日-15日12:00 吉林 1月12日-15日16:00 四川 1月12日-15日…

私域新手必看:这可能是你最快速的入门指南!

一、认知层&#xff1a;为什么必须做私域&#xff1f; 了解这个问题&#xff0c;必须得观察一下中国现状。根据中国互联网络信息中心&#xff08;CNNIC&#xff09;发布第48次《中国互联网络发展状况统计报告》显示&#xff0c;截至 2021 年 6 月&#xff1a; 而典型电商平台的…

电口模块SFP-GE-T常见问题解答

电口模块SFP-GE-T是一种常见的网络设备&#xff0c;用于实现光电信号的转换。在使用电口模块SFP-GE-T的过程中&#xff0c;可能会遇到一些问题。本文将为您解答一些常见问题&#xff0c;并提供一些使用技巧。 一、电口模块SFP-GE-T怎么用&#xff1f; 使用电口模块SFP-GE-T的…

【手搓深度学习算法】用逻辑回归分类双月牙数据集-非线性数据篇

用逻辑回归分类-非线性数据篇 前言 逻辑斯蒂回归是一种广泛使用的分类方法&#xff0c;它是基于条件概率密度函数的最大似然估计的。它的主要思想是将输入空间划分为多个子空间&#xff0c;每个子空间对应一个类别。在每个子空间内部&#xff0c;我们假设输入变量的取值与类别…

2024年寒假即将来临 如何实现高质量亲子陪伴?

近日,各地陆续公布了寒假放假时间安排,孩子们期待着迎来一个休闲和轻松的假期。然而,对于许多家长来说,他们也意识到寒假不仅是一个放松的时间,更是一个增进亲子关系的宝贵机会,可以为孩子提供有意义的学习陪伴。 自“双减”政策落地后,学生的课业负担减轻许多,拥有了更多的空余…

【leetcode 2707. 字符串中的额外字符】动态规划 字典树

2707. 字符串中的额外字符 题目描述 给你一个下标从 0 开始的字符串 s 和一个单词字典 dictionary 。你需要将 s 分割成若干个 互不重叠 的子字符串&#xff0c;每个子字符串都在 dictionary 中出现过。s 中可能会有一些 额外的字符 不在任何子字符串中。 请你采取最优策略分割…

Go 如何处理死锁以提供哪些工具来检测或防死锁?

并发是 Go 的核心特性&#xff0c;它使程序能够同时处理多个任务。它是现代编程的一个强大组件&#xff0c;如果使用正确&#xff0c;可以产生高效、高性能的应用程序。然而&#xff0c;并发性也带来了顺序编程中不存在的某些类型错误的可能性&#xff0c;其中最臭名昭著的是死…

拼多多API的未来:无限可能性和创新空间

拼多多&#xff0c;作为中国电商市场的巨头之一&#xff0c;自成立以来一直保持着高速的发展态势。其API的开放为开发者提供了无限的可能性和创新空间&#xff0c;使得更多的商业逻辑和功能得以实现。本文将深入探讨拼多多API的未来发展&#xff0c;以及它所具备的无限可能性和…

面相圆润是有福气的象征

在中国传统文化中&#xff0c;面相是一个非常重要的概念。相信大家肯定听说过“相由心生”这个成语吧&#xff0c;这就是告诉我们&#xff0c;一个人的面貌其实是可以反映出他内心的状态和气质&#xff0c;也可以反映其性格、健康状况和运势等。而一个圆润的面相&#xff0c;则…

游泳耳机排行榜前四名,分享几款值得推荐的游泳耳机

游泳是一项全面锻炼身体的运动&#xff0c;然而&#xff0c;水的阻力有时让人感到运动的笨拙和单调。为了让游泳更具趣味性和挑战性&#xff0c;选择一款高品质的游泳耳机至关重要。以下是游泳耳机排行榜前四名&#xff0c;以及几款强烈推荐的游泳耳机&#xff0c;它们结合防水…

火狐谷歌兼容性问题整理

火狐谷歌兼容性问题整理 整理近期项目中遇到的火狐浏览器和谷歌浏览器兼容性问题。 数字输入框实现功能&#xff1a;限制输入框可输入内容类型为Number类型&#xff0c;其他类型不可输入。 &#xff08;1&#xff09;错误实现方法&#xff1a; 此方式在谷歌浏览器中可以实现&…

【QT-UI】

1.使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 #include "mainwindow.h" #include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), …

Python中级知识梳理

1. 文件操作 Python中的文件操作通常使用内置的open()函数来打开文件。以下是一个简单的示例&#xff1a; with open("file.txt", "r") as f:content f.read()print(content)在这个示例中&#xff0c;我们打开了名为"file.txt"的文件&#xf…

mac 快捷键

mac 程序坞 ctrlaltD:打开程序坞 调度中心 Ctrl键↑: 调度中心 Ctrl键↓:应用程序窗口 F11 : 显示桌面 输入法 Ctrl键空格: 切换输入法 Ctrl键Alt(Option)空格: 切换输入法 截屏 帮助 Ctrl键shift键/: 显示帮助

使用 CSS : 伪元素:after、过渡动画transition实现过渡效果(鼠标悬浮或点击 标签时,底部边框从左到右过渡)

首先&#xff0c;给 <span> 标签添加一个父元素&#xff0c;定义属性类名&#xff1a;nav-wrapper &#xff0c;父级设置相对定位。然后&#xff0c;使用 ::after 伪元素来创建一个与底部边框相同宽度的元素&#xff0c;初始时宽度为 0&#xff0c;通过过渡动画transitio…

「服务器」4.新手小白如何安装服务器环境-宝塔

刚开始初始化好的服务器&#xff0c;使用了阿里云客户端&#xff0c;看着网络脚本乱装&#xff0c;后来决定宝塔环境发现有重复的环境&#xff0c;遂决定重新初始化一下&#xff0c;然后重头干起。 重置服务器 将服务器关闭运行状态后&#xff0c;点击重新初始化云盘即可重新初…

GCF:在线市场异质治疗效果估计的广义因果森林

英文题目&#xff1a;GCF: Generalized Causal Forest for Heterogeneous Treatment Effects Estimation in Online Marketplace 中文题目&#xff1a;GCF&#xff1a;在线市场异质治疗效果估计的广义因果森林 单位&#xff1a;滴滴&美团 时间&#xff1a;2022 论文链接…