ORACLE PL-SQL如何创建函数来拆分字符串并返回n-long“;“块”;变成一个数组?

ORACLE PL-SQL如何创建函数来拆分字符串并返回n-long“;“块”;变成一个数组?,sql,string,oracle,plsql,Sql,String,Oracle,Plsql,我需要创建一个函数,该函数将接受任意长度的sting输入,并返回一个字符串数组,每个字符串包含n个长块。例如,具有3个字符长的块的这是一个测试的输入应返回: Thi s i s a tes t Tes tin g w ith co mma del imi ter s, one , two , thr ee, te st 为此,我创建了以下函数。我的问题是,有没有更好更快的方法来解决这个问题?我知道这个函数可能会使用很长的字符串被多次调用,我不希望这会降低系统的速度。此外,我最终需要设

我需要创建一个函数,该函数将接受任意长度的sting输入,并返回一个字符串数组,每个字符串包含n个长块。例如,具有3个字符长的块的
这是一个测试的输入应返回:

Thi
s i
s a
tes
t   
Tes
tin
g w
ith
co
mma
del
imi
ter
s,
one
,
two
,
thr
ee,
te
st 
为此,我创建了以下函数。我的问题是,有没有更好更快的方法来解决这个问题?我知道这个函数可能会使用很长的字符串被多次调用,我不希望这会降低系统的速度。此外,我最终需要设置函数,以便在检测到分隔符时也创建一个新条目。例如,“块长度”为三:

使用逗号分隔符测试,一、二、三,测试

应返回:

Thi
s i
s a
tes
t   
Tes
tin
g w
ith
co
mma
del
imi
ter
s,
one
,
two
,
thr
ee,
te
st 
请注意,我不希望删除或替换分隔符本身。我刚在检测后填充了一个新行/新数组条目

以下是我目前的代码:

CREATE OR REPLACE FUNCTION SPLIT_STRING (
    p_str   VARCHAR2, --String to split
    p_del   VARCHAR2, --Delimiter
    p_len   INTEGER,  --Length of each chunk
    p_force NUMBER) --Forces split when length is reached (1=on, 0=off)
RETURN VARCHAR2 IS
    l_tmp_str   VARCHAR2(32767);
    l_chnk_len  INTEGER;
    l_str       VARCHAR2(32767);
    l_chunk     VARCHAR2(32767);
    l_pos       INTEGER;
    l_len       INTEGER;
    l_chnksize  NUMBER;
BEGIN
    --Determine the strings total length
    l_len:= LENGTH(p_str);
    IF (l_len > 0)
    THEN
        l_tmp_str:= p_str;

        --Determine the necessary number of chuncks
        l_chnksize:=(l_len/p_len);
        IF MOD(l_chnksize,1) != 0
        THEN
            l_chnksize:= CEIL(l_chnksize);
        END IF;

        --Split the string into chunks
        IF p_force = 1
        THEN
            l_pos:=1;    
            FOR loop_num IN 1..l_chnksize
            LOOP
                IF (loop_num>1)
                THEN
                    l_str:=l_str||CHR(10)||CHR(13)||SUBSTR(p_str,l_pos,p_len);
                ELSE
                    l_str:=SUBSTR(p_str,l_pos,p_len);
                END IF;

                --Increment position placeholder
                l_pos:=l_pos+p_len;
            END LOOP;
        ELSE
            l_str:='UNFORCED, NOT IMPLEMENTED'; 
        END IF;
    END IF;

--Return the delimited string
RETURN l_str;

我的具体问题是:对于大字符串输入,有没有更快的方法可以做到这一点?

我不知道这是否更快,但肯定更简单。实际上并不是将块放入数组中,而是在每个分隔符或一组字符后插入换行符。使用正则表达式可以很容易地做到这一点

select regexp_replace('Testing with comhm,a sdfdeli,mitjers,one,two,three,test',
                      '(.{0,3},)|(.{5})',
                      '\1\2' ||chr(10))     chunks
from dual;

CHUNKS
-------
Testi
ng wi
th co
mhm,
a sdf
deli,
mitje
rs,
one,
two,
three
,
test
正则表达式解释:

  • (.{0,3},):最多由3个字符组成的组,后跟逗号(分隔符),假设每个块的长度为5
  • (.{5}):由5个字符组成的组,假设每个块的长度为5
这些第一捕获组和第二捕获组被附加了换行符的它们自己替换

通用表达式是

'(.{0,'||(length-2)||'}'||delimiter||')|(.{'||(length)||'})'

您不需要为大字符串而烦恼。您的最大输入大小为32767。我认为执行此函数需要<0.01秒才能获得最大的输入。感谢您的回复,这确实有效。有趣的是,在使用循环结构(而不是正则表达式)修改我的代码以执行与正则表达式完全相同的操作,并在循环中对3000个字符长度的字符串进行10000次测试之后,循环方法的性能更好。我没有料到。尽管如此,谢谢你。