• Oracle之PLSQL语法


    PL/SQL

    PL:Procedure Language 过程式的语言。使用PL/SQL可以再Oracle中编写流程控制语句。

    PL/SQL基本语法:

    begin
    	-- 过程体
    end;
    

    :向控制台输出 Hello Oracle

    set serveroutput on		-- 设置向控制台服务器输出语句
    
    begin
    	-- dbms:database managment system  
    	dbms_output.put_line('Hello Oracle');
    end;
    

    定义变量

      Oracle定义的局部变量以 v_ 开始 v是变量variable简称

    语法:

    declare
     变量名 数据类型 := 值;
    begin
    	dbms_output.put_line(输出变量);
    end;
    

    :定义变量并输出

    declare
        v_var number(3,2):= 3.14;   -- :=  等于
    begin
        dbms_output.put_line('变量:' || v_var);    -- ||:拼接符
    end;
    

    定义常量

    语法:

    declare
    	常量名称 constant 数据类型 :=常量值;
    begin
    	dbms_output.put_line(输出常量);
    end;
    

    例:

    declare
        v_con constant number(6):=12;
    begin
        dbms_output.put_line('常量:'||v_con);
    end;
    

    修改变量的值

    例:

    declare
        v_var number(5):= 10;
    begin
        v_var := v_var + 2;
        dbms_output.put_line('变量值修改后为:'||v_var);
    end;
    

    接受输入

    语法:

    declare
    	变量名 数据类型 := &n;
    begin
    	dbms_output.put_line(变量名);
    end;
    

    :输入年龄并且打印

    declare
        v_input number(5):= &n;
    begin
        dbms_output.put_line('输入参数为:'||v_input);
    end;
    

    输入字符串并打印

    语法:

    declare
    	变量名 数据类型 := '&n';
    begin
    	dbms_output.put_line(变量名);
    end;
    

    例:

    declare
        v_input varchar2(5):= '&n';
    begin
        dbms_output.put_line('输入的字符串为:'||v_input);
    end;
    

    分支结构

    简单分支

    语法:

    begin
    	if 条件 then
    		-- 条件成立执行分支语句
    	end if;
    end 
    
    -- 注意: then相当于java的{   end if; 相当于java的}
    --       end if; 分号不能少
    

    例:

    declare
        v_input number(5):= &n;
    begin
        if v_input>80 then
            dbms_output.put_line('奖励一根棒棒糖!');
        end if;
    end;
    

    简单if...else分支

    语法

    begin
    	if 条件 then
      		-- 条件语句
    	else
      		-- 条件语句
    	end if;
    end ;
    
    -- 注意:else没有条件不要加then
    

    例:

    declare
        v_input number(5):= &n;
    begin
        if v_input>60 then
            dbms_output.put_line('及格');
        else
            dbms_output.put_line('不及格');
        end if;
    end;
    

    多条件if...else分支

    语法:

    begin
    	if 条件1 and 条件2 then
    		-- 条件语句
    	else
     		-- 条件语句
    	end if;
    end;
    

    例:

    declare
    	v_java_score number(5):=&n;
    	v_music_score number(5):=&n;
    begin
    	if v_java_score>90 and v_music_score>80 then
    		dbms_output.put_line('良好');
    	else
    		dbms_output.put_line('闭门思过');
    	end if;
    end;
    

    多重分支

    begin
    	if 条件 then
    		
    	elsif 条件 then
    		
    	else
    		
    	end if;
    end;
    

    例:

    declare
        v_input number(5):= &n;
    begin
        if v_input>=90 then
            dbms_output.put_line('优秀:'||v_input);
        elsif v_input<90 and v_input>=70 then
            dbms_output.put_line('良好:'||v_input);
        elsif v_input<70 and v_input>=60 then
            dbms_output.put_line('及格:'||v_input);
        else
            dbms_output.put_line('不及格:'||v_input);
        end if;
    end;
    

    多重等值判断

    语法:

    begin
    	case
    	when 条件 then
     
    	when 条件 then
     
    	when 条件 then
     
    	when 条件 then
     
    	else
     
    	end case;
    end;
    

    例:从控制台输入字母,判断等级 A优秀B良好C中等D及格E稀烂

    declare
    	v_garde varchar2(20) := '&n';
    begin
    	case 
    	when v_garde='A' then
     		dbms_output.put_line('优秀');
    	when v_garde='B' then
     		dbms_output.put_line('良好');
    	when v_garde='C' then
     		dbms_output.put_line('中等');
    	when v_garde='D' then
     		dbms_output.put_line('及格');
    	else
     		dbms_output.put_line('稀烂');
    	end case;
    end;
    

    循环结构

    for循环语法:

    begin
    	for 变量 in 初始值..最大值 loop
        	-- 打印语句  
    	end loop;
    end;
    
    -- 注意:初始值与最大值之间只有两个【..】
    

    例:向控制台打印1到10之间的整数

    begin
    	for i in 1..10 loop
     		dbms_output.put_line(i);
    	end loop;
    end;
    

    例:计算1~100和并打印

    declare
    	v_sum number(5):=0;
    begin
    	for i in 1..100 loop
     		v_sum := v_sum + i;
    	end loop;
    		dbms_output.put_line(v_sum);
    end;
    

    while循环语法:

    declare
    	初始化变量
    begin
    	while  条件  loop
    		执行循环体;
    		更新循环变量;
    	end loop
    end;
    

    例:1到100的和

    declare
        v_index number(3):=0;
        v_sum number(5):=0;
    begin
        while v_index<=100 loop
            v_sum := v_sum + v_index;
            v_index := v_index + 1;
        end loop;
            dbms_output.put_line('1到100累加之和:'||v_sum);
    end;
    

    loop循环,至少执行一次

    begin
    	loop
    		循环体
    		exit when 条件; 	-- 注意:条件为true退出循环
    	end loop;
    end;
    

    例:

    declare
        v_index number(3):=6;
        v_sum number(5):=6;
    begin
        loop
            v_sum := v_sum + v_index;
            v_index := v_index + 1;
        exit when v_index<=100;
        end loop;
            dbms_output.put_line('至少执行一次,结果为:'||v_sum);
    end;
    

    PL与SQL结合

    例:根据员工编号查询对应的员工信息(ename,sal,job),将查询的结果使用变量输出。

      步骤:1. 在declare块中定义变量,存储emp表对应的员工信息,

         2. 在begin块中编写sql语句,将查询的结果使用into关键字赋给变量,

         3. 输出对应编号的员工信息(ename,sal,job)。

    declare
        v_ename varchar2(30);
        v_sal number(5);
        v_job varchar2(30);
        v_empno number(4) :=&n;	-- 编号
    begin
        select ename 姓名,sal 薪资,job 职位 into v_ename,v_sal,v_job from emp where empno = v_empno;
        dbms_output.put_line(v_ename||'  '||v_sal||'  '||v_job);
    end;
    

     以上例子存在风险,变量名不知道列名称的数据类型和长度,一下方法可以解决此问题。

    %type

      为了使一个变量的数据类型与另一个已经定义了的变量(尤其是表的某一列)的数据类型相一致。

    declare
        v_ename emp.ename%type;
        v_sal emp.sal%type;
        v_job emp.job%type;
        v_empno emp.empno%type := &n;
    begin
        select ename,sal,job into v_ename,v_sal,v_job from emp where empno = v_empno;
        dbms_output.put_line(v_ename||'  '||v_sal||'  '||v_job);
    end; 
    

    %rowtype

      定义一个变量, 其数据类型和数据库表的数据结构相一致。定义一个变量的数据类型与一个表中记录的各个列的数据类型相对应、一致时,可以使用%rowtype来定义。

    -- employee 是一个变量名(自己声明的),表示emp表的一行数据
    -- 程序运行的时候根据where条件将emp表的一行赋给employee变量
    declare
        employee emp%rowtype;
        v_empno emp.empno%type:=&n;
    begin 
        SELECT ename,sal,job into employee.ename,employee.sal,employee.job FROM emp where empno = v_empno;
        dbms_output.put_line(employee.ename||'  '||employee.sal||'  '||employee.job);
    end;
    

    例:根据员工编号获取员工的工资,对工资进行判断,小于1000加100,1000~2000之间的加50,大于2000的加30

      步骤:
        1. 定义变量,
        2. 编写SQL语句根据编号查询工资,
        3. 编写 case when then 语句判断工资,并对工资进行累加(100,50,30),
        4. 执行update语句更新工资,最后使用 commit 提交数据。

    declare
        v_sal emp.sal%type; 
        v_empno emp.empno%type:=&n;
    begin
        select sal into v_sal from emp where empno = v_empno;
        case
        when v_sal<=1000 then
            v_sal := v_sal + 100;
        when v_sal>1000 and v_sal<=2000 then
            v_sal := v_sal + 50;
        when v_sal>2000 then
            v_sal := v_sal + 30;
      end case;
      update emp set sal=v_sal where empno=v_empno;     -- 数据更新
      commit;   -- 提交数据
    end;
    

    例:使用PL/SQL向控制台输出所有员工信息(ename,sal,job)

    declare 
    begin
        for employee in (select ename,sal,job from emp) loop
        dbms_output.put_line (employee.ename||'  '||employee.sal||'  '||employee.job);
        end loop;
    end;
    

    Oracle存储过程

      功能类似于java的方法,完成某个独立功能的一组指令(程序)集合。

    特征:没有return关键字

        编译一次,可以重复使用(调用)

        署名的PL/SQL(根据名称可以重复调用),之前写的PL/SQL是匿名的(每次执行都要编译,不能重复调用)

    存储过程语法:

    -- create or replace 执行存储过程如果没有就创建,如果有覆盖(替换)之前的存储过程
    create or replace procedure 存储过程名称(参数名称 参数类型  数据类型)
    as
     -- 定义变量
    begin
     -- 过程体
    end;
    
    -- 执行存储过程
    exec 存储过程名称;
    

    例:使用存储过程输出helloWorld

    create or replace procedure pro_hw(v_word in varchar2)
    as
    begin  
        dbms_output.put_line(v_word);
    end;
    
    exec pro_hw('HelloWorld!');		-- 执行存储过程,打印HelloWorld!
    

    例:根据员工编号获取员工信息,使用过程完成

      步骤:
        1. 定义存储过程,将员工编号作为参数
        2. 定义变量存储emp表的员工信息
        3. 定义sql语句根据员工编号获取员工信息
        4. 打印员工信息

    -- 定义存储过程
    create or replace procedure getEmpById(v_empno in number)
    as
    	employee emp%rowtype; 
    begin
    	select ename,sal,job,deptno into employee.ename,employee.sal,employee.job,employee.deptno from emp where empno=v_empno;
    	dbms_output.put_line(employee.ename||' '||employee.sal||' '||employee.job||'  '||employee.deptno);
    end;
    -- 执行过程
    exec getEmpById(7900);
    

    游标

      游标是指向此上下文区域的指针。PL/SQL通过游标控制上下文区域,游标保存SQL语句返回的行(一个或多个)。

      可以命名一个游标,以便在程序中引用它来获取和处理SQL语句返回的行,一次处理一个(行)。PL/SQL中有两种类型的游标:

    • 隐式游标

        当执行SQL语句时,如果语句没有显式游标,则Oracle会自动创建隐式游标。

    • 显式游标

        是指在使用之前有明确的游标声明和定义,这样游标定义会关联数据查询语句,通常会返回一行或多行。打开游标后,用户可以利用游标的位置对结果集进行任何操作,显示游标有用户控制。

    例:根据部门编号获取部门对应的员工信息,使用过程完成

    使用过程 + 游标完成,在过程中定义游标,逐个打印。

    -- 创建存储过程
    create or replace procedure getEmpByDeptNo(v_deptno in number)
    is
    begin
      for i in (select ename,sal,job from emp where deptno=v_deptno) loop
       dbms_output.put_line(i.ename||' '||i.sal||' '||i.job);
      end loop;
    end;
    -- 调用存储过程
    exec getEmpByDeptNo(30);
    

    场景:上面示例使用显示游标完成

    显示游标:自己定义游标

    显示游标语法:

    create or replace procedure 过程名(参数名 参数类型 数据类型)
    as
    cursor 游标名称  is SQL语句
    begin
      for 变量 in 游标名称  loop
        循环体
      end loop;
    end;
    
    create or place procedure get_Emp_By_Dept_No2(v_deptno in number)
    as
    -- cursor  科索沃
    cursor employee is select ename,sal,job from emp where deptno=v_deptno;
    begin
      for i in employee loop
         dbms_output.put_line(i.ename||'----'||i.sal||'------'||i.job);
      end loop;
    end;
    

    个人笔记,难免不足,可以参照下方链接

    PL/SQL教程https://www.yiibai.com/plsql

  • 相关阅读:
    Oracle学习(四)--sql及sql分类讲解
    Oracle学习(三)--数据类型及常用sql语句
    Oracle学习(二)--启动与关闭
    Tomcat学习笔记--启动成功访问报404错误
    有关Transaction not successfully started问题解决办法
    百度富文本编辑器UEditor1.3上传图片附件等
    hibernate+junit测试实体类生成数据库表
    js登录与注册验证
    SVN安装配置与使用
    [LeetCode] #38 Combination Sum
  • 原文地址:https://www.cnblogs.com/lyang-a/p/15042978.html
Copyright © 2020-2023  润新知