Oracle中的PL/SQL语句 oracle入门教程之PL/SQL

发布时间:2020-07-04编辑:脚本学堂
本文介绍下,oracle数据库中的PL/SQL语句的相关知识,作为oracle入门教程中的重点内容,通过具体实例做了详细的讲解,有需要的朋友参考下吧。

一, 概述
 1, 每种数据库都有内部的语言
 2, PL/SQL是 Oracle 中使用的编程语言   
 3, 编程语言
    ① 数据类型
    ② 语法
 4, Procedural Language/SQL
    过程化语言, 也就是带有分支循环的语言
    SQL语言功能太单一, 需要结合其他的语言完成复杂的功能.
    PL/SQL是oracle数据库sql语句的扩展。
    在普通SQL语句的使用上增加了编程语言的特点,
    所以PL/SQL就是把数据操作和查询语句组织在PL/SQL代码的过程性单元中,
    通过逻辑判断、循环等操作实现复杂的功能或者计算的程序语言。

二, PL/SQL
1, 匿名块
  (1)格式
     [declare
        变量声明
     ]
     begin
        正常流程语句
     [exception
        异常处理
     ]
     end   
  (2)HelloWorld
 

复制代码 代码示例:
SQL> set serveroutput on;
SQL> begin
  2          dbms_output.put_line('Hello World!');
  3      end;
  4      /
Hello World!
 

     注: 必须打开输出开关, 才能看到输出显示
  (3)declare
    ① 变量名命名惯例, 以 "v_" 为前缀
    ② declare 变量名 类型;
    ③ 赋值语句->  变量名 := 值;
 

复制代码 代码示例:
SQL> declare
  2    v_name varchar2(20);
  3  begin
  4    v_name := 'myname';
  5    dbms_output.put_line(v_name);
  6  end;
  7  /
myname
 

  (4)exception
 

复制代码 代码示例:
SQL> declare
  2    v_num number := 0;
  3  begin
  4    v_num := 1 / v_num;
  5    dbms_output.put_line(v_num);
  6  exception
  7    when others then
  8      dbms_output.put_line('error');
  9  end;
 10  /
error   
 

2, 变量声明的规则
(1) 变量名不能使用保留字, 如 from, select 等
(2) 第一个字符必须是字母
(3) 变量名最多包含30个字符
(4) 不要与数据库的表或者列同名
(5) 每一行只能声明一个变量

3, 常用变量类型
(1) binary_integer  : 整数, 主要用来计数而不是用来表示字段类型.
(2) number          : 数字类型
(3) char            : 定长字符串
(4) varchar(2)      : 变长字符串
(5) date            : 日期
(6) long            : 长字符串, 最大 2GB
(7) boolean         : 布尔类型, 取值 true/false/null

4, 简单变量
(1)
 

复制代码 代码示例:
declare 
    v_temp number(1) := 0; 
    v_count binary_integer := 0; 
    v_sal number(7, 2) := 4000.00; 
    v_date date := sysdate; 
    v_pi constant number(3, 2) := 3.14;     -- 常量 
    v_valid boolean := false; 
    v_name varchar2(20) not null := 'MyName';   -- 不能取空值 
begin 
    dbms_output.put_line('v_temp value:' || v_temp); 
end; 

(2) 变量的作用
    通常用于存储某张表的字段的值.
(3) %type , 同步 表字段/其他变量 的类型
 

复制代码 代码示例:
declare 
    v_empno number(4);       -- 自定义类型    
    v_empno2 emp.empno%type; -- emp表的empno字段的类型 
    v_empno3 v_empno2%type;  -- v_empno2的类型 
begin 
    dbms_output.put_line('test %type'); 
end;

5, 复杂变量 table record
(1) Table 变量类型 , 类似 java中的数组
注: 先声明类型, 在声明该类型的变量
 

复制代码 代码示例:
declare 
    type type_table_empno           -- 声明 类型  
        is table of emp.empno%type  -- 指定是 table类型 以及每个元素的类型 
        index by binary_integer;    -- 指定下标的类型 
 
    -- 声明一个 type_table_empno 类型的变量 
    v_empnos type_table_empno; 
begin 
    v_empnos(0) := 1111; 
    v_empnos(1) := 2222; 
    v_empnos(2) := 3333; 
    dbms_output.put_line(v_empnos(1)); 
end; 
 

(2) Record 变量类型, 类似于 C语言中的结构体

 

复制代码 代码示例:
declare 
    type type_record_dept is record 
        ( 
            deptno dept.deptno%type, 
            dname dept.dname%type, 
            loc dept.loc%type 
        ); 
    v_temp type_record_dept; 
begin 
    v_temp.deptno := 50; 
    v_temp.dname := 'zhangsan'; 
    dbms_output.put_line('v_temp.deptno ' || v_temp.deptno); 
    dbms_output.put_line('v_temp.dname ' || v_temp.dname); 
end; 

② 使用 %rowtype声明 record变量
 

复制代码 代码示例:
declare 
    v_temp dept%rowtype; 
begin 
    v_temp.deptno := 55; 
    v_temp.dname := 'zhangsan'; 
    v_temp.loc := 'WuHan'; 
    dbms_output.put_line('v_temp.deptno ' || v_temp.deptno); 
    dbms_output.put_line('v_temp.dname ' || v_temp.dname); 
    dbms_output.put_line('v_temp.loc ' || v_temp.loc); 
end; 

6, SQL语句的运用 into
(1) select into
注: 有且只能返回一行数据
① %type
 

复制代码 代码示例:
declare 
    v_ename emp.ename%type; 
    v_sal emp.sal%type; 
begin 
    select ename, sal into v_ename, v_sal 
    from emp 
    where empno = 7566; 
    dbms_output.put_line('v_ename ' || v_ename); 
    dbms_output.put_line('v_sal ' || v_sal); 
end; 

②  %rowtype
 

复制代码 代码示例:
declare 
    v_emp emp%rowtype; 
begin 
    select * into v_emp  
    from emp  
    where empno = 7566; 
    dbms_output.put_line('v_emp.empno ' || v_emp.empno); 
    dbms_output.put_line('v_emp.ename ' || v_emp.ename); 
    dbms_output.put_line('v_emp.sal ' || v_emp.sal);    
end; 

(2) insert into
 

复制代码 代码示例:
create table dept2 as select * from dept; 
declare 
    v_deptno dept.deptno%type := 50; 
    v_dname dept.dname%type := 'game'; 
    v_loc dept.loc%type := 'WuHan'; 
begin 
    insert into dept2 values(v_deptno, v_dname, v_loc); 
    commit; 
end; 

(3) update -- sql%rowcount
 

复制代码 代码示例:
注: 关键字sql, 其属性rowcount, 刚刚执行的语句影响了几条记录 
create table emp2 as select * from emp; 
declare 
    v_deptno emp2.deptno%type := 10; 
    v_count number; 
begin 
    update emp2 set sal = sal / 2 where deptno = v_deptno; 
    -- select count(*) into v_count from emp; --影响一条记录 
    dbms_output.put_line(sql%rowcount || ' 条记录被影响'); 
    commit; 
end; 

7, 循环 loop
(1) 类似于 java中 do{ .. }while(); 循环
 

复制代码 代码示例:
declare 
    i binary_integer := 1; 
begin 
    loop 
        dbms_output.put_line(i); 
        i := i + 1; 
        exit when ( i >= 11 ); 
    end loop; 
end; 

(2) 类似于 java中 while(){} 循环
 

复制代码 代码示例:
declare 
    i binary_integer := 1; 
begin    
    while i < 11 loop 
        dbms_output.put_line(i); 
        i := i + 1; 
    end loop; 
end; 

(3) 类似于 java中 for(){} 循环
① for each
 

复制代码 代码示例:
begin 
    for i in 1..10 loop 
        dbms_output.put_line(i); 
    end loop; 
end; 

② 反转
 

复制代码 代码示例:
begin 
    for i in reverse 1..10 loop 
        dbms_output.put_line(i); 
    end loop; 
end; 

8, IF语句

格式:
    if condition then
        ...
    end if;
例子:
 

复制代码 代码示例:
declare 
    x number := 1; 
begin 
    if x < 10 then 
        dbms_output.put_line(x || ' is less than 10'); 
    end if; 
end; 


格式:
    if condition then
        ...
    else
        ...
    end if;
例子:
 

复制代码 代码示例:
declare 
    x number(2) := 11; 
begin 
    if x < 10 then 
        dbms_output.put_line(x || ' is less than 10'); 
    else 
        dbms_output.put_line(x || ' is bigger than 10'); 
    end if; 
end; 


格式:
if condition_1 then
    ...
elsif condition_2 then
    ...
else
    ...
end if;
举例:
 

复制代码 代码示例:
declare 
    x number(2) := 10; 
begin 
    if x < 10 then 
        dbms_output.put_line(x || ' is less than 10'); 
    elsif x < 20 then 
        dbms_output.put_line(x || ' is less then 20'); 
    else 
        dbms_output.put_line(x || ' is bigger than 20'); 
    end if; 
end; 

9, 异常处理
(1) too_many_rows
 

复制代码 代码示例:
declare 
    v_temp number(4); 
begin 
    select empno into v_temp from emp where deptno = 10; 
exception 
    when too_many_rows then 
        dbms_output.put_line('太多记录了'); 
    when others then 
        dbms_output.put_line('error'); 
end; 

(2) no_data_found
 

复制代码 代码示例:
declare 
    v_temp number(4); 
begin 
    select empno into v_temp from emp where empno = 2222; 
exception  
    when no_data_found then 
        dbms_output.put_line('没有数据'); 
end; 

(3) 记录错误
 

复制代码 代码示例:
-- 记录错误的日志表 
create table errorlog 

    id number primary key, 
    errorcode number, 
    errormsg varchar2(1024), 
    errordate date 
); 
 
-- 创建序列 
create sequence seq_errorlog_id start with 1 increment by 1; 
-- 出错后, 插入错误日志表, SQLCODE, SQLERRM 
declare 
    v_deptno dept.deptno%type := 10; 
    v_errorcode errorlog.errorcode%type; 
    v_errormsg errorlog.errormsg%type; 
begin 
    delete from dept where deptno = v_deptno; 
    commit; 
exception 
    when others then 
        rollback; 
        v_errorcode := SQLCODE; 
        v_errormsg := SQLERRM; 
        insert into errorlog  
          values(seq_errorlog_id.nextval, v_errorcode, v_errormsg, sysdate); 
        commit; 
end; 
-- clean 
-- drop sequence seq_errorlog_id; 
-- drop table errorlog; 

10, case 语句
参考: http://www.jb200.com/db/12711.html
(1) CASE WHEN 表达式有两种形式
① 简单 case函数
 

复制代码 代码示例:
case sex 
  when '1' then '男' 
  when '2' then '女' 
  else '其他'  
end   

② case 搜索函数
 

复制代码 代码示例:
case 
  when sex = '1' then '男' 
  when sex = '2' then '女' 
  else '其他' 
end 

(2) CASE WHEN 在语句中不同位置的用法
① SELECT CASE WHEN 用法
 

复制代码 代码示例:
SELECT grade, COUNT (CASE WHEN sex = 1 THEN 1      /*sex 1为男生,2位女生*/ 
                     ELSE NULL 
                     END) 男生数, 
              COUNT (CASE WHEN sex = 2 THEN 1 
                     ELSE NULL 
                     END) 女生数 
FROM students GROUP BY grade;

② WHERE CASE WHEN 用法
 

复制代码 代码示例:
SELECT T2.*, T1.* 
FROM T1, T2 
WHERE (CASE WHEN T2.COMPARE_TYPE = 'A' AND T1.SOME_TYPE LIKE 'NOTHING%' THEN 1 
       WHEN T2.COMPARE_TYPE != 'A' AND T1.SOME_TYPE NOT LIKE 'NOTHING%' THEN 1 
       ELSE 0 
       END) = 1 

③ GROUP BY CASE WHEN 用法
 

复制代码 代码示例:
SELECT   
        CASE WHEN salary <= 500 THEN '1'   
        WHEN salary > 500 AND salary <= 600  THEN '2'   
        WHEN salary > 600 AND salary <= 800  THEN '3'   
        WHEN salary > 800 AND salary <= 1000 THEN '4'   
        ELSE NULL  
        END salary_class, -- 别名命名 
        COUNT(*)   
FROM Table_A   
GROUP BY   
        CASE WHEN salary <= 500 THEN '1'   
        WHEN salary > 500 AND salary <= 600  THEN '2'   
        WHEN salary > 600 AND salary <= 800  THEN '3'   
        WHEN salary > 800 AND salary <= 1000 THEN '4'   
        ELSE NULL  
        END;