我有一个列,它存储一个包含4个或更少野性字符的4个字符的长字符串(例如。????
,??01
',0??1
等。对于像0??1
这样的每个字符串,我必须插入另一个表值0001到0991;对于字符串??01
,值将为0001到9901;字符串????
的值将为0000到9999,依此类推。
如何使用PL / SQL和字符串函数完成此操作?
修改
目前的代码是:
declare
v_rule varchar2(50) := '????52132';
v_cc varchar2(50);
v_nat varchar2(50);
v_wild number;
n number;
begin
v_cc := substr(v_rule,1,4);
v_nat := substr(v_rule,5);
dbms_output.put_line (v_cc || ' '|| v_nat);
if instr(v_cc, '????') <> 0 then
v_wild := 4;
end if;
n := power(10,v_wild);
for i in 0 .. n - 1 loop
dbms_output.put_line(substr(lpad(to_char(i),v_wild,'0' ),0,4));
end loop;
end;
/
答案 0 :(得分:2)
将*替换为%,? to _并将 LIKE 子句与结果值一起使用。
答案 1 :(得分:2)
会有以下帮助吗?
BEGIN
FOR source_row IN (SELECT rule FROM some_table)
LOOP
INSERT INTO some_other_table (rule_match)
WITH numbers AS (SELECT LPAD(LEVEL - 1, 4, '0') AS num FROM DUAL CONNECT BY LEVEL <= 10000)
SELECT num FROM numbers WHERE num LIKE REPLACE(source_row.rule, '?', '_');
END LOOP;
END;
/
这假设您有一个名为some_table
的表格,其中包含rule
列,其中包含??01
,0??1
和????
等字词。它会在some_other_table
中插入与0000到9999相匹配的所有数字,这些数字与这些野外梳理模式相匹配。
子查询
SELECT LPAD(LEVEL - 1, 4, '0') AS num FROM DUAL CONNECT BY LEVEL <= 10000)
生成0000
到9999
范围内的所有数字。然后,我们使用LIKE
从此列表中过滤掉与此模式匹配的任何数字。请注意,_
是使用LIKE
而非?
时的单字符通配符。
我使用以下数据进行设置:
CREATE TABLE some_table (rule VARCHAR2(4));
INSERT INTO some_table (rule) VALUES ('??01');
INSERT INTO some_table (rule) VALUES ('0??1');
INSERT INTO some_table (rule) VALUES ('????');
COMMIT;
CREATE TABLE some_other_table (rule_match VARCHAR2(4));
运行上面的PL / SQL块后,表some_other_table
中有10200行,所有数字都与给定的三种模式相匹配。
答案 2 :(得分:1)
扩展@Oleg Dok的答案,它使用鲜为人知的事实,即下划线与%
相同,但仅针对单个字符并使用PL \ SQL我认为以下是最简单的方法它。关于如何使用connect by
的详细说明是here。
declare
cursor c_min_max( Crule varchar2 ) is
select to_number(min(numb)) as min_n, to_number(max(numb)) as max_n
from ( select '0000' as numb
from dual
union
select lpad(level, 4, '0') as numb
from dual
connect by level <= 9999 )
where to_char(numb) like replace(Crule, '?', '_');
t_mm c_min_max%rowtype;
l_rule varchar2(4) := '?091';
begin
open c_min_max(l_rule);
fetch c_min_max
into t_mm;
close c_min_max;
for i in t_mm.min_n .. t_mm.max_n loop
dbms_output.put_line(lpad(i, 4, '0'));
end loop;
end;
/