Oracle - 如何在select语句中解析巨大的clob列

时间:2017-05-15 09:52:00

标签: .net oracle

我有一张包含巨大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

我怎样才能实现这个目标?

2 个答案:

答案 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>