索引的plsql表类型正在抱怨

时间:2014-03-28 14:42:38

标签: oracle types plsql

PL / SQL: 意图:我的目的是通过使用key作为employee_id来访问作为光标下方的员工元组对象。

问题:我创建了一个游标 - * l_employees_cur *并且想要创建类型表,如下所示类型* l_employees_t *,如下所示,但编译器抱怨说 PLS-00315实现限制不支持表索引类型。

CURSOR l_employees_cur
  IS
    SELECT employee_id,manager_id,first_name,last_name FROM employees;
type l_employees_t
IS
  TABLE OF l_employees_cur%rowtype INDEX BY employees.employee_id%TYPE;

employees.employee_id的定义是:

EMPLOYEE_ID    NUMBER(6) NOT NULL

为什么我不能这样做?或者我做错了什么。

3 个答案:

答案 0 :(得分:2)

在PL / SQL集合中存储和检索SQL查询输出

OP中的示例看起来很像Oracle的新示例HR数据模式。 (对于那些知道,SCOTT-TIGER数据模型的继承者)的老人。此解决方案是在Oracle 11g R2实例上开发的。

演示表设计 - EMP

EMP table design

示范目标

此示例将说明如何从对象TYPE定义创建PL / SQL集合。复杂数据类型派生自以下游标定义:

 CURSOR l_employees_cur IS
    SELECT emp.empno as EMPLOYEE_ID, emp.mgr as MANAGER_ID, emp.ename as LAST_NAME
      FROM EMP;

将游标内容加载到索引收集变量后,存储过程的后半部分包含一个可选步骤,该步骤循环回到集合并通过DBMS_OUTPUT或INSERT DML操作显示数据另一张桌子。

存储过程示例源代码

这是用于查询演示表EMP的存储过程。

 create or replace procedure zz_proc_employee is

      CURSOR l_employees_cur IS
         SELECT emp.empno as EMPLOYEE_ID, emp.mgr as MANAGER_ID, emp.ename as LAST_NAME
           FROM EMP;

      TYPE employees_tbl_type IS TABLE OF l_employees_cur%ROWTYPE INDEX BY PLS_INTEGER;  

      employees_rec_var   l_employees_cur%ROWTYPE;
      employees_tbl_var   employees_tbl_type;

      v_output_string     varchar2(80);
      c_output_template   constant   varchar2(80):= 
         'Employee: <<EMP>>; Manager: <<MGR>>; Employee Name: <<ENAME>>'; 

      idx       integer;
      outloop   integer;

 BEGIN
      idx:= 1;
      OPEN l_employees_cur;
      FETCH l_employees_cur INTO employees_rec_var;

         WHILE l_employees_cur%FOUND LOOP

         employees_tbl_var(idx):= employees_rec_var;

         FETCH l_employees_cur INTO employees_rec_var;        

         idx:= idx + 1;
      END LOOP;

      CLOSE l_employees_cur;

 -- OPTIONAL (below) Output Loop for Displaying The Array Contents
 -- At this point, employees_tbl_var can be handed off or returned
 -- for additional processing.

 FOR outloop IN 1 .. idx LOOP
      -- Build the output string: 

      v_output_string:= replace(c_output_template, '<<EMP>>', 
          to_char(employees_tbl_var(outloop).employee_id));

      v_output_string:= replace(v_output_string, '<<MGR>>', 
          to_char(employees_tbl_var(outloop).manager_id));

      v_output_string:= replace(v_output_string, '<<ENAME>>', 
          employees_tbl_var(outloop).last_name);

      -- dbms_output.put_line(v_output_string);

      INSERT INTO zz_output(output_string, output_ts)
          VALUES(v_output_string, sysdate);

      COMMIT;

 END LOOP;

 END zz_proc_employee;

由于我无法控制的服务器配置问题,我注释了dbms_output电话。对输出表的备用insert命令是一种快速方法,可以直观地验证来自EMP表的数据是否成功地进入声明的集合变量。

解决方案的结果和讨论

调用过程并查询输出表后,这是我的输出:

EMP Collection Extracted Output Results

虽然在OP的非常简洁的细节中不清楚访问此表背后的实际目的,但我认为第一种方法是尝试理解集合和自定义数据类型的使用以实现高效的数据提取和从PL / SQL游标等结构处理。

此示例过程的一部分非常可重用,初始步骤表示制作和加载PL / SQL集合的工作方式。如果您注意到,即使您自己的此EMP表版本不同,唯一需要重新定义的地方就是光标本身。

由于其动态特性,使用类型,数组,嵌套表和其他集合类型实际上可以简化长期工作。

答案 1 :(得分:1)

来自Oracle Documenation:

关联数组

关联数组(以前称为PL / SQL表或索引表)是一组键值对。每个键都是唯一索引,用于使用语法variable_name(index)定位关联值。

索引的数据类型可以是字符串类型,也可以是PLS_INTEGER。索引按排序顺序存储,而不是创建顺序。对于字符串类型,排序顺序由初始化参数NLS_SORT和NLS_COMP确定。

答案 2 :(得分:0)

我认为你的错误是plsql表的声明。

为什么不试试下一个:

type l_employees_t
IS
  TABLE OF l_employees_cur%rowtype INDEX BY pls_integer;

我也有一个问题要问你: 上面代码中EMPLOYEE_ID NOT NULL NUMBER(6)的含义是什么?

问候 卡洛斯