PL / SQL使用Employee Id作为密钥创建关联数组

时间:2014-08-21 15:51:25

标签: oracle plsql oracle11g associative-array

我正在尝试创建一个哈希,其中employee_id (NUMBER(6,0))为关键字,salary (NUMBER(8,2))为值。

为此,我使用以下定义在PL / SQL(Oracle 11g)中创建了一个INDEX-OF表(关联数组):

TYPE emp_title_hash IS TABLE OF employees.salary%type 
                       INDEX BY employees.employee_id%type;

我收到以下编译错误:

Error(22,28): PLS-00315: Implementation restriction: unsupported table index type

我知道在这种情况下,索引唯一受支持的类型是STRINGPLS_INTEGER。这似乎是非常严格的限制。为什么在Oracle中强加了这个?有没有工作来完成上述工作?

感谢您的意见/建议。

1 个答案:

答案 0 :(得分:1)

正如有人已经指出的那样,你可以使用“index by pls_integer”,因为pls_integer可以包含任何数字(6,0)值。

当然能够使用任何可能的类型索引pl / sql关联数组会很好,但我总是设法编写一个函数来构建一个字符串,该字符串标识我想要用作的对象实例指数值。

所以,而不是写作:

 type TMyAssociativeArray is table of MyDataType index by MyIndexType;

我写道:

  Type TMyAssociativeArray is table of MyDataType index by varchar2(30);

然后我编写了一个从MyIndexType计算唯一字符串的函数:

function GetHash(obj MyIndexType) return varchar2;

并且,编写了这个函数后,我可以用它来模拟MyIndexType对象索引的关联数组:

所以我可以写

 declare
     arr TMyAssociativeArray;
     obj TMyDataType;
     idx TMyDataType;
 begin 
     ....
     arr(GetHash(idx)) := obj;
 end;

在这里,我摆脱了您提出的严格问题,并向您提供有关获得快速客户的可能其他方式的建议 - >薪资查询缓存...这是您的关联数组问题的最终目的,正如我可以从你的评论中读到的,所以也许这可能有用:

如果您正在使用关联数组来构建快速查找机制,并且如果您可以使用oracle 11g R2新功能,获得此缓存的更简单方法是依赖本机RESULT_CACHE功能已经为查询(通过使用RESULT_CACHE提示)和pl / sql函数引入。

对于pl / sql函数,您可以创建一个结果值缓存的函数,如下所示:

 create or replace function cached_employee_salary(employee number) 
 return number RESULT_CACHE is
     result number;
 begin
    select salary 
    into result 
    from employees e
    where e.code = employee;
    return result;
 end;

RESULT_CACHE关键字指示oracle保留结果值的内存缓存,并在后续调用中重用它们(当使用相同的参数调用函数时)。

与使用关联数组相比,

这种缓存具有以下优势:

  1. 它在所有会话之间共享:缓存数据不保存在为每个会话分配的专用内存中,因此浪费的内存较少
  2. oracle足够聪明,可以通过访问employees表来检测该函数计算结果,并在修改表数据时自动使缓存的结果无效。
  3. 当然,我建议你进行一些测试,看看这种优化是否会给你带来一些切实的结果。它主要取决于你在函数中计算的复杂程度。

    您还可以依赖为SQL查询引入的类似功能,由/ + RESULT_CACHE /提示触发:

        select /*+RESULT_CACHE*/
                salary 
        from employees e
        where e.code = employee;
        return result
    

    此提示指示oracle存储和重用(在后续执行时)查询的结果集。它也会存储在内存中。 实际上,这个提示还具有以下优点:作为提示 - 从语义上讲 - 一个特殊的注释,这个查询将继续工作,即使在服务器上也没有任何修改< 11gR2,而对于函数缓存版本,你应该使用一些“条件编译”魔术来使它与以前的服务器版本一起编译(对于它而言,它将是一个没有任何结果缓存的普通函数)

    我希望这有帮助。