Oracle CONNECT BY拆分多列字符串插入行数不足问题求解
问题说明
现有向测试表两列插入拆分数据的SQL语句,执行后仅生成2行数据,不符合预期的3行输出。经排查问题出在CONNECT BY子句仅对长度更短的分隔字符串做层级终止判断,直接遗漏了第三组值。由于传入的数值为动态内容,无法调整传入值的位置,也不能在同一查询中重复声明CONNECT BY子句,需要在不改动值位置的前提下修改语句,实现预期输出。
预期输出结果
Name Country a xy c yx null xc
原有问题语句
INSERT INTO tbl_test_customer ( NAME, COUNTRY ) SELECT TRIM(regexp_substr('a,c', '[^,]+', 1, level)) str, TRIM(regexp_substr('xy,yx,xc', '[^,]+', 1, level)) stri FROM dual CONNECT BY instr('a,c', ',', 1, level - 1) > 0;
故障原因
原有CONNECT BY的循环终止条件仅绑定了短字符串'a,c'的分隔符计数:该字符串仅包含1个逗号,最多触发2次层级循环,因此只会返回2行数据,完全没有覆盖长字符串'xy,yx,xc'拆分需要的第三层循环,导致第三行数据丢失。
修改方案
调整CONNECT BY的终止判断逻辑,通过REGEXP_COUNT分别统计两个待拆分字符串的总段数,取两个段数的最大值作为循环终止阈值,不需要调整传入值位置,也不需要重复声明CONNECT BY子句,修改后可直接适配动态传入的任意长度分隔字符串,语句如下:
INSERT INTO tbl_test_customer ( NAME, COUNTRY ) SELECT TRIM(regexp_substr('a,c', '[^,]+', 1, level)) str, TRIM(regexp_substr('xy,yx,xc', '[^,]+', 1, level)) stri FROM dual CONNECT BY level <= GREATEST( REGEXP_COUNT('a,c', '[^,]+'), REGEXP_COUNT('xy,yx,xc', '[^,]+') );
逻辑说明:该写法会自动匹配两个待拆分字符串的最大长度生成对应行数,较短的字符串拆分到超出自身长度的层级时,
regexp_substr会自动返回null,执行结果完全匹配预期输出。后续动态传入的字符串长度变化时,语句也能自动适配,不需要手动调整循环参数。
内容的提问来源于stack exchange,提问作者atc
相关产品推荐
相关产品推荐

