半小时带你了解 PL/SQL

简介:PL/SQL是是甲骨文公司开发,嵌入在Oracle数据库中的编程语言。

基础

  • 块结构
    • declare 声明部分 – 所有变量,游标,子程序,和其他元素
    • begin - end ; – 程序主体,可执行命令
  • 常见符号解释:
符号 含义
|| 字符串连接符
:+ 赋值运算符
% 获得相同的数据类型
= 相等运算符
  • 变量的常见类型:
类型 含义
varchar2 可变长字符串
int 整数类型
number (precision,scale) precision表示数字中的有效位,如果没有指定precision的话,oracle将使用38作为精度, 如果scale大于零,表示数字精度到小数点右边的位数;scale默认设置为0;如果scale小于零,oracle将把该数字取舍到小数点左边的指定位数
clob 用于存储字符大块数据在数据库中 大小为 8 - 128 TB
date 日期和时间
  • 数组 TYPE varray_type_name IS VARRAY(n) OF element_type
DECLARE
    type namesarray IS VARRAY(5) OF VARCHAR2(10);
    type grades IS VARRAY(5) OF INTEGER;
    names namesarray; --拿到数组的引用,下面就可以变长使用该数组
    marks grades;
    total integer;
BEGIN
    names := namesarray('Kavita', 'Pritam', 'Ayan', 'Rishav', 'Aziz');
    marks:= grades(98, 97, 78, 87, 92);
    total := names.count; --求数组的长度
    dbms_output.put_line('Total '|| total || ' Students');
    FOR i in 1 .. total LOOP
        dbms_output.put_line('Student: ' || names(i) || ' Marks: ' || marks(i));
    END LOOP;
END;
  • 全局变量与局部变量
DECLARE
    -- Global variables
    num1 number := 95;
BEGIN
    DECLARE
        -- Local variables
        num1 number := 195;
    BEGIN
        
    END;
END;
  • 常量
PI constant number := 3.14;
  • SELECT INTO 取值出来使用: SELECT 表中变量 INTO 定义变量 FROM XXX
declare
  c_id customers.id%type := 1;
  c_name customers.name%type;
  c_addr customers.address%type;
  c_sal customers.salary%type;
begin
  select name,address,salary into c_name,c_addr,c_sal from customers where id = c_id;
  dbms_output.put_line('Customer '||c_name||' from '||c_addr||' earns '||c_sal);
end;
  • 控制语句
    1. IF 语句:if 使用 end if 结束
DECLARE
    a number(3) := 100;
BEGIN
    IF ( a = 10 ) THEN
        dbms_output.put_line('Value of a is 10' );
    ELSIF ( a = 20 ) THEN
        dbms_output.put_line('Value of a is 20' );
    ELSE
        dbms_output.put_line('None of the values is matching');
    END IF;
    dbms_output.put_line('Exact value of a is: '|| a );
END;

 2. CASE语句: 以end case 结束

declare
  grade char(1) := 'A';
begin
  case grade
    when 'A' then dbms_output.put_line('A');
    when 'B' then dbms_output.put_line('B');
    else dbms_output.put_line('NO');
  end case;
end;
  • 循环控制语句
     1. LOOP :已END LOOP结束
DECLARE
    x number := 10;
BEGIN
    LOOP
        dbms_output.put_line(x);
        x := x + 10;
        IF x > 50 THEN
            exit;
        END IF;
    END LOOP;
    -- after exit, control resumes here
    dbms_output.put_line('After Exit x is: ' || x);
END;

 2. WHILE: 已END LOOP结束

DECLARE
    a number(2) := 10;
BEGIN
    WHILE a < 20 LOOP
        dbms_output.put_line('value of a: ' || a);
        a := a + 1;
    END LOOP;
END;
  1. FOR: 已END LOOP结束
DECLARE
    a number(2);
BEGIN
    FOR a in 10 .. 20 LOOP   -- 10 .. 20 表示10-20 全包含
        dbms_output.put_line('value of a: ' || a);
    END LOOP;
END;

进阶 (进步进阶无所谓半小时就看完了)

  • 两种子程序:
     参数 in :入参, out : 返回值, in out :入参且是返回值
create PROCEDURE squareNum(x IN OUT number) IS
BEGIN
    x := x * x;
END;

  1. 函数:这些子程序返回一个值,主要用于计算并返回一个值。
  1.1. 创建函数

CREATE [OR REPLACE] FUNCTION function_name
[(parameter_name [IN | OUT | IN OUT] type [, ...])] RETURN return_datatype
    {IS | AS}
BEGIN
    < function_body >
     RETURN XXX;
END [function_name];
  1. 过程:这些子程序没有直接返回值,主要用于执行操作。
    2.1. 创建过程
Create PROCEDURE findMin(x IN number, y IN number, z OUT number) IS
BEGIN
    IF x < y THEN
        z:= x;
    ELSE
        z:= y;
    END IF;
END;

 2.2. 销毁过程

drop procedure procedure_name;
  • 游标
    1. 隐式游标
      DML操作和单行SELECT语句会使用隐式游标,它们是:
       * 插入操作:INSERT。
       * 更新操作:UPDATE。
       * 删除操作:DELETE。
       * 单行查询操作:SELECT ... INTO ...。
      当系统使用一个隐式游标时,可以通过隐式游标的属性来了解操作的状态和结果,进而控制程序的流程。隐式游标可以使用名字SQL来访问,但要注意,通过SQL游标名总是只能访问前一个DML操作或单行SELECT操作的游标属性。所以通常在刚刚执行完操作之后,立即使用SQL游标名来访问属性。游标的属性有四种,如下所示:

    * sql%found (布尔类型,默认值为null)INSERT、UPDATE、DELETE 成功返回TRUE

    * sql%notfound(布尔类型,默认值为null)INSERT、UPDATE、DELETE 不成功返回TRUE

    * sql%rowcount(数值类型默认值为0)返回INSERT、UPDATE、DELETE 影响的行数

    * sql%isopen(布尔类型)隐式游标返回FALSE,
 2. 显式游标
  * 声明游标 cursor c_customer is select * from customers;
   * 打开游标 open c_customer;
   * 获取游标 fetch c_customers into c_addr,c_name,c_salary;
   * 关闭游标 close c_customers;

declare  c_id customers.id%type;  
    c_name customers.name%type;  
    c_addr customers.address%type;   
    cursor c_customers is select id,name,address from customers;
begin  
    open c_customers;  
    loop    
        fetch c_customers into c_id,c_name,c_addr;    
        exit when c_customers%notfound;    
        dbms_output.put_line(c_id || ' ' || c_name || ' ' || c_addr);  
    end loop;  
    close c_customers;
end;
  • 异常处理
    • 异常声明 : exception_name exception;
    • 抛出异常 : raise exception_name;
    • 捕获异常 : when exception_name then…
DECLARE
   c_id customers.id%type := &c_id; -- 接收用户输入的值,运行的时候会弹出一个输入框。
   c_name  customers.name%type;
   c_addr customers.address%type;

   -- user defined exception
   ex_invalid_id  EXCEPTION;
BEGIN
   IF c_id <= 0 THEN
      RAISE ex_invalid_id;
   ELSE
      SELECT  name, address INTO  c_name, c_addr
      FROM customers
      WHERE id = c_id;

      DBMS_OUTPUT.PUT_LINE ('Name: '||  c_name);
      DBMS_OUTPUT.PUT_LINE ('Address: ' || c_addr);
   END IF;
EXCEPTION
   WHEN ex_invalid_id THEN
      dbms_output.put_line('ID must be greater than zero!');
   WHEN no_data_found THEN
      dbms_output.put_line('No such customer!');
   WHEN others THEN
      dbms_output.put_line('Error!');
END;

TIPS

  • dbms_output.put_line() 输出日志

你可能感兴趣的:(半小时带你了解 PL/SQL)