Oracle学习笔记之PL/SQL编程

时间:2021-10-16 16:59:20

      

SQL(Structure Query Language)的含义是结构化查询语句,最早由Boyce和Chambedin在1974年提出,称为SEQUEL语言。1976年,IBM公司的San Jose研究所在研制关系数据库管理系统System R时修改为SEQUEL2,即目前的SQL语言。1976年,SQL开始在商品化关系数据库管理系统中应用。1982年美国国家标准化组织ANSI确认SQL为数据库系统的工业标准。目前,许多关系型数据库供应商都在自己的数据库中支持SQL语言,如:Access、Sybase、SQL Server、Infomix、DB2等。

PL/SQL也是一种程序语言,叫做过程化SQL语言(Procedural Language/SQL)。PL/SQL是Oracle数据库对SQL语句的扩展。在普通SQL语句的使用上增加了编程语言的特点,所以PL/SQL就是把数据操作和查询语句组织在PL/SQL代码的过程性单元中,通过逻辑判断、循环等操作实现复杂的功能或者计算的程序语言。

PL/SQL编制的程序代码如下所示

 DECLARE

               xm varchar2(8):=’丽丽’;

                    zym varchar2(10):=’计算机’;

                    zxf number(2):=45;         

            A integer:=1;   

      BEGIN

               UPDATE  XS

                      SET  zxf=zx

        WHERE  xm=xm; /*更新学生表*/

 

                      IF SQL%NOTFOUND THEN       /*检查记录是否存在,如果不存在就插入记录*/

                      INSERT INTO XS(XH,XM,ZYM,ZXF)

                       VALUES(1,xm,zym,zxf);

                    END IF;

      END;

 

合法字符:

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

括以下3类:

(1)所有的大写和小写英文字母;

(2)数字0~9;

(3)符号() + - * / <> = ! ~ ;:. ` @  % ,  " # ^ & _ { } ? [ ]。

PL/SQL标识符的最大长度为30个字符,不区分大小写,但是适当地使用大小写可以提高程序的可读性。

Oracle学习笔记之PL/SQL编程

PL/SQL中变量声明格式:

(1)   变量必须以字母(A~Z)开头

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

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

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

Oracle学习笔记之PL/SQL编程

常用数据类型:

(1)VARCHAR类型:

语法格式:

var_field VARCHAR(n);

其中长度值n是本变量的最大长度且必须是正整数,例如:

var_field VARCHAR(11);

在定义变量时,可以同时对其进行初始化,例如:

var_field VARCHAR(11):=’Hello world’;

(2)NUMBER类型:

NUMBER数据类型可用来表示所有的数值类型。

语法格式:

num_field NUMBER(precision,scale);

其中precision表示总的位数;scale表示小数的位数,scale缺省表示小

数位为0。如果实际数据超出设定精度则出现错误。例如:

num_field NUMBER(10,2);

num_field是一个整数部分最多使8位,小数部分最多是2的变量。

declare

v_no number:=10;

begin

v_no:=v_no/0;

dbms_output.put_line(v_no);

exception

when others then

dbms_output.put_line('分母不能为0');

end;

(3)DATE类型:

用来存放日期时间类型数据,用7个字节分别描述年、月、日、时、

分、秒。

语法格式:

date_field DATE;

日期缺省格式为DD-MON-YY,分别对应日、月、年,例如17-JUN-

2002。注意,月份的表达要用英文单词的缩写格式。日期的格式可

以设置为中文格式,例如17-六月-2002。

(4)BOOLEAN类型:

逻辑型(布尔型)变量的值只有true(真)或false(假)。逻辑型变量一般用

于判断状态,然后根据其值是“真”或是“假”来决定程序执行分支。关

系表达式的值就是一个逻辑值。

注意:boolean类型变量不能直接通过  dbms_output.put_line(参数);直接输出,如果想输出,必须通过if判断;

条件判断语句:

IF逻辑结构

IF逻辑结构有3种表达式。

(1)  IF-THEN

语法格式:

IF Boolean_expression THEN      /*条件表达式*/

Run_expression          /*条件表达式为真时执行*/

END IF

(2)   IF-THEN-ELSE

语法格式:

IF Boolean_expression THEN             /*条件表达式*/

Run_expression                            /*条件表达式为真时执行*/

ELSE

Run_expression                          /*条件表达式为假时执行*/

END IF;

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

语法格式:

IF Boolean_expression1 THEN

Run_expression1

ELSIF Boolean_expression2 THEN

Run_expression2

ELSE

Run_expression3

END IF;

declare

i number:=10;

begin

if i<=0

then

dbms_output.put_line('分母不能为0');

else

dbms_output.put_line('分母不能为2');

end if;

end;

declare

v_no number:=1000;

begin

if v_no>1000 then

dbms_output.put_line('1');

elsif v_no=1000  then

dbms_output.put_line('2');

else

dbms_output.put_line('3');

end if;

end;

 循环操作语句:

(1) LOOP-EXIT-END循环

语法格式:

LOOP

Run_expression                          /*执行循环体*/

IF Boolean_expression THEN     /*测试Boolean_expression是否符合退出条件*/

EXIT;                                   /*满足退出条件,退出循环*/

END IF;

END LOOP;

declare

i number;

begin

for i in 1..10

loop

dbms_output.put_line(i);

end loop;

end;

declare

i number;

sum1 number:=0;

begin

for i in 1..10

loop

sum1:=sum1 +i;

end loop;

dbms_output.put_line(sum1);

end;

--例:求10的阶乘。

DECLARE

               n NUMBER:=1;

    count1 NUMBER:=2;

BEGIN

LOOP

            n:=n*count1;

            count1:=count1+1;

IF count1>10THEN

EXIT;

ENDIF;

ENDLOOP;

    dbms_output.put_line(to_char(n));

END;

(2)LOOP-EXIT-WHEN-END循环

除退出条件检测有所区别外,此结构与前一个循环结构

类似。

语法格式:

LOOP

Run_expression                                  /*执行循环体*/

EXIT WHEN Boolean_expression      /*测试是否符合退出条件*/

END LOOP;

--例:求10的阶乘。

DECLARE

               n NUMBER:=1;

    count1 NUMBER:=2;

BEGIN

LOOP

      n:=n*count1;

      count1:=count1+1;

EXITWHEN count1=11;

ENDLOOP;

    dbms_output.put_line(to_char(n));

END;

(3)WHILE-LOOP-END循环

语法格式:

WHILE Boolean_expression       /*测试Boolean_expression是否符合退出条件*/

LOOP

Run_expression          /*执行循环体*/

END LOOP;

--例:用WHILE-LOOP-END循环结构求10的阶层。

DECLARE

    n NUMBER:=1;

    count1 NUMBER:=2;

BEGIN

WHILE count1<=10

LOOP

      n:=n*count1;

      count1:=count1+1;

ENDLOOP;

    dbms_output.put_line(to_char(n));

END;

(4) FOR-IN-LOOP-END循环

语法格式:

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

LOOP

Run_expression      /*执行循环体*/

END LOOP;

--例:用FOR-IN-LOOP-END循环结构求10的阶层。

DECLARE

    n NUMBER:=1;

    count1 NUMBER;

BEGIN

FOR count1 IN2..10

LOOP

      n:=n*count1;

ENDLOOP;

    dbms_output.put_line(to_char(n));

END;

逻辑判断语句:

1.  CASE语句

CASE语句是在Oracle9i才引入的。

语法格式:

CASE input_name

WHEN expression1 THEN result_expression1

WHEN expression2 THEN result_expression2

WHEN expressionN THEN result_expression

[ELSE result_expressionN]

END;

例如:

DECLARE

    ename_1 varchar2(20);

    empno_1 varchar2(16);

    v_Result varchar2(20);

BEGIN

SELECT empno,ename

INTO empno_1,ename_1

FROM emp

WHERE empno='7369';

CASE  length(ename_1)/*判断v_kch的值,并给出结果 */

WHEN1THEN v_Result:='名字有1个字符';

WHEN2THEN v_Result:='名字有2个字符';

WHEN3THEN v_Result:='名字有3个字符';

WHEN4THEN v_Result:='名字有4个字符';

when5then v_result:='名字有5个字符';

ELSE

        v_Result:='Nothing';

ENDCASE;

      dbms_output.put_line(v_result||':'||ename_1);

END;

(5)使用%TYPE

%TYPE属性提供了变量和数据库列的数据类型。

my_xh XS.XH%TYPE;即:变量名 表名.列名%TYPE; 表示该属性为某个表中的某个列的类型一致;

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

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

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

例如:

-- Created on 2017/10/19 by ADMINISTRATOR

declare

    employeeNO emp.empno%type;--声明employeeNO 属性类型为emp表的empno列类型一致;

    employeeName emp.ename%type;

 

    deptNO number(5);

    deptName varchar2(20);

 

    i char(1):=2;

begin

if i=1then--注意比较通过一个=号

 

select deptno,dName into deptNO,deptName from dept where deptno=20;

      dbms_output.put_line('查询部门20的编号以及部门名称:'||deptno||':'||deptName);

else

 

select empno,ename into employeeNO ,employeeName from emp where empno=7369;

       dbms_output.put_line('查询7369员工编号以及姓名:'||employeeNO||':'||employeeName);

endif;

end;

(6)   E emp%ROWTYPE

可以使用%ROWTYPE属性声明描述表的行数据的记录;

例如:

-- Created on 2017/10/19 by ADMINISTRATOR

declare

    employee emp%rowtype;--声明employee 属性类型为emp表行类型一致;

    department dept%rowType;--声明deptartment变量为dept行类型;

    i number(5):=2;

begin

if i=1then--注意比较通过一个=号

 

select deptno,dName into department.deptno,department.dname from dept where deptno=20;--可以直接将某列赋值给该变量中的某个字段

      dbms_output.put_line('查询部门20的编号以及部门名称:'||department.deptno||':'||department.dname);

else

 

select emp.*into employee  from emp where empno=7369;--可以直接将正行赋值给该变量

       dbms_output.put_line('查询7369员工编号以及姓名:'||employee.empno||':'||employee.ename||':'||employee.hiredate);

endif;

end;

(7)数组类型:数据是具有相同数据类型的一组成员的集合。在PL/SQL中,数组数据类型是VARRAY。 定义VARRY数据类型语法如:

TYPE varray_name IS VARRAY(size) OF element_type [NOT NULL

例如:

DECLARE

--定义一个最多保存5个VARCHAR(25)数据类型成员的VARRAY数据类型

TYPE reg_varray_type ISVARRAY(5)OFVARCHAR(25);

--声明一个该VARRAY数据类型的变量

   v_reg_varray REG_VARRAY_TYPE;

 

BEGIN

--用构造函数语法赋予初值

   v_reg_varray := reg_varray_type ('中国','美国','英国','日本','法国');

 

   DBMS_OUTPUT.PUT_LINE('地区名称:'||v_reg_varray(1)||'、'

||v_reg_varray(2)||'、'

||v_reg_varray(3)||'、'

||v_reg_varray(4));

   DBMS_OUTPUT.PUT_LINE('赋予初值NULL的第5个成员的值:'||v_reg_varray(5));

--用构造函数语法赋予初值后就可以这样对成员赋值

   v_reg_varray(5):='法国';

   DBMS_OUTPUT.PUT_LINE('第5个成员的值:'||v_reg_varray(5));

END;

(8)record用户定义的记录,必须声明自己的域。记录包含唯一的命名域,具有不同的数据类型。

DECLARE

TYPE TimeRec IS RECORD(HH number(2),MM number(2));

TYPE MeetingTyp IS RECORD

(

Meeting_Date date,

Meeting_Time TimeRec,

Meeting_Addr varchar2(20),

Meeting_Purpose varchar2(50)

)

 

例如:

declare

--type声明一种自定义类型, is record表示该类型中包含有哪些属性

TYPE TimeRec ISRECORD(empno number(10),deptno number(5));

a   timeRec;--a变量为我们声明timeRec类型

begin

select empno,deptno into a  from emp where empno=7369;--into 表示赋值,注意一条语句中只能使用一次 且返回结果不能多条记录

dbms_output.put_line(a.empno);--表示输出

end;