本人新手。。求大神看看关于过滤分隔符提取字符串的问题,我用数组实现错误好多
题目是:
编写存储过程,实现功能:
1.输入参数:字符串,分隔符,序号
2.输出参数:字符串
3.注:序号可为负数,为负数时从右往左找字符串
例:
输入参数分别为: ab@@cd@@ee@@ff @@ 2 则输出:cd
输入参数分别为: ab@@cd@@ee@@ff @@ -2 则输出:ee
输入参数分别为: ab@@cd@@ee@@ff @@ 4 则输出:ff
我写的代码如下 改了很多次
CREATE OR REPLACE PROCEDURE str_to(input IN VARCHAR2,
separator IN VARCHAR2,
serialno IN INTEGER) IS
v_input VARCHAR2(100) := input;
v_separator VARCHAR2(5) := separator;
v_separatorno INTEGER;
v_serialno INTEGER := serialno;
v_output VARCHAR2(20);
i NUMBER;
strlength INTEGER;
str VARCHAR2(5);
TYPE type_array IS VARRAY(200) OF VARCHAR2(20);
array1 type_array;
array2 type_array;
flag BOOLEAN;
-- num NUMBER;
-- a INTEGER;
BEGIN
array1 := type_array();
array2 := type_array();
strlength := length(v_input);
v_separatorno := length(v_separator);
flag := FALSE;
array2.extend;
IF v_serialno < 0 THEN
BEGIN
v_serialno := -v_serialno;
flag := TRUE;
SELECT REVERSE(v_input) INTO v_input FROM dual;
END;
END IF;
--如果序号为负数,将输入的字符串反转
FOR i IN 1 .. strlength LOOP
array1.extend;
array1(i) := substr(v_input, - (strlength - i + 1));
--DBMS_OUTPUT.put_line(array1(i));
END LOOP;
COMMIT;
--逆向剪切字符串,逐一存入数组
-- a := -v_separatorno;
FOR i IN 1 .. strlength LOOP
--SELECT substr(array1(i), 1,v_separatorno) INTO str FROM dual;
--DBMS_OUTPUT.put_line(str);
IF substr(array1(i), 1, v_separatorno) <> v_separator THEN --若数组元素不以分隔符为首将数组1的元素存到数组2中
FOR j IN 1 .. array2.count LOOP
--array1.extend;
--array2.extend;
array2(j) := array1(i); --但是这里会出现以一个“@”为首的元素
DBMS_OUTPUT.put_line(array2(j));
END LOOP;
END IF;
END LOOP;
array2.extend;
/*v_output := array2(v_serialno);*/
/* SELECT INSTR(array2(v_serialno), '[^v_separator]+', 1, 1)
INTO num
FROM dual;*/ --扫描分隔符出现的位置
/* SELECT SUBSTR(array2(v_serialno), 1, 2)
INTO v_output
FROM DUAL;*/
SELECT SUBSTR(array2(v_serialno),
1,
v_serialno)
INTO v_output
FROM DUAL; --从第一位开始截取,得到的结果是字符串的最后一位 有点搞不懂= =!
IF flag = TRUE THEN
BEGIN
SELECT REVERSE(v_output) INTO v_output FROM dual;
END;
END IF; --当序号为负的时候保证输出的字符串是正向的
DBMS_OUTPUT.put_line(v_output);
END str_to;
存储过程 分隔符
[解决办法]
CREATE OR REPLACE PROCEDURE str_to(input IN VARCHAR2,
separator IN VARCHAR2,
serialno IN INTEGER,
str out varchar2) IS
v_count number;
v_lv number;
v_input varchar2(4000);
v_replace varchar2(10) := '▽';
BEGIN
v_input := replace(input, separator, v_replace);
select length(v_input) - length(replace(v_input, v_replace, '')) + 1
into v_count
from dual;
if (serialno >= 0) then
v_lv := serialno;
else
v_lv := v_count + serialno + 1;
end if;
with t as
(select level lv,
regexp_substr(v_input, '[^'
[解决办法]
v_replace
[解决办法]
']+', 1, level) str
from dual
connect by level <= v_count)
select str into str from t where lv = v_lv;
dbms_output.put_line(str);
exception
when others then
str := '';
END str_to;