Oracle カスタム区切り関数

今日仕事に行ったとき、プロダクト マネージャーが、顧客が在庫データのバッチを持っており、biz_type にはカンマで区切られた複数のビジネス キーがあり、このフィールドをカンマで区切られた複数行のレコードに調整する必要があると報告しました。

Oracle カスタム区切り関数:

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;

文字列区切り関数を呼び出す

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

出力結果はビジネス要件を満たしています。関連する SQL スクリプトを顧客サイトの運用および保守担当者に提供し、在庫データの移行と修正に関する残りの問題を担当させます。

私が正午の昼休みから起きるとすぐに、プロダクト マネージャーの @ が、運用と保守の同僚にリモート サポートを提供する必要があると言いました。

機能要件: インベントリ データの biz_type フィールドはカンマで区切られ、複数行のレコードに変換されます。

-- 定义数转存储过程
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;   
    

ストアド プロシージャを呼び出す

declare
begin
    conver_procedure()
end;
    

完全なカスタムタイプ

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

カスタム関数split_stringの戻りデータ型を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;

発生した問題:

PLS-00653: Oracleでパイプライン関数を適用する場合、PL/SQLドメインでは集計/表関数は使用できません。

この問題の理由:

1. カスタムテーブルタイプ: TYPE_SPLIT

2. カスタム文字列分割関数:split_string は TYPE_SPLIT パイプライン ストリームを返します。

3. ストレージ conver_procedure を直接呼び出して、split_string 関数を実行し、関連するコレクションを TYPE_SPLIT 型に割り当てます。「PL/SQLドメイン内では集計/テーブル関数は使用できません」

進入禁止:

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

正しいスペル

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

パイプライン関数は TABLE 演算子を使用して SQL クエリから呼び出す必要があるため、ここで直接割り当てることはできません。

おすすめ

転載: blog.csdn.net/zhouzhiwengang/article/details/130258198