我试了一下,可以达到类似的效果,
CREATE OR REPLACE FUNCTION get_series_of_numbers(p_input_string IN VARCHAR2)
RETURN VARCHAR2 IS
lo_start NUMBER;
lo_end NUMBER;
lo_final_string VARCHAR2(4000);
--a convinient method to get the series for a strig like '1-3' or 9-15'
FUNCTION get_series(p_series_string VARCHAR2) RETURN VARCHAR2 IS
lo_string_to_return VARCHAR2(4000);
BEGIN
IF instr(p_series_string
,'-') > 0
THEN
lo_start := to_number(substr(p_series_string
,1
,instr(p_series_string
,'-') - 1));
lo_end := to_number(substr(p_series_string
,instr(p_series_string
,'-') + 1));
--query to generate a series of numbers between a start and end point and then concatenate all with ','
SELECT listagg(actual_numbers
,',') within GROUP(ORDER BY actual_numbers)
INTO lo_string_to_return
FROM (SELECT LEVEL actual_numbers FROM dual WHERE LEVEL >= lo_start CONNECT BY LEVEL <= lo_end);
ELSE
lo_string_to_return := p_series_string;
END IF;
RETURN lo_string_to_return;
END;
BEGIN
--this loop is to get all the elements in the string separated by ',' as column
--so that we can loop over all
FOR i IN (SELECT regexp_substr(str
,'[^,]+'
,1
,rownum) split
FROM (SELECT p_input_string str FROM dual)
CONNECT BY LEVEL <= length(regexp_replace(str
,'[^,]+')) + 1)
LOOP
IF lo_final_string IS NOT NULL
THEN
lo_final_string := lo_final_string || ',' || get_series(i.split);
ELSE
lo_final_string := get_series(i.split);
END IF;
END LOOP;
RETURN lo_final_string;
END get_series_of_numbers;
一些测试结果:
DECLARE
input_string VARCHAR2(4000) := '1,2,8-3,4';
result_string VARCHAR2(4000);
begin
dbms_output.put_line('Input string is: '||input_string);
result_string := get_series_of_numbers(p_input_string => input_string);
dbms_output.put_line('Output string is: '||result_string);
end;
/*
Input string is: 1-3,4,9,11-15
Output string is: 1,2,3,4,9,11,12,13,14,15
Input string is: 1-3,4-6,9-10,11-15
Output string is: 1,2,3,4,5,6,9,10,11,12,13,14,15
Input string is: 1,2,3,4
Output string is: 1,2,3,4
Input string is: 1,2,3-8,4
Output string is: 1,2,3,4,5,6,7,8,4
--a negative case
Input string is: 1,2,8-3,4
Output string is: 1,2,,4
*/
希望它能提供有关可以进一步优化以处理极端情况或尚未涵盖的任何内容的要求的想法。干杯!!