包用于 组合 PL/SQL类型、PL/SQL项、PL/SQL子程序,由 包规范、包体 组成.
一、建立包
建立包时,需要先建立包规范、然后建立包体.
1、建立包规范
包规范是包与应用程序之间的接口,是用来定义包的公用组件:常量、变量、游标、过程、函数等,包规范中定义的公用组件不仅可以在包内引用,也可以由其它的子程序引用,语法如下:
create or replace package pkg_name --指定包名
{is| as}
-- 在这里定义包规范的公用组件
end;
示例:
create or replace package pkg_first is
v_address VARCHAR2(20) := '中国';
PROCEDURE add_product(in_name VARCHAR2, in_price NUMBER, in_address VARCHAR2 DEFAULT v_address);
PROCEDURE del_category(in_cid NUMBER);
FUNCTION get_cname(in_cid NUMBER) RETURN VARCHAR2;
end;
2、建立包体
包体用于实现包规范中定义的过程、函数,建立包体时,也可以单独定义私有组件,包体中定义的私有组件只能在包内使用,不能在其它子程序中使用。定义包体语法如下:
create or replace package body pkg_name --指定包体名
{is| as}
-- 在这里实现包规范中定义的过程、函数,定义私有组件
end;
示例:
create or replace PACKAGE BODY pkg_first is
--包体中定义私有组件: check_fun 函数 功能:商品类别存在返回true,否则返回false
FUNCTION check_fun(in_cid NUMBER)
RETURN boolean
IS
v_count NUMBER;
BEGIN
SELECT COUNT(1) INTO v_count FROM category WHERE cid = in_cid;
RETURN TRUE;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN FALSE;
END;
--实现 add_product 过程
PROCEDURE add_product(in_name VARCHAR2, in_price NUMBER, in_address VARCHAR2 DEFAULT v_address)
IS
BEGIN
INSERT INTO product(pid, name, price, address)
VALUES(seq_product.nextval, in_name, in_price, in_address);
END;
--实现 del_category 过程
PROCEDURE del_category(in_cid NUMBER)
IS
BEGIN
DELETE FROM category WHERE cid = in_cid;
IF SQL%NOTFOUND THEN
raise_application_error(-20001,'该cid的商品类别不存在');
END IF;
END;
--实现 get_cname 函数
FUNCTION get_cname(in_cid NUMBER)
RETURN VARCHAR2
IS
v_cname VARCHAR(20);
BEGIN
IF check_fun(in_cid) THEN --调用私有组件
SELECT cname INTO v_cname FROM category WHERE cid = in_cid;
RETURN v_cname;
ELSE
raise_application_error(-20001,'该cid的商品类别不存在');
END IF;
END;
end;
3、包组件的调用
私有组件只能在包内调用,共用组件可以在包内调用、也可以在其它应用程序中调用,在其它应用程序中调用时,需要加上包名作为前缀(包名.组件名).
二、包重载
包重载指包内有多个相同名称的子程序.
需要注意2点:
1、同名的过程、函数必须有不同的输入参数
PROCEDURE del_category(in_cid NUMBER);
PROCEDURE del_category(in_cname VARCHAR2);
FUNCTION get_price(in_pid NUMBER) RETURN NUMBER;
FUNCTION get_price(in_name VARCHAR2) RETURN NUMBER;
2、同名的函数返回值数据类型必须一致