PL/SQL基本用法

什么是PL/SQL?

  • PL/SQL是一种程序语言,叫做过程化SQL语言(Procedure·Language/SQL)。
  • PL/SQL是Oracle数据库对SQL语言的扩展。在普通SQL语句的使用上增加了编程语言的特点。
  • PL/SQL是面向过程的语言

PL/SQL的语法结构

PL/SQL块的基本结构

DECLARE
	/*
	*声明部分--声明变量、常量、复杂数据类型、游标等
	*/
BEGIN
	/*
	*执行部分--PL/SQL语句和SQL与语句
	*/
EXECPTION
	/*
	*异常处理部分--处理运行错误
	*/
END;	--块结束标记

例子

SET SERVEROUTUT ON
BEGIN
	--打印输出
	DBMS_OUTPUT.PUT_LINE('hello everyone!')
END;

PL/SQL块的分类

  • 匿名块:动态构造、只能执行一次 子程序:储存在数据库中的存储过程、函数及包等。当在
  • 数据库上建立好后可以在其它程序中调用它们。
  • 触发器:当数据库发生操作时,会触发一些事件,从而自动执行相应的程序。

PL/SQL的变量类型

标识符

  • 当编写PL/SQL块时,为了临时存储数据,需要定义变量和常量。那么变量和常量的定义是需要满足标识符的限制要求的:
    • 标识符名不能超过三十个字符
    • 第一个字符必须是字母
    • 不分大小写
    • 不能用‘-‘(减号)
    • 注意:尽量不把变量名声明成和表中字段名一样的值

变量的命名方法

为了代码的可读性,需遵循以下编码规则

标识符 命名规则 例子
程序常量 v_name v_sal
程序变量 c_name c_pi
游标变量 name_curror emp_curror
异常标识 e_name e_integrity_error
记录类型 name_record emp_record

变量的类型

  • 数值类型:NUMBER(p,s)、INT、FLOAT等
  • 字符类型:CHAR(n)、VARCHAR2(n)
  • 日期类型:DATE
  • 布尔类型:BOOLEAN

变量的大小写规则

  • 当编写SQL语句和PL/SQL语句时,既可以采用大写格式,也可以采用小写格式。但是为了程序的可读性,应该尽量按照以下规则
    • SQL关键字大写,如:SELECT、UPDATE等
    • PL/SQL关键字大写,如:DECLARE、BEGIN、END等
    • 数据类型大写,如:INT、DATE等
    • 标识符和参数小写,如:v_sal等
    • 数据库对象和列小写,如:emp、sal等

注释

单行注释:-- 注释内容
多行注释:/* 注释内容 */

PL/SQL的引用型变量和记录型变量

  • 在许多情况下,PL/SQL变量可以用来存储在数据库表中的数据。在这种情况下,变量应该拥有与表列相同的类型。

  • 举例

DECLARE
	v_name  varchar2(10);
	v_sal number(7,2);
BEGIN
	SELECT ename,sal INTO v_name,v_sal FROM emp WHERE empon = 7788;
	--打印姓名和薪水
	DBMS_OUTPUT.PUT_LINE(v_name || ' 的工资是 :' || v_sal);
END;

以上的变量都为硬性编码,当数据表字段类型发生变化时,变量类型也要随之改变。非常的不便。

引用型变量

  • 应用型变量:是指其数据类型与已经定义的某个数据变量的类型相同,或者与数据库表的某个列的数据类型相同。
    • v_name emp.ename%TYPE;

    • 举例

-- 引用型变量
DEClARE
   v_name emp.ename%TYPE;
   v_sal emp.sal%TYPE;
BEGIN
--给变量赋值
   SELECT ename,sal
   INTO v_name,v_sal
   FROM emp
   WHERE empno = 7788;
--打印输出
   DBMS_OUTPUT.PUT_LINE( v_name || ' 的工资是 :' || v_sal );
END;

记录型变量

  • PL/SQL提供 %ROWTYPE 操作符,返回一个记录类型,其数据类型和数据库表的数据结构相一致。
    • emp_record emp%ROWTYPR;
    • 举例(记录型变量相当于记录一整行完整的表记录,通过“变量名.列名”获取其值)
-- 记录型变量
DEClARE
   emp_record emp%ROWTYPE;
BEGIN
--给变量赋值
   SELECT* 
   INTO emp_record 
   FROM emp
   WHERE empno = 7788;
--打印输出
   DBMS_OUTPUT.PUT_LINE( emp_record.name || ' 的工资是 :' || emp_record.sal );
END;

PL/SQL的运算符

算数运算符

运算符 意义
+ 加号
- 减号
* 乘号
/ 除号
** 乘方
-- 算数运算符
DEClARE
   v_num1 NUMBER(3) :=10;
   v_num2 NUMBER(3) :=2;
BEGIN
   DBMS_OUTPUT.PUT_LINE(v_num1 + v_num1);
   DBMS_OUTPUT.PUT_LINE(v_num1 - v_num1);
   DBMS_OUTPUT.PUT_LINE(v_num1 * v_num1);
   DBMS_OUTPUT.PUT_LINE(v_num1 / v_num1);
   DBMS_OUTPUT.PUT_LINE(v_num1 ** v_num1);
END;

关系运算符

运算符 意义
= 等于
<> , != , ~= , ^= 不等于
< 大于
> 小于
<= 小于等于
>= 大于等于
--“ &n1 ”替代变量,运行程序时,会提示用户输入值n1
DECLARE 
   v_num1 NUMBER(2) := &n1;
   v_num2 NUMBER(2) := &n2;
   BEGIN
   IF (v_num1 = v_num2) THEN
         DBMS_OUTPUT.PUT_LINE('num1等于num2');
   ELSIF(v_num1 < v_num2) THEN
         DBMS_OUTPUT.PUT_LINE('num1小于num2');
   ELSIF(v_num1 > v_num2) THEN
         DBMS_OUTPUT.PUT_LINE('num1大于num2');
   END IF;
       
       IF (v_num1 <> v_num2) THEN
             DBMS_OUTPUT.PUT_LINE('num1不等于num2');
       END IF;
   END;

比较运算符

运算符 意义
IS NULL 是空值
BRTWEEN…AND 介于俩者之间
IN 等于列表中的某个值
--比较运算符
DECLARE
	--&n1是替代变量,在执行程序时会提示输入值
    v_num1  NUMBER(2):= &n1;
BEGIN
	IF(v_num1 BETWEEN 5 AND 10 )THEN
	          DBMS_OUTPUT.PUT_LINE('num1在5到10之间');
	ELSE
	          DBMS_OUTPUT.PUT_LINE('num1不在5到10之间');
	END IF;
	
	IF(v_num1 IN(3,8,10) )THEN
	          DBMS_OUTPUT.PUT_LINE('num1等于3,8,10中的一个值');
	ELSE
	          DBMS_OUTPUT.PUT_LINE('num1不等于3,8,10中的一个值');
	END IF;
	
	IF(v_num1 IS NULL)THEN
	          DBMS_OUTPUT.PUT_LINE('num1为空');
	ELSE
	          DBMS_OUTPUT.PUT_LINE('num1不为空');
	END IF;
END;

逻辑运算符

运算符 意义
AND 逻辑与
OR 逻辑或
NOT 取反,如 IS NOT NULL,NOT IN
--逻辑运算符
DECLARE
    v_b1  BOOLEAN  := &n1;
    v_b2  BOOLEAN  := &n2;
BEGIN
    IF(v_b1 AND v_b2)THEN
            DBMS_OUTPUT.PUT_LINE('AND--TRUE');
    END IF;
    
    IF(v_b1 OR v_b2)THEN
            DBMS_OUTPUT.PUT_LINE('OR--TRUE');
    END IF;
    
    IF(NOT v_b1)THEN
            DBMS_OUTPUT.PUT_LINE('v_b1取反为TRUE');
    END IF;
END;

变量赋值

  • 变量赋值
    • variable := expression;
  • 字符及数字运算特点
    • 空值加数字认识空值:NULL + <数字> = NULL
    • 空值连接字符,结果仍为字符: NULL || <字符串> = <字符串>

PL/SQL的条件控制语句

IF语句

  • 举例1–简单的IF语句
--输入员工号,判断员工工资, 显示工资小于3000的员工姓名及工资。
--简单的IF语句
DECLARE
      v_name  emp.ename%TYPE;
      v_sal   emp.sal%TYPE;
BEGIN
      SELECT ename,sal
      INTO   v_name,v_sal
      FROM   emp
      WHERE  empno = &no;
      IF   v_sal <3000 THEN
           DBMS_OUTPUT.PUT_LINE(v_name||'的工资是:'||v_sal);
      END IF;
END;
  • 举例2–二重分支IF语句
--输入员工号,判断员工工资,将工资小于3000的员工工资涨200,并显示涨工资的员工姓名,其他员工显示员工姓名及工资。
--二重分支语句
DECLARE
       v_name    empnew.ename%TYPE;
       v_sal     empnew.sal%TYPE;
       v_empno   empnew.empno%TYPE := &no;
BEGIN
       SELECT ename,sal
       INTO   v_name,v_sal
       FROM   empnew
       WHERE  empno = v_empno;
       IF  v_sal <3000 THEN
           UPDATE empnew set sal = sal + 200 where empno = v_empno;
           COMMIT;
           DBMS_OUTPUT.put_line(v_name||'涨工资了');
       ELSE
           DBMS_OUTPUT.put_line(v_name||'的工资是:'||v_sal);
       END IF;
END;


  • 举例3–多重分支IF语句
--输入员工号,判断员工工资, 工资小于2000,显示低收入,工资小于6000,显示中等收入,其它显示高收入。
--多重分支语句
DECLARE
       v_name    empnew.ename%TYPE;
       v_sal     empnew.sal%TYPE;
       
BEGIN
       SELECT ename,sal
       INTO   v_name,v_sal
       FROM   empnew
       WHERE  empno = &no;
       IF v_sal<2000  THEN
          DBMS_OUTPUT.PUT_LINE(v_name||'的工资是:'||v_sal||' 属于低收入');
       ELSIF v_sal<6000  THEN
          DBMS_OUTPUT.PUT_LINE(v_name||'的工资是:'||v_sal||' 属于中等收入');
       ELSE
          DBMS_OUTPUT.PUT_LINE(v_name||'的工资是:'||v_sal||' 属于高收入');
       END IF;       
END;

CASE语句

  • 举例1–等值比较
--输入成级等级,判断属于哪个层次,并打印输出
--CASE 等值比较
DECLARE 
       v_grade char(1) := '&no';
BEGIN
       CASE v_grade
            WHEN  'A'  THEN
                  DBMS_OUTPUT.PUT_LINE('优秀');
            WHEN  'B'  THEN
                  DBMS_OUTPUT.PUT_LINE('中等');     
            WHEN  'C'  THEN
                  DBMS_OUTPUT.PUT_LINE('一般'); 
            ELSE
                  DBMS_OUTPUT.PUT_LINE('输入有误');    
       END CASE;              
END;

  • 举例2–非等值比较
--输入员工号,获取员工工资,判断工资,如果工资小于1500,补助加100,如果工资小于2500,补助加80,如果工资小于5000,补助加50.
--CASE 非等值比较
DECLARE       
       v_sal     empnew.sal%TYPE;
       v_empno   empnew.empno%TYPE := &no;
BEGIN
       SELECT sal
       INTO   v_sal
       FROM   empnew
       WHERE  empno = &no;
       CASE 
              WHEN v_sal<1500 THEN
                   UPDATE empnew set comm = nvl(comm,0)+100 WHERE empno = v_empno;
              WHEN v_sal<2500 THEN
                   UPDATE empnew set comm = nvl(comm,0)+80 WHERE empno = v_empno;     
              WHEN v_sal<5000 THEN
                   UPDATE empnew set comm = nvl(comm,0)+50 WHERE empno = v_empno;       
              --COMMIT; 
       END CASE;
END;

#PL/SQL的循环语句

  • 基本循环
--基本循环
DECLARE
    v_cnt INT :=1;
BEGIN
    LOOP 
          DBMS_OUTPUT.PUT_LINE(v_cnt);
          EXIT WHEN v_cnt = 10;
          v_cnt := v_cnt+1;          
    END LOOP;
END;
  • while循环
--while循环
DECLARE
    v_cnt INT :=1;
BEGIN
    WHILE v_cnt<=10 LOOP
          DBMS_OUTPUT.PUT_LINE(v_cnt);
          v_cnt := v_cnt+1;
    END LOOP;
END;

  • for循环
--IN  下限 1,上限10 “REVERSE” 代表递减,如果去掉“REVERSE”的话,就是打印1,2,3...10;
 
BEGIN
    FOR i  IN REVERSE 1..10 LOOP
        DBMS_OUTPUT.PUT_LINE(i);
    END LOOP;
END;

PL/SQL的嵌套循环与退出语句

嵌套循环和标号

  • 嵌套循环是指在一个循环语句中嵌入另一个循环语句
  • 标号用于标记嵌套块或嵌套循环
  • 使用<<lable_name>>定义标号
--嵌套循环
DECLARE
    v_result INT;
BEGIN
    <<outter>>
    FOR i IN 1..5 LOOP
        <<inter>>
        FOR j IN 1..5 LOOP
          v_result:=i;
          EXIT outter WHEN i=4;
        END LOOP inter;
        DBMS_OUTPUT.PUT_LINE('内'||v_result);
     END LOOP outter;
     DBMS_OUTPUT.PUT_LINE('外'||v_result);
END;

EXIT和EXIT WHEN语句

  • EXIT语句用于直接退出当前循环
  • EXIT WHERE语句用于在满足特定条件时退出当前循环
--CONTINUE
DECLARE
    v_cnt INT :=0;
BEGIN
    LOOP 
             v_cnt := v_cnt+1;
             CONTINUE WHEN v_cnt = 5;
             DBMS_OUTPUT.PUT_LINE(v_cnt);
             EXIT WHEN v_cnt = 10;     
    END LOOP;
END;

PL/SQL的顺序语句

GOTO语句

  • GOTO语句用于跳转到特定标号处执行语句
    • GOTO lable_name;
    • 注意:当使用GOTO跳转到特定标号时,标号后至少要包含一条执行语句
--GOTO语句
DECLARE
  v_cnt INT := 1;
BEGIN
  LOOP
    DBMS_OUTPUT.PUT_LINE(v_cnt);
    IF v_cnt=10 THEN
       --EXIT;
       GOTO end_loop;
    END IF;
    v_cnt := v_cnt + 1;
   END LOOP;
   <<end_loop>>
   DBMS_OUTPUT.PUT_LINE('循环结束');
END;

NULL语句

  • NULL语句不会执行任何操作,并且会直接将控制传递到下一个语句,使用该语句的主要目的是提高PL/SQL的可读性
  • 举例
--根据输入的员工号,判断员工的工资,如果工资小于3000,将该员工的补助加工资的2%,
  并打印输某员工的奖金更新了
--NULL语句
DECLARE
   v_sal empnew.sal%TYPE;
   v_name empnew.ename%TYPE;
BEGIN
  SELECT ename,sal 
  INTO v_name,v_sal
  FROM empnew
  WHERE empno = &no;
  IF v_sal<3000 THEN
    UPDATE empnew set comm = nvl(comm,0)+sal*0.2 WHERE ename=v_name;
    COMMIT;
    DBMS_OUTPUT.PUT_LINE(v_name||'的奖金更新了');
  ELSE
    NULL;
  END IF;
END;

猜你喜欢

转载自blog.csdn.net/qq_41525263/article/details/88555961