今日仕事に行ったとき、プロダクト マネージャーが、顧客が在庫データのバッチを持っており、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 クエリから呼び出す必要があるため、ここで直接割り当てることはできません。