• LightDB中的存储过程(八)—— 包


    LightDB支持存储过程,除了支持Postgres的plpgsql存储过程,还兼容Oracle的存储过程,新增了plorasql过程语言。上一篇中我们介绍了存储过程中的子程序,这一篇主要讲述存储过程中的包。

    什么是包(package)?

    包用于将相关的PL/SQL元素(过程、函数、变量、常量、自定义数据类型、游标等)组织在一起,作为一个完整的逻辑单元,编译后存储在数据库服务器中,作为一种全局的模式对象,供应用程序共享。

    包由包规范和包体两部分组成,在数据库中独立存储。其中包规范声明了包中的所有公共元素,这些公共元素可以在包的外部被引用。如果包规范中声明了存储过程,则需要在包体中实现。在包体中,还可以定义私有元素,这些私有元素只能在包内部引用,而不能在包的外部引用。

    除了包规范和包体的概念,还有内置包、用户包的区别,内置包不是用户定义的包,而是数据库本身提供的,用户可以不用创建,直接调用内置包。LightDB中本身也提供部分内置包,可以到官网去查看。而用户包就是用户自己创建的包。

    好了,下面我们看一下如何创建包吧。

    创建包

    创建包可通过CREATE PACKAGE 语法创建,包括创建包规范,创建包体两部分。其中,包规范声明了包中的公共元素,如过程、函数、游标、数据类型、变量等。这些公共元素的作用域为包所在的模式。在包规范中声明的元素不仅可以在包的内部使用,也可以被应用程序调用。另外包可以支持重载子程序(即包中的子程序允许具有相同的名称,但具有不同的形式参数)。

    示例如下:

    create or replace package changan    -- CREATE PACKAGE 创建包规范
    is
    	procedure shenlan;  -- 声明一个存储过程
    end;
    /
    
    create or replace package body changan   -- CREATE PACKAGE BODY 创建包体
    is
    	procedure shenlan
    	is
    		begin
    			raise notice 'hello changan shenlan sl03';
    		end;
    	end;
    end;
    /
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    包中支持重载子程序:

    create or replace package changan    -- CREATE PACKAGE 创建包规范
    is
    	procedure shenlan;  -- 声明一个存储过程
    	procedure shenlan(a int);	-- 重载子程序
    end;
    /
    
    create or replace package body changan   -- CREATE PACKAGE BODY 创建包体
    is
    	procedure shenlan
    	is
    		begin
    			raise notice 'hello changan shenlan sl03';
    		end;
    	end;
    
    	procedure shenlan(a int)  -- changan为模式名,shenlan为存储过程名
    	is
    	begin	
    		raise notice '%', a;		-- 通过下标访问联合数组
    	end;
    end;
    /
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    其中, OR REPLACE表示如果包已经存在,则重建包。如果包规范中声明了游标或子程序,那么必须创建对应的包体,否则包体是可选的。包体与包规范必须同名且放在同一个模式中。

    create or replace package changan
    is
    	TYPE xxRec IS RECORD (x char, y int);  -- 类型定义
    	-- 没有子程序以及游标,不必创建包体
    end;
    /
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    包体中还可以包含包规范中没有声明的变量、游标、类型、过程和函数等,但他们是私有元素,只能由同一包中的过程或函数使用。示例如下:

    create or replace package pkgtb
    as
    	procedure show;
    	procedure show(a int);
    end;
    /
    create or replace package body pkgtb
    as
    	v int := 10;
    	procedure show
    	is
    	begin
    		for v in (select b from t1) loop
    			raise notice 'show1: %', v;
    		end loop;
    	end;
    	
    	procedure show(a int)
    	is
    	begin
    		for v in (select b from t1) loop
    			raise notice 'show2: %', v;
    		end loop;
    	end;
    
    	procedure privshow
    	is
    	begin
    		raise notice 'package private procedure';
    	end;
    end;
    /
    
    -- 不能在包外调用私有元素
    postgres@postgres=# call pkgtb.privshow;
    ERROR:  package private procedure ("pkgtb.privshow") is not accessible
    LINE 1: call pkgtb.privshow;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    创建包体需要注意下面几项:

    • 包体中函数和过程的原型必须与包规范中的声明完全一致
    • 只有在已经创建包规范的情况下,才可以创建包体
    • 如果包规范中不包含任何游标、函数或过程的声明,则可以不创建包体

    最后,还有一个细节,就是包的构造函数,如果没有声明构造函数,则会默认添加如下为构造函数。

    begin
    	null;
    end;
    
    • 1
    • 2
    • 3

    也可以用户自己定义构造函数:

    create or replace package changan    -- CREATE PACKAGE 创建包规范
    is
    	procedure shenlan;  -- 声明一个存储过程
    end;
    /
    
    create or replace package body changan   -- CREATE PACKAGE BODY 创建包体
    is
    	procedure shenlan
    	is
    		begin
    			raise notice 'hello changan shenlan sl03';
    		end;
    	end;
    
    --  构造函数
    begin
    	raise notice 'package constructor function.';
    end;
    
    end;
    /
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    包的调用

    包的调用很简单,与存储过程/函数的调用类似。这里不再细述,可参考LightDB中的存储过程(七)

    create or replace package changan    -- CREATE PACKAGE 创建包规范
    is
    	procedure shenlan;  -- 声明一个存储过程
    end;
    /
    
    create or replace package body changan   -- CREATE PACKAGE BODY 创建包体
    is
    	procedure shenlan
    	is
    		begin
    			raise notice 'hello changan shenlan sl03';
    		end;
    	end;
    end;
    /
    
    --包的调用
    postgres@postgres=# call changan.shenlan;
    NOTICE:  hello changan shenlan sl03
    CALL
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    这里需要注意:在包规范中声明的任何元素都是公有的,在包外部可见,可通过package-name.element的形式进行调用,在包体中可以直接通过元素名调用。但是,在包体中定义而没有在包规范中声明的元素是私有的,包外无法访问,只能包内调用。

    更多请参考LightDB官网

  • 相关阅读:
    基于UDP丢包统计程序设计
    java ssm企业图书借阅职工书屋系统
    Redis——》过期删除策略
    财报解读:将低价作为“唯一性基础武器”的京东,效果在慢慢显现
    如果一定要在C++和JAVA中选择,是C++还是java?
    heatmap | cell cycle genes in Seurat
    Android/Automotive 多声道录音支持
    MQ简单入门案例
    SAP 选择屏幕动态通过Radio Button 显示与隐藏以及控制是否必输
    【网络原理】基本原理篇:I/O
  • 原文地址:https://blog.csdn.net/s_lisheng/article/details/126122447