2015-06-17 84 views
1

Oracle快捷11G R2: 在PLSQL我有一個包含價值的這樣一個CSV列表VARCHAR2:PLSQL移動數據

vList:='1212,3232,3232,4343,54545,65654,65665,65654,788787' 

我想移動這些成集,所以我創建了一個新的類型:

CREATE TYPE INTEGER_TT AS TABLE OF INTEGER; 

然後聲明我的變量:

my_list INTEGER_TT; 

使用包含CSV的varchar2中的值填充「my_list」的最快方式(以處理器時間而非執行時間而言)是什麼?

這是我目前的代碼,查詢本身的運行時間大約爲0.01s,「批量收集」添加大約需要6秒,列表中大約有500個值。

select regexp_substr(vList,'[^,]+', 1, level) intID 
bulk collect into my_list 
from dual connect by regexp_substr(vList, '[^,]+', 1, level) is not null; 

任何比上面我的代碼更好的選擇?

回答

2

性能會因平臺,配置等而有所不同,所以一個明確的答案將會很困難。正則表達式的0.1s似乎很多,並且增加到6s來填充集合似乎過度。

由於您的字符串僅包含數字,你可以嘗試一招用的XMLTable:

select to_number(column_value) 
bulk collect into my_list 
from xmltable(vList); 

這通過您的CSV列表爲an XQuery expression,而且它解釋爲一個XQuery序列。這隻適用於數字,但不能將此方法用於字符串。

採樣定時進行比較與同500元列表中的方法,用隨機整數生成:

set serveroutput on 
declare 
    my_list INTEGER_TT; 
    vList varchar2(32767); 
    vTime pls_integer; 
begin 
    -- create list of 500 random integers 
    vTime := dbms_utility.get_time; 
    select listagg(trunc(dbms_random.value(1, 10000)), ',') 
    within group (order by null) 
    into vList 
    from dual 
    connect by level <= 500; 
    dbms_output.put_line('Creating list took ' || (dbms_utility.get_time - vTime)); 

    -- original regex approach 
    vTime := dbms_utility.get_time; 
    select regexp_substr(vList,'[^,]+', 1, level) intID 
    bulk collect into my_list 
    from dual connect by regexp_substr(vList, '[^,]+', 1, level) is not null; 
    dbms_output.put_line('Regex took ' || (dbms_utility.get_time - vTime)); 

    -- XMLTable approach 
    vTime := dbms_utility.get_time; 
    select to_number(column_value) 
    bulk collect into my_list 
    from xmltable(vList); 
    dbms_output.put_line('XMLTable took ' || (dbms_utility.get_time - vTime)); 
end; 
/

得到以下時間,在百分之一秒:

Creating list took 2 
Regex took 188 
XMLTable took 3 

您可能因爲不同的結果,或不同幅度的差異...


如果你'這樣做是爲了在SQL查詢中使用集合作爲數據源 - 這是可能的,因爲它是模式級集合類型 - 您可以跳過該步驟。如果您使用的是table(my_list),則可以直接參考xmltable(vList)。您完全可以避免PL/SQL,具體取決於您在做什麼;儘管你可以用CTE完成這件事。

+0

的最佳解決方案,我的成績從查詢:創建列表了89 正則表達式了1062 的XMLTable了6 –

+0

嗨@Alex,只是一張紙條,似乎VLIST可能是最大尺寸爲4000,超過這一數額的「從xmltable(vList)給出一個錯誤:「ORA-01460:未實現或不合理的轉換請求」我看不到任何解決方法。 –

+0

@ASims - 這是在SQL上下文中使用XMLTable,其中字符串大小限制爲4000 (直到12c),你需要使'vList'成爲一個CLOB以超過這個長度(通過一個包含1000個數字的長度爲4874的CLOB進行驗證)。 –