在这个过程中我想插入userid
值不同,就像在这个select查询中我们插入所有数据一样。
T_ALLOCATIONCONFIG
表的内容:
id userid customerid subbatchtypeid
---- -------- ------------ ----------------
1 29 10003 1
1 30 10003 1
VW_BATCH
表的内容:
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
假设我们有来自vw_batch的10条记录,所以我想在userid = 29
表格中插入5条带有userid = 30
的记录和5条带有batchallocation
的记录。
如何编写查询或存储过程来插入这种结果?
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 :(得分: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;
/
N.B。未经测试,因为您没有提供表格定义或样本数据
另外,我不确定我回答了你原来的问题,因为我不明白。请更改您的问题,以便在表格中提供一些示例数据以及您希望以表格格式插入的内容。
好的,按照您的问题中添加的其他信息,我认为以下内容将会执行您的操作:
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;
/
N.B。您可能必须使用partition by
和join子句来确保数据被分组并在正确的列上连接 - 我猜测了逻辑背后的原因,因为您没有说。希望您能够解构查询以查看它正在做什么,并在适当时进行修改!