【问题标题】:Delimited Blob data in oracleoracle中的分隔Blob数据
【发布时间】:2017-05-31 20:03:58
【问题描述】:

我在 oracle 表中有+ 分隔的 BLOB 数据。

数据:

2342-34-34+83898oov+4ncjj+jdjjd11kj+20-12-2017

我想提取这些数据并将其存储在一个数组中

预期输出:

 Array[1]   Array[2]    Array[3]
2342-34-34  83898oov    4ncjj

我们有什么方法可以在 oracle 中实现这一点,而无需在 DB 之外提取数据?

注意:分隔符文本的数量因记录而异。

【问题讨论】:

  • 您的意思是 BLOB 即二进制编码还是实际上是 CLOB 即 ascii 字符?如果是 BLOB,使用什么机制来生成它?
  • 它由基于 Web 的银行应用程序生成
  • 可以使用正则表达式编写流水线函数

标签: oracle blob


【解决方案1】:

Oracle 设置

CREATE OR REPLACE TYPE stringlist IS TABLE OF VARCHAR2(4000);
/
CREATE OR REPLACE TYPE cloblist IS TABLE OF CLOB;
/

CREATE OR REPLACE FUNCTION blob_to_clob (blob_in IN BLOB)
  RETURN CLOB
AS
     c_buffer  CONSTANT PLS_INTEGER := 32767;
     v_clob    CLOB;
     v_varchar VARCHAR2(32767);
     v_start   PLS_INTEGER := 1;
BEGIN
  DBMS_LOB.CREATETEMPORARY(v_clob, TRUE);

  FOR i IN 1 .. CEIL( DBMS_LOB.GETLENGTH(blob_in) / c_buffer ) LOOP
    v_varchar := UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(blob_in, c_buffer, v_start));
    DBMS_LOB.WRITEAPPEND(v_clob, LENGTH(v_varchar), v_varchar);
    v_start := v_start + c_buffer;
  END LOOP;

  RETURN v_clob;
END blob_to_clob;
/
SHOW ERRORS;

CREATE OR REPLACE FUNCTION split_clob(
  i_str    IN  CLOB,
  i_delim  IN  VARCHAR2 DEFAULT ','
) RETURN stringlist /* or cloblist */ DETERMINISTIC PIPELINED
AS
  p_start        PLS_INTEGER := 1;
  p_end          PLS_INTEGER;
  c_len CONSTANT PLS_INTEGER := DBMS_LOB.GETLENGTH( i_str );
  c_ld  CONSTANT PLS_INTEGER := LENGTH( i_delim );
BEGIN
  IF c_len > 0 THEN
    p_end := DBMS_LOB.INSTR( i_str, i_delim, p_start );
    WHILE p_end > 0 LOOP
      PIPE ROW ( DBMS_LOB.SUBSTR( i_str, p_end - p_start, p_start ) );
      p_start := p_end + c_ld;
      p_end := DBMS_LOB.INSTR( i_str, i_delim, p_start );
    END LOOP;
    IF p_start <= c_len + 1 THEN
      PIPE ROW ( DBMS_LOB.SUBSTR( i_str, c_len - p_start + 1, p_start ) );
    END IF;
  END IF;
END;
/

示例数据

CREATE TABLE test ( data BLOB );

INSERT INTO test VALUES ( UTL_RAW.CAST_TO_RAW( '2342-34-34+83898oov+4ncjj+jdjjd11kj+20-12-2017' ) );

查询 1 - 作为行

SELECT x.COLUMN_VALUE AS value
FROM   test t,
       TABLE( split_clob( blob_to_clob( data ), '+' ) ) x;

输出

VALUE    
----------
2342-34-34
83898oov  
4ncjj     
jdjjd11kj 
20-12-2017

查询 2 - 作为列

SELECT DBMS_LOB.SUBSTR( str, delimiter1 - 1, 1 ) AS A1,
       DBMS_LOB.SUBSTR( str, delimiter2 - delimiter1 - 1, delimiter1 + 1 ) AS A2,
       DBMS_LOB.SUBSTR( str, delimiter3 - delimiter2 - 1, delimiter2 + 1 ) AS A3
FROM   (
  SELECT str,
         DBMS_LOB.INSTR( str, '+', 1, 1 ) AS delimiter1,
         DBMS_LOB.INSTR( str, '+', 1, 2 ) AS delimiter2,
         DBMS_LOB.INSTR( str, '+', 1, 3 ) AS delimiter3
  FROM   (
    SELECT BLOB_TO_CLOB( data ) AS str
    FROM   test
  )
);

输出

A1         A2         A3       
---------- ---------- ----------
2342-34-34 83898oov   4ncjj     

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-24
    • 2016-12-08
    • 2014-10-11
    • 1970-01-01
    • 2016-02-07
    • 2018-05-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多