2015-12-02 184 views
-1

在这个程序中我想插入userid的值是不一样的,就像在这个select查询中我们插入所有的数据一样。如何在Oracle 11g中使用游标在表中插入数据?

T_ALLOCATIONCONFIG表的内容:VW_BATCH

id userid customerid subbatchtypeid 
---- -------- ------------ ---------------- 
1 29  10003  1 
1 30  10003  1 

内容:

batchid batchname subbatchtypeid customerid batchstatus_id 
--------- ----------- ---------------- ------------ ---------------- 
1   test  1    10003  1 
2   test1  1    10003  1 
3   test2  1    10003  1 
4   test3  1    10003  1 
5   test4  1    10003  1 
6   test5  1    10003  1 
7   test6  1    10003  1 
8   test7  1    10003  1 
9   test8  1    10003  1 
10  test9  1    10003  1 
11  test12  1    10003  1 

我想在T_BATCHALLOCATION表这种类型的结果:

id batchid customerid userid 
---- --------- ----------- -------- 
1 1   10003  29 
2 2   10003  29 
3 3   10003  29 
4 4   10003  29 
5 5   10003  29 
6 6   10003  30 
7 7   10003  30 
8 8   10003  30 
9 9   10003  30 
10 10  10003  30 

假设我们有10个记录从vw_batch,所以我想插入5记录机智h userid = 29userid = 30batchallocation表中的5条记录。

如何编写查询或存储过程来插入这种结果?

CREATE OR REPLACE PROCEDURE p_autoallocate_batches 
AS 
    BEGIN 
    DECLARE 
     --  v_coll_rules_id coll_rules.coll_rules_id%TYPE; 
     v_customer_id t_customers.customer_id%TYPE; 
     v_batchid  t_batch.batchid%TYPE; 
     v_user_id  t_users.user_id%TYPE; 
     c    types.cursortype; 

     CURSOR c_aa IS 
     SELECT b.customer_id, 
       b.batchid, 
       a.user_id 
     FROM vw_batch b 
     JOIN t_allocationconfig a 
      ON a.customer_id = b.customer_id 
     AND a.subbatchtypeid = b.subbatchtypeid 
     WHERE b.batchstatus = 'New' AND a.isactive = 'Y'; 

    BEGIN 
     -- Dbms_Output.Put_Line('Hello World'); 
     -- Insert Into Tmp (Column1) Values ('Started'); 

     OPEN c_aa; 

     LOOP 
     FETCH c_aa INTO v_customer_id, v_batchid, v_user_id; 
     EXIT WHEN c_aa%NOTFOUND; 

     IF (v_customer_id > 0 AND v_batchid > 0 AND v_user_id > 0) THEN 
      INSERT INTO t_batchallocation (customer_id, batchid, user_id, created_by, created_date) 
      VALUES (v_customer_id, v_batchid, v_user_id, 1, sysdate); 

      UPDATE t_batch 
      SET batchstatus_id = 2, modified_by = 1, modified_date = sysdate 
      WHERE batchid = v_batchid; 
     END IF; 

     --Insert Into Tmp (Column1) Values ('Started123'); 

     COMMIT; 
     END LOOP; 

     CLOSE c_aa; 

    END; 
    END; 
+0

你真的需要在** PL/SQL **中做到吗?我认为你可以使用** MERGE **语句在纯** SQL **中一步完成。 –

+0

请给我例子使用MERGE。是我需要在oracle sql developer –

+0

SQL Developer是一个工具。 SQL是一种语言。无论如何,只要在网站上搜索MERGE语句,就会得到大量的例子。 –

回答

3

有没有必要使用游标来做到这一点 - 你可以做到这一点在两个SQL语句像这样(但你必须创建一个类来保存插入的batch_ids):

create type num_list as table of integer; 

create or replace procedure p_autoallocate_batches 
as 
    v_batch_ids num_list; 
begin 
    insert into t_batchallocation (customer_id, 
           batchid, 
           user_id, 
           created_by, 
           created_date) 
    select b.customer_id, 
     b.batchid, 
     a.user_id, 
     1, 
     sysdate 
    from vw_batch b 
     inner join t_allocationconfig a on (a.customer_id = b.customer_id 
              and a.subbatchtypeid = b.subbatchtypeid) 
    where b.batchstatus = 'New' 
    and a.isactive = 'Y' 
    and b.customer_id > 0 
    and b.batchid > 0 
    and a.user_id > 0 
    returning batchid bulk collect into v_batch_ids; 

    update t_batch 
    set batchstatus_id = 2, modified_by = 1, modified_date = sysdate 
    where batchid in (select * from table(v_batch_ids)); 

    commit; 

end p_autoallocate_batches; 
/

NB未经测试,因为您没有提供表格定义或样本数据

此外,我不确定我是否回答了您原来的问题,因为我不明白。请修改您的问题,以便在表格中提供一些示例数据,并以表格格式插入您想要的内容。


好吧,下面加入到你的问题的其他信息,我觉得下面会做你以后:

with t_allocationconfig as (select 1 id, 29 userid, 10003 customerid, 1 subbatchtypeid from dual union all 
          select 1 id, 30 userid, 10003 customerid, 1 subbatchtypeid from dual), 
       vw_batch as (select 1 batchid, 'test' batchname, 1 subbatchtypeid, 10003 customerid, 1 batchstatus_id from dual union all 
          select 2 batchid, 'test1' batchname, 1 subbatchtypeid, 10003 customerid, 1 batchstatus_id from dual union all 
          select 3 batchid, 'test2' batchname, 1 subbatchtypeid, 10003 customerid, 1 batchstatus_id from dual union all 
          select 4 batchid, 'test3' batchname, 1 subbatchtypeid, 10003 customerid, 1 batchstatus_id from dual union all 
          select 5 batchid, 'test4' batchname, 1 subbatchtypeid, 10003 customerid, 1 batchstatus_id from dual union all 
          select 6 batchid, 'test5' batchname, 1 subbatchtypeid, 10003 customerid, 1 batchstatus_id from dual union all 
          select 7 batchid, 'test6' batchname, 1 subbatchtypeid, 10003 customerid, 1 batchstatus_id from dual union all 
          select 8 batchid, 'test7' batchname, 1 subbatchtypeid, 10003 customerid, 1 batchstatus_id from dual union all 
          select 9 batchid, 'test8' batchname, 1 subbatchtypeid, 10003 customerid, 1 batchstatus_id from dual union all 
          select 10 batchid, 'test9' batchname, 1 subbatchtypeid, 10003 customerid, 1 batchstatus_id from dual union all 
          select 11 batchid, 'test12' batchname, 1 subbatchtypeid, 10003 customerid, 1 batchstatus_id from dual) 
--end of mimicking your sample data - see SQL below: 
select vb.batchid id, -- is id supposed to be derived using a sequence, perhaps? 
     vb.batchid, 
     vb.customerid, 
     ta.userid 
from (select id, 
       userid, 
       customerid, 
       subbatchtypeid, 
       row_number() over (partition by id, customerid, subbatchtypeid order by userid) rn, 
       count(*) over (partition by id, customerid, subbatchtypeid) cnt 
     from t_allocationconfig) ta 
     inner join (select batchid, 
          batchname, 
          subbatchtypeid, 
          customerid, 
          batchstatus_id, 
          row_number() over (partition by customerid, subbatchtypeid order by batchid) rn, 
          count(*) over (partition by customerid, subbatchtypeid) cnt 
        from vw_batch) vb on (ta.customerid = vb.customerid 
              and ta.subbatchtypeid = vb.subbatchtypeid 
              and ta.rn = ceil(vb.rn/ceil(vb.cnt/ta.cnt))); 

     ID BATCHID CUSTOMERID  USERID 
---------- ---------- ---------- ---------- 
     1   1  10003   29 
     2   2  10003   29 
     3   3  10003   29 
     4   4  10003   29 
     5   5  10003   29 
     6   6  10003   29 
     7   7  10003   30 
     8   8  10003   30 
     9   9  10003   30 
     10   10  10003   30 
     11   11  10003   30 

这意味着你的代码应该是沿东西线作者:

-- make sure you have a global type: 
create type num_list as table of integer; 

create or replace procedure p_autoallocate_batches 
as 
    v_batch_ids num_list; 
begin 
    insert into t_batchallocation (customer_id, 
           batchid, 
           user_id, 
           created_by, 
           created_date) 
    select vb.customerid, 
     vb.batchid, 
     ta.userid, 
     1, 
     sysdate 
    from (select id, 
       userid, 
       customerid, 
       subbatchtypeid, 
       row_number() over (partition by id, customerid, subbatchtypeid order by userid) rn, 
       count(*) over (partition by id, customerid, subbatchtypeid) cnt 
      from t_allocationconfig) ta 
     inner join (select batchid, 
          batchname, 
          subbatchtypeid, 
          customerid, 
          batchstatus_id, 
          row_number() over (partition by customerid, subbatchtypeid order by batchid) rn, 
          count(*) over (partition by customerid, subbatchtypeid) cnt 
        from vw_batch) vb on (ta.customerid = vb.customerid 
              and ta.subbatchtypeid = vb.subbatchtypeid 
              and ta.rn = ceil(vb.rn/ceil(vb.cnt/ta.cnt))) 
    returning batchid bulk collect into v_batch_ids; 

    update t_batch 
    set batchstatus_id = 2, modified_by = 1, modified_date = sysdate 
    where batchid in (select * from table(v_batch_ids)); 

    commit; 

end p_autoallocate_batches; 
/

NB你可能不得不玩弄partition by并加入子句,以确保数据被分组并加入到正确的列中 - 我猜测了它背后的逻辑是什么,因为你没有说。希望你能够解构查询,看看它在做什么,并根据需要进行修改!

+0

thx boneist为您的答复,但它不能解决我的问题我读你不明白我的问题,所以我可以编辑我的问题,如果你知道然后回复它非常紧迫 –

+1

你需要提供相应的数据从你的vw_batch,连同您希望看到的数据。请记住,我们无法看到您的屏幕,所以如果您希望我们帮助您,您需要提供尽可能多的信息,以便我们可以复制您的数据等并针对它执行查询。 – Boneist

+0

@DipalKothari我已经更新了我的答案,以包含SQL语句,我相信你做了之后,假设我理解你的需求当然!感谢您将信息添加到问题中 - 这让我们更容易看到您想要实现的目标! – Boneist

相关问题