为什么使用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 ) ASBEGIN 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;-- DEMOSELECT 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;