如何在 PL/SQL 中解析逗号分隔的字符串? [复制]
Posted
技术标签:
【中文标题】如何在 PL/SQL 中解析逗号分隔的字符串? [复制]【英文标题】:How to parse comma delimited string in PL/SQL? [duplicate] 【发布时间】:2011-10-25 01:55:08 【问题描述】:我在 PL/SQL 脚本中有一个逗号分隔的字符串(例如 data:= 'a,b,c,d,e'),我需要在脚本中解析出来。
我想遍历字符串并处理每个项目。就像一个“foreach”循环。
这在 PL/SQL 中可能吗?有人可以指点我一些代码吗?
【问题讨论】:
看看@TonyAndrews 博客:tonyandrews.blogspot.com/2004/10/… @StevieG - 您应该将其发布为答案。我会赞成它 StevieG,这行得通。请将其添加为我的问题的答案,以便我接受并投票。 完成。感谢您的及时回复。 这里概述了另一种技术blogs.oracle.com/aramamoo/entry/… 基本上使用regexp_substr。 【参考方案1】:如果您使用的是 Oracle 10G 或 11G,那么您应该有一个内置的 Apex 函数apex_util.string_to_table
:
SQL> declare
2 v_array apex_application_global.vc_arr2;
3 v_string varchar2(2000);
4 begin
5
6 -- Convert delimited string to array
7 v_array := apex_util.string_to_table('alpha,beta,gamma,delta', ',');
8 for i in 1..v_array.count
9 loop
10 dbms_output.put_line(v_array(i));
11 end loop;
12
13 -- Convert array to delimited string
14 v_string := apex_util.table_to_string(v_array,'|');
15 dbms_output.put_line(v_string);
16 end;
17 /
alpha
beta
gamma
delta
alpha|beta|gamma|delta
PL/SQL procedure successfully completed.
【讨论】:
似乎 11G 并不总是内置这个。我收到一个错误,告诉我必须定义 apex_application_global.vc_arr2。 @Adam 在旧版本中可能称为htmldb_application_global
。【参考方案2】:
对于基本的逗号分隔字符串。执行下面的程序,它旨在一次将记录减少一段。当p_input_string = p_output_value
完成时。默认为逗号,但您可以传入不同的分隔符parse_delimited_string(V_string, v_value, ';');
--- 分号分隔
create or replace procedure parse_delimited_string(P_INPUT_STRING IN OUT VARCHAR2,
P_OUTPUT_VALUE OUT VARCHAR2,
P_DELIMITOR IN VARCHAR2 DEFAULT ',')
is
/*This Procedure will parse out the first field of a delimited string it will return
the result and a the orginal string minus the parsed out string.
the ideal would be to execute this procedure for each field you want to extract
from string. If you don't know how many values you need to parse out you can just
keep executing this until the p_input_strng equals the P_output_value
*/
begin
IF (instr(P_INPUT_STRING, P_DELIMITOR)) > 0
THEN
P_OUTPUT_VALUE := substr(P_INPUT_STRING, 1, (instr(P_INPUT_STRING, P_DELIMITOR)));
P_INPUT_STRING := regexp_replace(P_INPUT_STRING, P_OUTPUT_VALUE, '',1,1);
P_OUTPUT_VALUE := replace(P_OUTPUT_VALUE, P_DELIMITOR, '');
IF NVL(P_INPUT_STRING, ' ') = ' '
THEN
P_INPUT_STRING := P_OUTPUT_VALUE;
END IF;
ELSE
P_OUTPUT_VALUE := P_INPUT_STRING;
END IF;
end parse_delimited_string;
【讨论】:
【参考方案3】:declare
type vartype is varray(10) of number;
x1 vartype;
total integer;
begin
x1 := vartype (1,2,3,4);
total := x1.count;
for i in 1 .. total loop
dbms_output.put_line(x1(i));
end loop;
end;
/
【讨论】:
这可以在集合(varray 和 table)的帮助下完成。 它可以工作,除了需要将字符串从 varchar 解析为 varray 的目的。据我了解,这个问题的目的是获取一个字符串并将其转换为可以使用的格式,例如 varray。这个答案缺少从字符串到集合的部分。【参考方案4】:甲骨文 11g:
SELECT num_value
FROM ( SELECT TRIM (REGEXP_SUBSTR (num_csv,
'[^,]+',
1,
LEVEL))
num_value
FROM ( SELECT '1,2,3,4,5,6,7,8,9,10' num_csv FROM DUAL)
CONNECT BY LEVEL <= regexp_count (num_csv, ',', 1) + 1)
WHERE num_value IS NOT NULL
【讨论】:
这甚至适用于 Oracle 10。 @mvermand regexp_count 在 10g 中不存在【参考方案5】:简单,简单的例子如下:
declare
string_to_parse varchar2(2000) := 'abc,def,ghi,klmno,pqrst';
l_count number;
l_value varchar2(2000);
begin
string_to_parse := string_to_parse||',';
l_count := length(string_to_parse) - length(replace(string_to_parse,',',''));
-- In oracle 11g use regexp_count to determine l_count
for i in 1 .. l_count loop
select regexp_substr(string_to_parse,'[^,]+',1,i)
into l_value
from dual;
dbms_output.put_line(l_value);
end loop;
end;
【讨论】:
【参考方案6】:适用于 Oracle 10g 和 11g 的简单标记器 SQL 语句可以编写如下:
WITH string AS (
SELECT pv_string value
FROM dual)
SELECT DISTINCT upper(trim(regexp_substr (value, '[^' || pv_separator || ']+', 1, ROWNUM))) value,
level
FROM string
CONNECT BY LEVEL <= LENGTH(regexp_replace (value, '[^' || pv_separator || ']+')) + 1
ORDER BY level;
您可以将pv_string
替换为要解析的字符串(例如'a,b,c,d,e')和pv_separator
替换为分隔符字符串(例如',')。
【讨论】:
以上是关于如何在 PL/SQL 中解析逗号分隔的字符串? [复制]的主要内容,如果未能解决你的问题,请参考以下文章