Oracle custom separator function

When I went to work today, the product manager reported that the customer had a batch of stock data, biz_type had multiple business keys separated by commas, and now this field needs to be adjusted to a comma-separated multi-line record.

Oracle custom separator function:

create or replace function split_string(t_string in varchar2, p_delimiter in varchar2)
    return sys.Odcivarchar2list
    pipelined
    is
    l_idx Pls_integer;
    v_string varchar(245) := t_string;
begin
    loop
        l_idx := instr(v_string, p_delimiter);
        if l_idx > 0 then
            pipe row(substr(v_string, 1, l_idx-1));
            v_string := substr(v_string, l_idx + length(p_delimiter));
        else
            pipe row(v_string);
            exit;
        end if;
    end loop;
    return;
end;

call the string delimiter function

select * from table (split_string('1, 2, 3'), ',')

The output results meet the business requirements. Provide relevant SQL scripts to the operation and maintenance colleagues at the customer's site, and let him handle the remaining problems of stock data migration and correction.

As soon as I woke up from the lunch break at noon, the product manager @, said that I needed to provide remote support to my colleagues in operation and maintenance.

Functional requirements: The biz_type field in the inventory data is separated by commas and converted into multi-line records.

-- 定义数转存储过程
create or replace procedure conver_procedure is
    -- 定义查询游标
    cursor cur_tid_biz_type is
        select tid, biz_type from **** where biz_type like '%,%';
    -- 定义游标记录
    cur cur_tid_biz_type%ROWTYPE;
    -- 定义集合列表(突然发现,split_string 分隔函数返回的sys.Odcivarchar2list类型是char 类型,无法与兼容,解决办法修改split_string 函数自定义type)
    v_biz_type_list TYPE_SPLIT;
    
    begin
        -- for 循环游标
        for cur in cur_tid_biz_type loop
            -- 调用字符串分隔函数split_string(),将结果存储至自定义集合v_biz_type_list  中。
            select split_string(cur.BIZ_TYPE, ',') into  v_biz_type_list from dual;
            -- 遍历集合
            for i in v_biz_type_list.FIRST .. v_biz_type_list.LAST Loop
                -- 输出结果
                DBMS_OUTPUT.PUT_LINE('tid:'||cur.TID||',bizType:'||v_biz_type_list(i));
            end loop;
        end loop;
    end;   
    

call stored procedure

declare
begin
    conver_procedure()
end;
    

Complete custom Type

create or replace type TYPE_SPLIT as table of varchar2(245);

Modify the return data type of the custom function split_string to TYPE_SPLIT.

create or replace function split_string(t_string in varchar2, p_delimiter in varchar2)
    return TYPE_SPLIT
    pipelined
    is
    l_idx Pls_integer;
    v_string varchar(245) := t_string;
begin
    loop
        l_idx := instr(v_string, p_delimiter);
        if l_idx > 0 then
            pipe row(substr(v_string, 1, l_idx-1));
            v_string := substr(v_string, l_idx + length(p_delimiter));
        else
            pipe row(v_string);
            exit;
        end if;
    end loop;
    return;
end;

Problems encountered:

PLS-00653: Aggregate/table functions not allowed in PL/SQL domain when applying pipeline functions in Oracle.

Reasons for this problem:

1. Custom table type: TYPE_SPLIT

2. Custom string split function: split_string returns TYPE_SPLIT pipeline stream.

3. Directly call the storage conver_procedure to execute the split_string function and assign the relevant collection to the TYPE_SPLIT type. "Aggregate/table functions are not allowed within the PL/SQL domain"

Wrong way:

v_biz_type_list := split_string(cur.BIZ_TYPE, ',')

correct spelling

 select split_string(cur.BIZ_TYPE, ',') into  v_biz_type_list from dual;

Because the pipeline function needs to be called from the SQL query with the TABLE operator, it cannot be directly assigned here.

Guess you like

Origin blog.csdn.net/zhouzhiwengang/article/details/130258198