Oracle 将字符串拆分为变量
执行下面的select后,如何将其分配到变量中 如果输入字符串是“x/y/z”,我必须将“x”存储到变量A中,将“y”存储到变量B中,将“z”存储到变量“C”中 假设字符串是“x/z”,那么我必须将“x”存储到变量A中,而将z存储到变量c中 在所有其他情况下,假设输入字符串仅为“x”或“x/y/z/z”,则无法存储任何内容Oracle 将字符串拆分为变量,oracle,plsql,Oracle,Plsql,执行下面的select后,如何将其分配到变量中 如果输入字符串是“x/y/z”,我必须将“x”存储到变量A中,将“y”存储到变量B中,将“z”存储到变量“C”中 假设字符串是“x/z”,那么我必须将“x”存储到变量A中,而将z存储到变量c中 在所有其他情况下,假设输入字符串仅为“x”或“x/y/z/z”,则无法存储任何内容 SELECT REGEXP_SUBSTR(<<Input String>>, '[^/]+', 1, LEVEL)
SELECT REGEXP_SUBSTR(<<Input String>>, '[^/]+', 1, LEVEL)
FROM DUAL
CONNECT BY REGEXP_SUBSTR((<<Input String>>, '[^/]+', 1, LEVEL)
IS NOT NULL;
选择REGEXP_SUBSTR(,'[^/]+',1,级别)
来自双重
通过REGEXP_SUBSTR((,'[^/]+',1,级别)连接
不为空;
我不使用SQL,而是使用PL/SQL,因为似乎没有必要引入不必要的上下文切换:
declare
v_a varchar2(10);
v_b varchar2(10);
v_c varchar2(10);
v_string varchar2(33);
procedure split_string (p_string in varchar2,
p_a out varchar2,
p_b out varchar2,
p_c out varchar2)
is
begin
if regexp_count(p_string, '/') = 2 then
p_a := regexp_substr(p_string, '[^/]+', 1, 1);
p_b := regexp_substr(p_string, '[^/]+', 1, 2);
p_c := regexp_substr(p_string, '[^/]+', 1, 3);
elsif regexp_count(p_string, '/') = 1 then
p_a := regexp_substr(p_string, '[^/]+', 1, 1);
p_c := regexp_substr(p_string, '[^/]+', 1, 2);
end if;
end;
begin
v_string := 'x/y/z';
split_string(v_string, v_a, v_b, v_c);
dbms_output.put_line('v_string = "'||v_string||'", v_a = "'||v_a||'", v_b = "'||v_b||'", v_c = "'||v_c||'"');
v_string := 'x/y';
split_string(v_string, v_a, v_b, v_c);
dbms_output.put_line('v_string = "'||v_string||'", v_a = "'||v_a||'", v_b = "'||v_b||'", v_c = "'||v_c||'"');
v_string := 'x/y/z/1';
split_string(v_string, v_a, v_b, v_c);
dbms_output.put_line('v_string = "'||v_string||'", v_a = "'||v_a||'", v_b = "'||v_b||'", v_c = "'||v_c||'"');
v_string := 'x';
split_string(v_string, v_a, v_b, v_c);
dbms_output.put_line('v_string = "'||v_string||'", v_a = "'||v_a||'", v_b = "'||v_b||'", v_c = "'||v_c||'"');
end;
/
v_string = "x/y/z", v_a = "x", v_b = "y", v_c = "z"
v_string = "x/y", v_a = "x", v_b = "", v_c = "y"
v_string = "x/y/z/1", v_a = "", v_b = "", v_c = ""
v_string = "x", v_a = "", v_b = "", v_c = ""
如果您绝对必须使用SQL,则无需使用connect by-您只需将结果分隔为3列,以匹配要将结果输入到的3个变量:
with strings as (select 'x/y/z' str from dual union all
select 'x/y' str from dual union all
select 'x/y/z/1' str from dual union all
select 'x' str from dual)
select str,
case when regexp_count(str, '/') in (1, 2) then regexp_substr(str, '[^/]+', 1, 1) end v_a,
case when regexp_count(str, '/') = 2 then regexp_substr(str, '[^/]+', 1, 2) end v_b,
case when regexp_count(str, '/') = 2 then regexp_substr(str, '[^/]+', 1, 3)
when regexp_count(str, '/') = 1 then regexp_substr(str, '[^/]+', 1, 2)
end v_c
from strings;
STR V_A V_B V_C
------- --------------------- --------------------- ---------------------
x/y/z x y z
x/y x y
x/y/z/1
x
注意,regex_substr使用格式
'[^/]+'
来解析字符串元素。下面是一种从处理空值的列表中提取特定元素的方法,可以是(这将获取分隔符为斜杠的第一个元素):
请参见上面的链接,但调用如下简单示例,其中列表元素由一个名为get_list_element的函数按顺序提取并分配给变量。也许您可以将此逻辑应用于您的需要:
SQL> declare
2 a varchar2(1);
3 b varchar2(1);
4 c varchar2(1);
5 begin
6 select get_list_element('x/y/z', 1, '/'),
7 get_list_element('x/y/z', 2, '/'),
8 get_list_element('x/y/z', 3, '/')
9 into a, b, c
10 from dual;
11
12 dbms_output.put_line('a: ' || a);
13 dbms_output.put_line('b: ' || b);
14 dbms_output.put_line('c: ' || c);
15 end;
16 /
a: x
b: y
c: z
PL/SQL procedure successfully completed.
SQL>
或者修复您最初的问题,尝试使用以下方法将元素转换为行:
SQL> with tbl(str) as (
2 select 'x/y/z' from dual
3 )
4 select regexp_substr(str, '(.*?)(/|$)', 1, level, null, 1) element
5 from tbl
6 connect by level <= regexp_count(str, '/')+1;
ELEME
-----
x
y
z
SQL>
SQL>以tbl(str)作为(
2从双通道中选择“x/y/z”
3 )
4选择regexp_substr(str,(.*)(/|$)',1,level,null,1)元素
5来自tbl
6.分层连接
这个问题非常不清楚。要访问查询的元素,您应该读取光标,可以通过两种方式完成。例如,您可以在循环中迭代元素,并将值分配给变量。
SQL> with tbl(str) as (
2 select 'x/y/z' from dual
3 )
4 select regexp_substr(str, '(.*?)(/|$)', 1, level, null, 1) element
5 from tbl
6 connect by level <= regexp_count(str, '/')+1;
ELEME
-----
x
y
z
SQL>