declare
p_dbs varchar(1000):='MK~RU_AR~ZEN~ADFORM_CP~3301071970_CI~FY22QO_OB~1X1_TS~APV-123895_VV~NONE_PI~123895_ID~GLD0009ADF__CV~PPV-123895_FF~CPM';
type values_t is table of varchar(150);
t_values values_t := values_t();
l_char varchar2(1 char);
l_buffer varchar2(150 char);
l_sp boolean :=false;
l_ep boolean :=false;
begin
for i in 1..length(p_dbs)
loop
l_char := substr(p_dbs, i, 1);
if nvl(length(replace(translate(l_char, '0123456789', rpad(chr(1), 10, chr(1))), chr(1))), 0) = 0 and l_sp=false and l_ep=false
then -- char is number
l_buffer := l_buffer || l_char;
l_sp := true;
end if;
if nvl(length(replace(translate(l_char, '0123456789', rpad(chr(1), 10, chr(1))), chr(1))), 0) = 0 and l_sp=true and l_ep=false
then l_buffer := l_buffer || l_char;
end if;
if nvl(length(replace(translate(l_char, '0123456789', rpad(chr(1), 10, chr(1))), chr(1))), 0) > 0 and l_sp=true and l_ep=false
then
if --length(l_buffer)=5 or length(l_buffer)=6
not l_buffer MEMBER OF t_values then
t_values.EXTEND;
t_values(t_values.COUNT) := l_buffer;
dbms_output.put_line(l_buffer);
l_buffer := '';
l_sp := false;
l_ep := true;
end if;
end if;
if nvl(length(replace(translate(l_char, '0123456789', rpad(chr(1), 10, chr(1))), chr(1))), 0) = 0 and l_sp=false and l_ep=true
then
l_buffer := l_buffer || l_char;
l_sp := true;
l_ep := false;
end if;
end loop;
end;
无法理解的行为,显示的值不是 1123895:
33301071970
22
1
1123895
123895
0009
如果您删除对成员的检查,它会显示正确的数据:
33301071970
22
1
1
123895
123895
0009
123895
如果检查字符数,则结果集为空。
如何实现这样的结果,即只有一个值会写入类型:
123895
l_sp我不太明白代码中的标志 (和)应该是什么意思l_ep,因此不太明白如何修复它。您可以基于正则表达式构建查询。
例如,这是一个这样的查询,它从字符串中提取数字序列:
工作原理:该函数
REGEXP_SUBSTR返回字符串中与正则表达式匹配的第 N 个序列。正则表达式[[:digit:]]+提取数字序列。递归查询 (connect by) 将依次提取所有数字序列,直到它们用完(将返回一个空字符串,即null)。现在您可以从字符串中提取所需长度的唯一序列:
你可以把它们拿出来:
可采集:
添加到原始代码
我试图简化原始代码。看起来你可以不用标志。试试这个例子:
因此,该函数可能如下所示:
显然,在您的代码中,两个相互影响的条件存在错误:
因此,该函数会将序列的第一个字符附加两次,从而导致错误。例如,对于输入字符串
1235a,将返回值11235。