2015-09-04 116 views
3

執行完後選擇如何將其分配給變量。將字符串拆分爲變量

如果輸入字符串是「x/y/z」,我必須將「x」存入變量say A,將「y」存入變量B,將z存入變量「C」。

假設如果字符串是「x/z」,那麼我必須將「x」存入變量say A,但將z存入變量「c」。

在所有其他情況下

想,如果輸入的字符串是唯一的「x」或「X/Y/Z/Z」再沒有什麼可以存儲

SELECT REGEXP_SUBSTR(<<Input String>>, '[^/]+', 1, LEVEL) 
           FROM DUAL 
        CONNECT BY REGEXP_SUBSTR((<<Input String>>, '[^/]+', 1, LEVEL) 

IS NOT NULL; 
+0

的問題是不太清楚。爲了訪問查詢的元素,你應該讀取光標,它可以通過幾種方法完成。例如,您可以在'FOR'循環中迭代元素並將值分配給變量。 –

回答

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,沒有必要通過使用連接 - 你可以分開的結果分爲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  
1

小心,regex_substr使用格式'[^/]+'解析字符串元素do not handle null list elements。這裏有一個方法,從一個處理空值的列表,它可以是提取特定元素put into a function for reuse(這得到其中的分隔符是斜線的第一個元素):

REGEXP_SUBSTR(string_in, '(.*?)(/|$)', 1, 1, NULL, 1); 

見上面的鏈接,但這樣調用簡單例如,列表元素按名稱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>