PL/SQL特点及高级应用

为什么使用PL/SQL

  执行sql语句时,一次仅向Oracle服务器发送一条语句可能会导致大量的网络流量。PL/SQL可以一次性发送多条sql语句,减少了Oracle服务器的开销。

PL/SQL特点

  数据抽象。在PL/SQL中,面向对象的编程是基于对象类型的。对象类型封装了数据结构、函数和过程。组成数据结构的为属性,函数和过程为方法。

CREATE TYPE BankAccount AS OBJECT (
    accountNo VARCHAR2(30),    
    MEMBER PROCEDURE desp(amount IN REAL),
    MEMBER FUNCTION computeBalance(num IN INTEGER) RETURN INTEGER
);

基本语言块  

DECLARE -- 声明变量、游标、用户自定义类型和异常
BEGIN -- 程序开始标志
EXCEPTION -- 异常处理部分
END; -- 程序结束标志

过程  

SET SERVEROUTPUT ON;

CREATE OR REPLACE PROCEDURE print ( hyname VARCHAR2 )
    AS
BEGIN
    dbms_output.put_line(hyname);
END;

EXEC print('hello world');

函数

CREATE OR REPLACE FUNCTION compare (
    firstnum   IN NUMBER,
    endnum     IN NUMBER
) RETURN NUMBER AS
    resultnum   NUMBER(38);
BEGIN
    IF
        firstnum > endnum
    THEN
        resultnum := firstnum;
    ELSE
        resultnum := endnum;
    END IF;

    RETURN resultnum;
END;

BEGIN
    dbms_output.put_line(compare(100,200) );
END;

   包是一组相关过程、函数、变量、类型和游标等PL/SQL程序设计元素的组合。包具有面向对象设计的特点,是对这些PL/SQL程序设计元素的封装。一个包由两个分开的部分组成即包头和包体。包为PL/SQL提供了全局变量的作用。  

-- 创建包头
CREATE OR REPLACE PACKAGE packagedemo AS
    age INTEGER;
    FUNCTION compare ( firstnum NUMBER,endnum NUMBER ) RETURN NUMBER;

END;

-- 创建包体
CREATE OR REPLACE PACKAGE BODY packagedemo AS

    FUNCTION compare ( firstnum NUMBER,endnum NUMBER ) RETURN NUMBER AS
        resultnum   NUMBER(38);
    BEGIN
        IF
            firstnum > endnum
        THEN
            resultnum := firstnum;
        ELSE
            resultnum := endnum;
        END IF;

        RETURN resultnum;
    END;

END;

-- DEMO
SELECT PACKAGEDEMO.COMPARE(100, 200) AS DEMO FROM F_ORDER;

BEGIN
    packagedemo.age := 100;
    dbms_output.put_line(packagedemo.age);
END;

集合

  index-by表

DECLARE
    TYPE hyname IS
        TABLE OF f_order.hy_name%TYPE INDEX BY BINARY_INTEGER;
    membername   hyname;
BEGIN
    membername(1) := 'hello world!';
    dbms_output.put_line(membername(1) );
END;

  嵌套表

DECLARE
    TYPE hynameArr IS
        TABLE OF VARCHAR2(30);
    memberArr   hynameArr;
BEGIN
    memberArr := hynameArr('hello', 'world');
    dbms_output.put_line(memberArr(1) );
END;

  可变数组

DECLARE
    TYPE hynameArr IS
        VARRAY(10) OF VARCHAR2(30);
    memberArr   hynameArr;
BEGIN
    memberArr := hynameArr('hello', 'world');
    dbms_output.put_line(memberArr(1) );
END;

游标

  游标创建

  1、显示游标

SET SERVEROUTPUT ON;
DECLARE
    CURSOR forder_cursor IS
        SELECT
            f_order_code,
            hy_code,
            hy_name
        FROM
            f_order;

BEGIN
    FOR result_row IN forder_cursor LOOP
        dbms_output.put_line(result_row.f_order_code
         || ','
         || result_row.hy_code
         || ','
         || result_row.hy_name);
    END LOOP;
END;

  2、隐式游标

  用隐式游标sql的属性%found,%notfound,%rowcount,%isopen观察update等语句的执行情况。

 

SET SERVEROUTPUT ON;

BEGIN
    UPDATE f_order
        SET
            hy_name = 'hello world'
    WHERE
        f_order_code = 'hello world';

    IF
        SQL%found
    THEN
        dbms_output.put_line('update success');
    ELSE
        dbms_output.put_line('update failed');
    END IF;

END;

  游标变量及控制游标变量

DECLARE
    TYPE fordercursortype IS REF CURSOR RETURN f_order%rowtype;
    fordercursor   fordercursortype;

    PROCEDURE f_order_procedure ( forder fordercursortype ) AS
        fordertemp   f_order%rowtype;
    BEGIN
        LOOP
            FETCH forder INTO fordertemp;
            EXIT WHEN forder%notfound;
            dbms_output.put_line(fordertemp.f_order_code
             || ','
             || fordertemp.hy_code
             || ','
             || fordertemp.hy_name);

        END LOOP;
    END;

BEGIN
    OPEN fordercursor FOR
        SELECT
            *
        FROM
            f_order
        WHERE
            hy_name = 'hello';

    f_order_procedure(fordercursor);
    CLOSE fordercursor;
END;

 

posted @ 2018-03-10 17:25  BINGJJFLY  阅读(662)  评论(0编辑  收藏  举报