plsql中的所有光标都在里面

时间:2015-01-13 15:08:15

标签: sql oracle plsql

我正在写一个包如下: -

create or replace package body pack_name
    is 

    cursor is cur_get_data(p_run_id)
    is 
    select p_run_id run_id,
    person_id ,
    emp_name 
    from abc;


     TYPE demo_table_type IS TABLE OF get_demo_data%ROWTYPE;

       demo_table                         demo_table_type;

    procedure demo_data(p_data_array      IN     demo_table_type)
    is 

    cursor is cur_get_person(p_person_id number)
    is 
    select tot_comp_annual 
    from xyz;

    begin

     FORALL j IN 1 .. p_data_array.COUNT SAVE EXCEPTIONS
        insert    
      INTO table_bad  (run_id,  person_id,emp_name)
     VALUES (p_data_array (j).run_id,
                           p_data_array (j).person_id,
                           p_data_array (j).emp_name);


    end;

现在的问题是我想打开cur_get_person并传递我从p_data_array(j).person_id获取的person_id,并在table_bad的列annual_comp中插入该值。我怎样才能做到这一点 ?

2 个答案:

答案 0 :(得分:2)

最简单的答案是不使用游标。而是将select xyz构建到insert语句中。通常,应避免在游标循环内打开游标;加入的是什么。

CREATE OR REPLACE PACKAGE BODY pack_name IS
   CURSOR cur_get_data (p_run_id NUMBER) IS
      SELECT p_run_id run_id, person_id, emp_name FROM abc;


   TYPE demo_table_type IS TABLE OF get_demo_data%ROWTYPE;

   demo_table demo_table_type;

   PROCEDURE demo_data (p_data_array IN demo_table_type) IS
   BEGIN
      FORALL j IN 1 .. p_data_array.COUNT SAVE EXCEPTIONS
         INSERT INTO table_bad (run_id,
                                person_id,
                                emp_name,
                                tot_comp_annual)
            SELECT p_data_array (j).run_id,
                   p_data_array (j).person_id,
                   p_data_array (j).emp_name,
                   tot_comp_annual
            FROM   xyz
            WHERE  xyz.person_id = p_data_array (j).person_id;
   END;
END;

答案 1 :(得分:1)

你不能直接引用光标,甚至不能通过另一个集合间接引用(产生内部错误,除非我做错了)。 Allan展示了如何使用光标查询与集合相结合,但是你似乎在做什么似乎根本不需要PL / SQL,我假设你只是在试验并试图结合东西以有意思的方式故意所以这是一种继续该主题的方法,并使用你的光标:

  procedure demo_data(p_data_array IN demo_table_type) is 

    cursor get_person_info is
      select person_id, tot_comp_annual
      from xyz;

    type comp_table_type is table of xyz.tot_comp_annual%type
      index by pls_integer;
    comp_table comp_table_type;

    type bad_table_type is table of table_bad%rowtype;
    bad_table bad_table_type := bad_table_type();
  begin

    -- intentioanlly convoluted, since the whole idea is; get all the
    -- info into another PL/SQL table
    for r in get_person_info loop
      comp_table(r.person_id) := r.tot_comp_annual;
    end loop;

    -- merge the two existing tables into a third with all the columns
    bad_table.extend(p_data_array.count);
    for j in 1 .. p_data_array.count loop
      bad_table(j).run_id := p_data_array(j).run_id;
      bad_table(j).person_id := p_data_array(j).person_id;
      bad_table(j).emp_name := p_data_array(j).emp_name;
      if comp_table.exists(p_data_array(j).person_id) then
        bad_table(j).tot_comp_annual :=
          comp_table(p_data_array(j).person_id);
      end if;
    end loop;

    forall j in 1 .. bad_table.count save exceptions
      insert into table_bad values bad_table(j);

  end demo_data;

这将创建一个本地PL / SQL表,其中所有get_person_info行都被批量提取。您也不能直接在forall中使用它。但是您可以拥有第三个基于目标表的PL / SQL表,并从p_data_array和包含游标数据的集合中填充该表。这也简化了forall,因为您可以一次性插入整行。

SQL Fiddle demo