我有一张包含巨大clob列的表。
此列中有坐标,可以有300.000个数量的坐标,用逗号分隔,如29.0000, 40.0000 | 29.0001, 40.0000 | 29.0002, 40.0000
我需要查看特定行的选择输出,例如
1 | 29.0000, 40.0000
2 | 29.0001 , 40.0000
3 | 29.0002 , 40.0000
我怎样才能实现这个目标?
答案 0 :(得分:0)
您可以创建用户定义的函数来生成用户定义的坐标集合:
Oracle安装程序:
CREATE TYPE coordinate_type IS OBJECT(
x NUMBER,
y NUMBER
);
/
CREATE TYPE coordinate_table IS TABLE OF coordinate_type;
/
CREATE FUNCTION splitCoordinateList(
i_string CLOB,
i_delimiter VARCHAR2 := '|',
i_separator VARCHAR2 := ','
) RETURN coordinate_table DETERMINISTIC PIPELINED
AS
p_start PLS_INTEGER := 1;
p_end PLS_INTEGER;
p_sep PLS_INTEGER;
c_del_len CONSTANT PLS_INTEGER := LENGTH( i_delimiter );
c_sep_len CONSTANT PLS_INTEGER := LENGTH( i_separator );
BEGIN
IF i_delimiter IS NULL OR c_del_len = 0 THEN
RETURN;
END IF;
IF i_separator IS NULL OR c_sep_len = 0 THEN
RETURN;
END IF;
LOOP
p_end := INSTR( i_string, i_delimiter, p_start );
EXIT WHEN p_end = 0;
p_sep := INSTR( i_string, i_separator, p_start );
IF p_sep = 0 OR p_sep >= p_end THEN
RAISE_APPLICATION_ERROR( -20001, 'Co-ordinate separator not found' );
END IF;
PIPE ROW(
coordinate_type(
TO_NUMBER( SUBSTR( i_string, p_start, p_sep - p_start ) ),
TO_NUMBER( SUBSTR( i_string, p_sep + c_sep_len, p_end - p_sep - c_sep_len ) )
)
);
p_start := p_end + c_del_len;
END LOOP;
p_end := LENGTH( i_string );
IF p_start < p_end THEN
p_sep := INSTR( i_string, i_separator, p_start );
IF p_sep = 0 THEN
RETURN;
END IF;
PIPE ROW(
coordinate_type(
TO_NUMBER( SUBSTR( i_string, p_start, p_sep - p_start ) ),
TO_NUMBER( SUBSTR( i_string, p_sep + c_sep_len, p_end + 1 - p_sep - c_sep_len ) )
)
);
END IF;
END splitCoordinateList;
/
<强>查询强>:
SELECT ROWNUM, t.*
FROM TABLE( splitCoordinateList(
'29.0000, 40.0000 | 29.0001, 40.0000 | 29.0002, 40.0000'
) ) t;
<强>输出强>:
ROWNUM X Y
------ ------- -------
1 29 40
2 29.0001 40
3 29.0002 40
答案 1 :(得分:0)
您可以使用这个简单的SQL
来获得上述结果:
SELECT to_char( LEVEL
|| '|'
|| TRIM (
REGEXP_SUBSTR (
col,
'[^|]+',
1,
LEVEL)))
Col
FROM clob_tbl
CONNECT BY LEVEL <=
REGEXP_COUNT (
col,
',') ;
演示:
SQL> create table clob_tbl(col clob);
SQL> select * from clob_tbl;
COL
--------------------------------------------------------------------------------
29.0000, 40.0000 | 29.0001, 40.0000 | 29.0002, 40.0000
SQL> SELECT to_char( LEVEL
|| '|'
|| TRIM (
REGEXP_SUBSTR (
col,
'[^|]+',
1,
LEVEL)))
Col
FROM clob_tbl
CONNECT BY LEVEL <=
REGEXP_COUNT (
col,
',') ;
COL
--------------------------------------------------------------------------------
1|29.0000, 40.0000
2|29.0001, 40.0000
3|29.0002, 40.0000
SQL>