【问题标题】:How can I write a re-usable function to return CSV output from a query?如何编写可重用函数以从查询中返回 CSV 输出?
【发布时间】:2012-10-15 05:55:29
【问题描述】:

在我的应用程序的许多地方,我需要将数据显示为 CSV。

为此,我通常会遍历光标并构建 CSV。

for j in c_get_mydata loop
    v_CSV := v_CSV || ', ' || j.column_value;
end loop;

如何编写一个可以接受查询并返回 CSV 字符串的可重用函数?您是否建议将其作为一个单独的函数,还是像上面那样处理每个查询更好?如果您建议将其作为一个单独的函数,您是否建议该函数将查询字符串或结果光标作为输入?

编辑:

澄清:我想将单列数据显示为一行,用逗号分隔。

例如:Tom, Dick, Harry, Sally

我不希望在多行上显示多列数据:

Tom, 18, London
Dick, 22, New York
Harry, 16, San Fransisco
Sally, 18, Paris

编辑 2:

我发现了收集功能:

选择收集(员工姓名)
来自员工

这会返回一个数据集,但如何将其转换为字符串?

【问题讨论】:

标签: oracle csv plsql code-reuse


【解决方案1】:

最简单的选择通常是使用DBMS_SQL 包。 Tom Kyte 的dump_csv procedure 就是一个很好的例子。当然,您可能希望将结果写入 CLOB,而不是使用 utl_file 将其写入文件,但这是一个相对容易的调整。

【讨论】:

    【解决方案2】:

    我知道旧问题并且已经正确回答,但由于这是“oracle cursor to csv”的热门 Google 热门歌曲之一,而且我刚刚写了一些东西来做到这一点,所以我想我会发布一个新答案。

    从 Oracle 11.2 开始,DBMS_SQL 可以处理普通的引用游标,而不是像 Tom Kyte 的 2000 解决方案中的字符串。您使用

    将其摄取到 DBMS_SQL
    l_cursor_id := dbms_sql.to_cursor_number(your_refcursor);
    

    (然后l_cursor_id 将包含一个无意义的生成数字,DBMS_SQL 使用它来跟踪其相应的内部值。)

    由于 ref 游标已经打开并解析,您可以跳过这些步骤并调用

    dbms_sql.describe_columns(l_cursor_id, l_col_count, l_cursor_columns);
    

    其中l_cursor_columns(DBMS_SQL 为您填充的 ​​OUT 参数)是 dbms_sql.desc_tab,它是一个列定义数组,其中填充了查询中每一列的条目并包含列名、数据类型等,以及l_col_count 有点多余地包含与l_cursor_columns.count 相同的值。然后,您需要遍历这个调用 dbms_sql.define_column 的数组,以告诉 DBMS_SQL 使用它刚刚告诉您的数据类型来处理每一个,这是一个相当冗长的步骤,我永远看不到重点。 (它确实允许您将所有 '%CHAR%' 类型视为 varchar2 等,所以我想它允许一些灵活性。)

    那么只需在循环中调用dbms_sql.fetch_rows 并处理结果即可。我把它放在一个接受 ref 游标参数的流水线表函数中,所以你会得到这样的结果:

    select column_value
    from   table(csv.report(cursor(
               select * from dept  -- << Use any query here
           )));
    
    COLUMN_VALUE
    ----------------------------------------------
    10,ACCOUNTING,NEW YORK
    20,RESEARCH,DALLAS
    30,SALES,CHICAGO
    40,OPERATIONS,BOSTON
    
    4 rows selected.
    

    完整的文章和代码在这里: www.williamrobertson.net/documents/refcursor-to-csv.shtml

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-29
    • 2022-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多