拆分多列分号分隔的字符串并创建记录
Posted
技术标签:
【中文标题】拆分多列分号分隔的字符串并创建记录【英文标题】:Split multi column semicolon separated string and create records 【发布时间】:2012-11-21 08:38:39 【问题描述】:我有一个接收三个字符串参数的存储过程
1. p_ReqIDs VARCHAR2
2. p_ItemIDs VARCHAR2
3. p_Qtys VARCHAR2
以上 3 个字符串变量包含分号分隔的值,如下所示:
p_ReqIDs := "56;56;56;"
p_ItemIDs := "3;2;1;"
p_Qtys := "400;300;200;"
我需要像这样拆分值并创建行:
p_ReqIDs p_ItemIDs p_Qtys
------------------------------------
56 3 400
56 2 300
56 1 200
我还需要拆分并插入表格的查询。
谢谢
【问题讨论】:
【参考方案1】:您可以按如下方式处理参数:
SQL> declare
2 type l_rec_type is record(
3 r_ReqIDs varchar2(31),
4 r_ItemIDs varchar2(31),
5 r_Qtys varchar2(31)
6 );
7
8 type l_rec_list is table of l_rec_type;
9 -- your parameters.
10 l_ReqIDs constant varchar2(31) := '56;56;56;';
11 l_ItemIDs constant varchar2(31) := '3;2;1;';
12 l_Qtys constant varchar2(31) := '400;300;200;';
13
14 l_rec l_rec_list;
15 begin
16
17 with Parameters(param) as(
18 select l_ReqIDs from dual union all
19 select l_ItemIDs from dual union all
20 select l_Qtys from dual
21 ),
22 Occurrences(oc) as(
23 select level
24 from ( select max(regexp_count(param, '[^;]+')) moc
25 from parameters) s
26 connect by level <= s.moc
27 )
28 select max(res1)
29 , max(res2)
30 , max(res3)
31 bulk collect into l_rec
32 from (select decode(param, l_ReqIDs, res) res1
33 , decode(param, l_ItemIDs,res) res2
34 , decode(param, l_Qtys, res) res3
35 , rn
36 from ( select param, regexp_substr(param, '[^;]+', 1, o.oc) res
37 , row_number() over(partition by param order by param) rn
38 from parameters p
39 cross join occurrences o
40 )
41 )
42 group by rn;
43
44 for i in l_rec.first..l_rec.last
45 loop
46 dbms_output.put_line(l_rec(i).r_ReqIDs || ' ' || l_rec(i).r_ItemIDs || ' ' || l_rec(i).r_Qtys);
47 end loop;
48 end;
49 /
56 2 200
56 1 300
56 3 400
PL/SQL procedure successfully completed
如果您只需要将处理后的数据插入表中,则只需要 insert into
语句和查询(bulk collect into l_rec
必须删除):
insert into your_table(<<columns>>)
with Parameters(param) as(
select l_ReqIDs from dual union all
select l_ItemIDs from dual union all
select l_Qtys from dual
....
-- the rest of the query from the above pl/sql block.
您还可以将整条记录插入到表中(如果您需要在插入之前对提取的元素进行额外处理),如下所示:
如果表中的列数等于插入的元素数
for i in l_rec.first..l_rec.last
loop
insert into your_table
values l_rec(i);
end loop;
如果表中的列数大于插入的值数
for i in l_rec.first..l_rec.last
loop
insert into (select column1, .. ,columnn from your_table)
values l_rec(i);
end loop;
【讨论】:
【参考方案2】:我确实喜欢这个 :) 简短而甜蜜。
create or replace procedure proc1(p_ReqID varchar2,p_ItemID varchar2,p_ItemQty varchar2)
is
begin
insert into test(req_id,item_id,itemqty)
select regexp_substr(req_id,'[^;]+',1,level),
regexp_substr(item_id,'[^;]+',1,level),
regexp_substr(item_qty,'[^;]+',1,level)
from (
select p_ReqID Req_ID,p_ItemID item_id,p_ItemQty item_qty
from dual
)
connect by regexp_substr(req_id,'[^;]+',1,level) is not null;
end;
【讨论】:
是的,它更短。您只需要在connect by
子句中为每个参数添加OR
条件,以防第二个或第三个等参数具有比第一个更多的元素。否则你可能会丢失有价值的信息:)
Nicholas 在我的情况下它永远不会发生,因为我正在提取相同 REQ_ID 的详细记录并传递给 Oracle 的 .NET Web 服务。所以所有的列总是有相同的值:)以上是关于拆分多列分号分隔的字符串并创建记录的主要内容,如果未能解决你的问题,请参考以下文章
Pandas使用split函数基于指定分隔符拆分数据列的内容为列表设置expand参数将拆分结果列表内容转化为多列数据并添加到原数据中replace函数基于正则表达式替换字符串数据列中的匹配内容
Pandas使用split函数基于指定分隔符拆分数据列的内容为列表设置参数n控制拆分的次数设置expand参数将拆分结果列表内容转化为多列dataframe并添加到原dataframe中
Pandas使用str属性获取数据列的字符串方法类split函数基于指定分隔符拆分数据列的内容为列表设置参数n控制拆分的次数设置expand参数将拆分结果列表内容转化为多列dataframe