oracle如何将csv转成表格

Posted

技术标签:

【中文标题】oracle如何将csv转成表格【英文标题】:how to convert csv to table in oracle 【发布时间】:2011-03-09 17:33:19 【问题描述】:

如何制作一个在传入 csv 值时以表格格式返回结果的包。

select * from table(schema.mypackage.myfunction('one, two, three'))

应该返回

one
two
three

我尝试了 ask tom 的一些东西,但这只适用于 sql 类型。

我正在使用 oracle 11g。有内置的吗?

【问题讨论】:

【参考方案1】:

以下作品 调用它作为 select * from table(splitter('a,b,c,d'))

create or replace function splitter(p_str in varchar2) return  sys.odcivarchar2list
is
v_tab sys.odcivarchar2list:=new sys.odcivarchar2list();
begin
with cte as (select level  ind from dual
connect by 
level <=regexp_count(p_str,',') +1
)
select regexp_substr(p_str,'[^,]+',1,ind)
bulk collect into v_tab
from cte;
return v_tab;
end;
/

【讨论】:

regexp_substr函数参数'[^,]+'允许空字段,如'123,456,,999'【参考方案2】:

唉,在 11g 中,我们仍然必须使用 SQL 类型手动处理我们自己的 PL/SQL 标记器。在 11gR2 中,Oracle 给了我们一个聚合函数来将结果连接成一个 CSV 字符串,所以也许在 12i 中它们会提供反向功能。

如果您不想特别创建 SQL 类型,可以使用内置的 SYS.DBMS_DEBUG_VC2COLL,如下所示:

create or replace function string_tokenizer
    (p_string in varchar2
        , p_separator in varchar2 := ',')
    return sys.dbms_debug_vc2coll
is
    return_value SYS.DBMS_DEBUG_VC2COLL;
    pattern varchar2(250);
begin

    pattern := '[^('''||p_separator||''')]+' ;

    select trim(regexp_substr (p_string, pattern, 1, level)) token
    bulk collect into return_value
    from dual
    where regexp_substr (p_string, pattern, 1, level) is not null
    connect by regexp_instr (p_string, pattern, 1, level) > 0;

    return return_value;

end string_tokenizer;
/

它在行动:

SQL> select * from table (string_tokenizer('one, two, three'))
  2  /

COLUMN_VALUE
----------------------------------------------------------------
one
two
three

SQL>

致谢:此代码是some code I found on Tanel Poder's blog 的变体。

【讨论】:

【参考方案3】:

这是另一种完全在 sql 中使用正则表达式匹配器的解决方案。

SELECT regexp_substr('one,two,three','[^,]+', 1, level) abc
FROM dual 
CONNECT BY regexp_substr('one,two,three', '[^,]+', 1, level) IS NOT NULL

【讨论】:

【参考方案4】:

为获得最佳性能,最好避免在拆分器函数中使用分层 (CONNECT BY) 查询。

以下拆分器功能在应用于更大的数据量时会表现得更好

CREATE OR REPLACE FUNCTION row2col(p_clob_text IN VARCHAR2) 
   RETURN sys.dbms_debug_vc2coll PIPELINED 
IS
     next_new_line_indx PLS_INTEGER;
     remaining_text VARCHAR2(20000);
     next_piece_for_piping VARCHAR2(20000);
  BEGIN

    remaining_text := p_clob_text;
    LOOP
       next_new_line_indx := instr(remaining_text, ','); 
       next_piece_for_piping :=
          CASE
             WHEN next_new_line_indx <> 0 THEN
                TRIM(SUBSTR(remaining_text, 1, next_new_line_indx-1))
             ELSE
                TRIM(SUBSTR(remaining_text, 1))
          END;

       remaining_text := SUBSTR(remaining_text, next_new_line_indx+1 );
       PIPE ROW(next_piece_for_piping);
       EXIT WHEN next_new_line_indx = 0 OR remaining_text IS NULL;
    END LOOP;
    RETURN;
  END row2col;
/

可以在下面观察到这种性能差异(我使用了本讨论前面给出的函数拆分器)。

SQL> SET TIMING ON
SQL>
SQL> WITH SRC AS (
  2  SELECT rownum||',a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z'||rownum txt
  3  FROM DUAL
  4  CONNECT BY LEVEL <=10000
  5  )
  6  SELECT  NULL
  7  FROM SRC, TABLE(SYSTEM.row2col(txt)) t
  8  HAVING MAX(t.column_value) > 'zzz'
  9  ;

no rows selected

Elapsed: 00:00:00.93
SQL>
SQL> WITH SRC AS (
  2  SELECT rownum||',a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z'||rownum txt
  3  FROM DUAL
  4  CONNECT BY LEVEL <=10000
  5  )
  6  SELECT  NULL
  7  FROM SRC, TABLE(splitter(txt)) t
  8  HAVING MAX(t.column_value) > 'zzz'
  9  ;

no rows selected

Elapsed: 00:00:14.90
SQL>
SQL> SET TIMING OFF
SQL>

【讨论】:

【参考方案5】:

我没有安装 11g 来玩,但是有一个 PIVOT 和 UNPIVOT 操作用于将列转换为行/将行转换为列,这可能是一个很好的起点。

http://www.oracle.com/technology/pub/articles/oracle-database-11g-top-features/11g-pivot.html

(实际上做了一些进一步的调查,这看起来不适合这种情况 - 它适用于实际的行/列,但不适用于列中的数据集)。

还有 DBMS_UTILITY.comma_to_table 和 table_to_comma 用于将 CSV 列表转换为 pl/sql 表。有一些限制(处理换行等),但可能是一个很好的起点。

我倾向于使用 TYPE 方法,使用一个简单的函数来执行 comma_to_table,然后为 comma_to_table 结果中的每个条目进行 PIPE ROW(不幸的是,DBMS_UTILITY.comma_to_table 是一个过程,因此无法从 SQL 调用)。

【讨论】:

以上是关于oracle如何将csv转成表格的主要内容,如果未能解决你的问题,请参考以下文章

如何将csv文件转换成excel

csv如何转化为excel

csv文件转换成excel的方法

如何将csv文件转换成excel文件呢?

java怎么将xlsx转换成csv格式

如何将excel表格转成在线文档