我有两个包pkg_company和pkg_employee. pkg_company包含(记录)类型定义typ_company. pkg_employee包含类型定义typ_employee.
我有一个公司类型的实例和1000个typ_employee实例.在员工类型中,我希望有一个指向公司实例的指针.
declare c pkg_company.typ_company; e pkg_employee.typ_employee; begin c := pkg_company.get(12345); for e in (select employeeid from employee where companyid=12345) loop e := pkg_employee.get(12345,c); -- c passed by reference in out nocopy pkg_employee.process(e); -- I would like to access company info inside here as e.c.companyname end loop; end;
如何在e中存储指向c的指针?我不想创建1000的c副本.只是想存储指针并在需要时访问该值.
感谢您的帮助!
结束;
解决方法
在Oracle sql中,use
但是PL / sql中没有指针或引用这样的东西,所以你需要一个解决方法.
REF
and DEREF
functions可以将逻辑指针传递给存储在数据库表中的对象.
但是PL / sql中没有指针或引用这样的东西,所以你需要一个解决方法.
下面介绍PL / sql中可能的解决方法.我提前为代码中的任何错误道歉.它的目的是展示方法,而不是用于生产.
通用的想法是通过缓存结果的函数访问实体:
create or replace package EntitytAccess as procedure GetCompany1( pCompanyId in number,pCompany out nocopy pkg_company.typ_company ); function GetCompany2( pCompanyId in number ) return pkg_company.typ_company; procedure ClearCompanyCache; end;
访问包体:
create or replace package body EntitytAccess as type typ_company_cache is table of pkg_company.typ_company index by number; var_company_cache typ_company_cache; procedure GetCompany1( pCompanyId in number,pCompany out nocopy pkg_company.typ_company ) is begin if( var_company_cache.exists(pCompanyId) ) pCompany := var_company_cache(pCompanyId); else pCompany := pkg_company.get(pCompanyId); var_company_cache(pCompanyId) := pCompany; end if; end; function GetCompany2( pCompanyId in number ) return pkg_company.typ_company is begin if(not var_company_cache.exists(pCompanyId) ) var_company_cache(pCompanyId) := pkg_company.get(pCompanyId); end if; return var_company_cache(pCompanyId); end; procedure ClearCompanyCache is begin var_company_cache.Delete; end; end;
用法:
declare c pkg_company.typ_company; e pkg_employee.typ_employee; begin EntityAccess.GetCompany2(12345,c); for e in (select employeeid from employee where companyid=12345) loop e := pkg_employee.get(12345,c); -- c passed by reference in out nocopy -- and c.companyid stored inside e. pkg_employee.process(e); -- No need to pass company,but inside process() -- method you need to call either -- EntityAccess.GetCompany1(e.companyid,var_c) -- or -- var_c := EntityAccess.GetCompany2(e.companyid) end loop; end;
方法2 – 环境包
由于包状态属于一个会话,因此您可以使用包变量来保存当前处理状态并在需要时引用它.
create or replace package ProcessEnvironment as var_current_company pkg_company.typ_company; -- may be more "global" variables here end; / create or replace package body ProcessEnvironment as end;
用法:
declare e pkg_employee.typ_employee; begin ProcessEnvironmant.var_current_company := pkg_company.get(12345); for e in (select employeeid from employee where companyid=12345) loop e := pkg_employee.get(12345,ProcessEnvironmant.var_current_company); -- c passed by reference in out nocopy -- and c.companyid stored inside e. pkg_employee.process(e); -- No need to pass company,but inside process() -- method you references -- ProcessEnvironmant.var_current_company -- with appropriate checks end loop; end;
混合的方法
似乎在方法1实例中从集合中复制了实例,尤其是在使用函数GetCompany2()访问时.复制构造函数可能足够快但产生一些开销.
对于方法2,在业务逻辑功能的代码中必须存在一些检查,因此从另一个角度来看它是维护开销.
要处理这两个问题,您可以使用缓存,但在包中只保留一个值:
create or replace package EntitytAccess as procedure GetCompany( pCompanyId in number,pCompany out nocopy pkg_company.typ_company ); end;
包装体:
create or replace package body EntitytAccess as var_cached_company pkg_company.typ_company; procedure GetCompany( pCompanyId in number,pCompany out nocopy pkg_company.typ_company ) is begin if( (var_cached_company is null) or (var_cached_company.comanyid != pCompanyId) )then var_company_cache := pkg_company.get(pCompanyId); end if; pCompany := var_cached_company; end; end;
用法:
declare c pkg_company.typ_company; e pkg_employee.typ_employee; begin EntityAccess.GetCompany(12345,c); for e in (select employeeid from employee where companyid= c.companyid) loop e := pkg_employee.get(c.companyid,c); -- c passed by reference in out nocopy -- and c.companyid stored inside e. pkg_employee.process(e); -- No need to pass company,but inside process() -- method you need to call -- EntityAccess.GetCompany(e.companyid,var_c) -- where var_c is company object variable. end loop; end;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。