Как разбирать строку с разделителями-запятыми в PL/SQL?
У меня есть строка с разделителями-запятыми в PL/SQL script (например, data: = 'a, b, c, d, e'), которые мне нужно проанализировать в script.
Я хотел бы перебрать строку и обработать каждый элемент. Как петля foreach.
Возможно ли это в PL/SQL? Может ли кто-нибудь указать мне какой-нибудь код?
Ответы
Ответ 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.
Ответ 2
Oracle 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
Ответ 3
Существует еще один способ, описанный здесь http://blogs.oracle.com/aramamoo/entry/how_to_split_comma_separated_string_and_pass_to_in_clause_of_select_statement
в основном с помощью regexp_substr.
Ответ 4
Это простой пример:
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;
Ответ 5
Простой оператор SQL-выражения tokenizer, работающий для Oracle 10g и 11g, можно записать следующим образом:
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
с помощью строки разделителя (например, "," ).
Ответ 6
Для основной строки с разделителями-запятыми. выполните процедуру, описанную ниже, она предназначена для уменьшения количества записей за один раз. Когда 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;
Ответ 7
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;
/