如何编写可重复使用的函数以从查询中返回CSV输出?

时间:2012-10-15 05:55:30

标签: oracle csv plsql code-reuse

在我的应用程序的许多地方,我需要将数据显示为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:

我发现了收集功能:

选择收集(employee_name)
来自员工

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

2 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:1)

老问题并且已经正确回答我知道,但由于这是Google搜索“oracle cursor to csv”的热门话题之一,我刚刚写了一些内容来做这件事,我想我会发布一个新答案。

从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用于跟踪其相应内部值的无意义生成数字。)

由于引用游标已经打开并解析,因此您跳过这些步骤并调用

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并处理结果即可。我把它放在一个流水线表函数中,它接受一个引用游标参数,所以你得到这样的东西:

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