oracle行转列 列转行求助
发布网友
发布时间:2022-04-22 20:42
我来回答
共2个回答
热心网友
时间:2022-04-08 02:24
Oracle 需要首先在数据库中, 创建好 类型 与 函数。
来实现一个 split 功能的处理。
-- 定义一个对象类型.
CREATE OR REPLACE TYPE ty_row_str_split as object (strValue VARCHAR2 (4000));
/
-- 定义一个 表/数组类型, 内容是前面定义的那个对象.
CREATE OR REPLACE TYPE ty_tbl_str_split IS TABLE OF ty_row_str_split;
/
--------------------
-- 字符分割函数.
-- 参数1: 被分割的源字符串
-- 参数2: 用于拆分的字符串。
--------------------
CREATE OR REPLACE FUNCTION fn_split(
p_str IN VARCHAR2,
p_delimiter IN VARCHAR2)
RETURN ty_tbl_str_split IS
j INT := 0;
i INT := 1;
-- 被分割的源字符串 的长度.
len INT := 0;
-- 分隔字符串的长度
len1 INT := 0;
-- 暂存的中间每一个单元的文本信息.
str VARCHAR2(4000);
-- 预期返回结果.
str_split ty_tbl_str_split := ty_tbl_str_split();
BEGIN
-- 被分割的源字符串 的长度.
len := LENGTH(p_str);
-- 分隔字符串的长度.
len1 := LENGTH(p_delimiter);
-- 遍历 被分割的源字符串.
WHILE j < len LOOP
-- 在被分割的源字符串中, 查询 分隔字符串.
j := INSTR(p_str, p_delimiter, i);
IF j = 0 THEN
-- j=0 意味着没有找到.
-- 可以理解为是查询到最后一个单元了.
-- 设置 j := len, 让外部的循环处理可以结束了.
j := len;
-- 获取最后一个单元的内容.
str := SUBSTR(p_str, i);
-- 结果追加一行.
str_split.EXTEND;
-- 设置结果内容.
str_split(str_split.COUNT) := ty_row_str_split(strValue => str);
IF i >= len THEN
EXIT;
END IF;
ELSE
-- 如果在被分割的源字符串中,找到了 分隔字符串.
-- 首先,获取分割的内容.
str := SUBSTR(p_str, i, j - i);
-- 然后设置索引, 下一次再查找的时候,从指定的索引位置开始(不是从0开始找了)
i := j + len1;
-- 结果追加一行.
str_split.EXTEND;
-- 设置结果内容.
str_split(str_split.COUNT) := ty_row_str_split(strValue => str);
END IF;
END LOOP;
RETURN str_split;
END fn_split;
/
函数创建完毕以后,可以开始做查询的处理.
CREATE TABLE a (
id int,
val varchar2(10)
);
insert into a values(1, 'B1||B2||B3');
insert into a values(2, 'B4||B5');
insert into a values(3, 'B6');
COLUMN "Value" FORMAT A15
SQL> select
2 a.id,
3 to_char(strvalue) as Value
4 from
5 a,
6 table(fn_split( a.val, '||'));
ID VALUE
---------- ---------------
1 B1
1 B2
1 B3
2 B4
2 B5
3 B6
已选择6行。
追问用正则表达式能写吗
追答正则 你要
1 B1||B2||B3
一行变三行啊
你有什么 WHERE 条件, 可以一行 拆三行的?
热心网友
时间:2022-04-08 03:42
select id, substr( names, instr('||'|| names, '||', 1, rn),
instr( names||'||', '||', 1, rn) - instr('||'|| names, '||', 1, rn) ) name
from A,(select rownum rn from al connect by rownum < 10)
where instr('||'|| names, '||', 1, rn) > 0