oracle 如何使用带条件的批量收集for循环

pftdvrlh  于 2023-11-17  发布在  Oracle
关注(0)|答案(2)|浏览(130)

我有一个要求,其中标题是重复的每一行从源表。我必须创建plsql过程插入到单独的标题和行表与共同的标识符。我目前使用简单的循环结构,如果否则条件,以保持唯一的标识符(invoiceid)在标题和行表

例如:源表

| Invnum|线型|量|lineNumber|
| --|--|--|--|
| 123 |项目| 100 | 1 |
| 123 |税| 20 | 2 |
| 446 |项目| 100 | 1 |
| 446 |项目| 100 | 2 |
| 446 |税| 20 | 3 |

头表

| 因维|Invasion| AMT|
| --|--|--|
| 100 | 123 | 120 |
| 101 | 446 | 220 |

线路表

| 因维|线型|量|lineNumber|
| --|--|--|--|
| 100 |项目| 100 | 1 |
| 100 |税| 20 | 2 |
| 101 |项目| 100 | 1 |
| 101 |项目| 100 | 2 |
| 101 |税| 20 | 3 |
我尝试用if else条件构造简单的forloop。但是还有更好的方法吗

ogq8wdun

ogq8wdun1#

我的理解是,你需要一个连接,而不是一个循环。
样本数据:

SQL> with
  2  source (invnum, linetype, amount, linenumber) as
  3    (select 123, 'ITEM', 100, 1 from dual union all
  4     select 123, 'TAX' ,  20, 2 from dual union all
  5     select 446, 'ITEM', 100, 1 from dual union all
  6     select 446, 'ITEM', 100, 2 from dual union all
  7     select 446, 'TAX' ,  20, 3 from dual
  8    ),
  9  header (invid, invnum, amt) as
 10    (select 100, 123, 120 from dual union all
 11     select 101, 446, 220 from dual
 12    )

字符串
生成该结果的查询:

13  select h.invid, s.linetype, h.amt, s.linenumber
 14  from header h join source s on s.invnum = h.invnum
 15  order by h.invid, s.linenumber;

     INVID LINE        AMT LINENUMBER
---------- ---- ---------- ----------
       100 ITEM        120          1
       100 TAX         120          2
       101 ITEM        220          1
       101 ITEM        220          2
       101 TAX         220          3

SQL>


如果它必须是PL/SQL过程,只需将这段代码移到那里;例如:

create or replace procedure p_line is
begin
  insert into line_table (invid, line, amt, linenumber)
  select h.invid, s.linetype, h.amt, s.linenumber
  from header h join source s on s.invnum = h.invnum;
end;
/


现在,您可以修改它并添加参数(“仅插入所需的invid行”)和类似的参数。

m3eecexj

m3eecexj2#

你可以使用两个insert。因为它们都查询同一个数据集,所以它们得到相同的invnum,你可以安全地使用DENSE_RANK(或者甚至ROW_NUMBER,当你按invnum聚合时)创建invid。

insert into header_table (invid, invnum, amt)
select
  row_number() over (order by invnum) + 99,
  invnum,
  sum(amount)
from source_table
group by invnum;

字符串

insert into line_table (invid, linetype, amount, linenumber)
select
  dense_rank() over (order by invnum) + 99,
  linetype,
  amount,
  linenumber
from source_table;


然而,冗余地存储数据并不是一个好主意,在头表中不应该有一个总金额,因为这个金额可以从行表条目中选择。
演示:https://dbfiddle.uk/_b78_f_S

相关问题