我正在处理pl sql存储过程。 我需要的是做一个选择,使用游标,并为每个记录使用值构建一个字符串。 最后我需要把它写入一个文件。 我尝试使用dbms_output.put_line(“toto”),但缓冲区大小很小,因为我有大约1400万行。 我从unix ksh调用我的过程。 我在想使用“spool on”(在ksh端)来转储我的过程结果,但我不知道如何去做(如果可能的话)Oracle PL/SQL:将查询结果转储到文件中
任何人都有任何想法?
我正在处理pl sql存储过程。 我需要的是做一个选择,使用游标,并为每个记录使用值构建一个字符串。 最后我需要把它写入一个文件。 我尝试使用dbms_output.put_line(“toto”),但缓冲区大小很小,因为我有大约1400万行。 我从unix ksh调用我的过程。 我在想使用“spool on”(在ksh端)来转储我的过程结果,但我不知道如何去做(如果可能的话)Oracle PL/SQL:将查询结果转储到文件中
任何人都有任何想法?
除非真的有必要,否则我不会使用程序。
如果调用使用SQL 加上剧本,只是把下面的内容test.sql
(在SET
s是SQLPlus FAQ去除噪声):
SET ECHO OFF
SET NEWPAGE 0
SET SPACE 0
SET PAGESIZE 0
SET FEEDBACK OFF
SET HEADING OFF
SET TRIMSPOOL ON
SET TAB OFF
Select owner || ';' || object_name
From all_objects;
QUIT
和输出重定向到文件(test.txt
):
sqlplus user/[email protected]ce @ test.sql > test.txt
如果你真的需要做的东西在PL/SQL,考虑把该进的功能和Ca LL它每个记录:
Create Or Replace Function calculate_my_row(in_some_data In Varchar2)
Return Varchar2
As
Begin
Return in_some_data || 'something-complicated';
End calculate_my_row;
电话:
Select owner || ';' || calculate_my_row(object_name)
From all_objects;
业绩可能遭受负面,但它应该工作。请确保,尽管如此,您尝试使用纯粹的SQL
无法完成。
阅读您的评论我觉得解析函数Lag
是你所需要的。
这个例子追加*
的情况下val
值发生了变化:
With x As (
Select 1 id, 'A' val FROM dual
Union Select 2 id, 'A' val FROM dual
Union Select 3 id, 'B' val FROM dual
Union Select 4 id, 'B' val FROM dual
)
--# End of test-data
Select
id,
val,
Case When (val <> prev_val Or prev_val Is Null) Then '*' End As changed
From (
Select id, val, Lag(val) Over (Order By id) As prev_val
From x
)
Order By id
返回
ID V C
---------- - -
1 A *
2 A
3 B *
4 B
这也不起作用,因为问题是我需要为每一行做一些东西,所以我做了一个游标,并在里面为每一行做我的东西。 – 2010-03-31 08:18:39
请看我更新的答案。你在尝试什么,不能在纯SQL中完成? – 2010-03-31 08:31:58
不坏这个解决办法,但... :) 我在每一行做的treatement是: 如果字段的前值是不同的,目前的价值,我会串连东西,别的什么也不做。 因此,使用它的游标工作,但我不能/我不知道如何转储结果。 – 2010-03-31 08:42:37
utl_file是你的朋友 http://www.adp-gmbh.ch/ora/plsql/utl_file.html 但是写入数据到服务器上的文件系统,所以你可能需要你的DBA的帮助。
我看到了utl_file,但我无法使用它,因为我没有权限。 – 2010-03-31 08:09:06
如果输出的每一行都是表格中一行操作的结果,那么存储函数与Peter Lang的答案一起可以完成您所需的操作。
create function create_string(p_foobar foobar%rowtype) return varchar2 as
begin
do_some_stuff(p_foobar);
return p_foobar.foo || ';' ||p_foobar.bar;
end;
/
如果它要复杂得多,也许你可以使用一个流水线表函数
create type varchar_array
as table of varchar2(2000)
/
create function output_pipelined return varchar_array PIPELINED as
v_line varchar2(2000);
begin
for r_foobar in (select * from foobar)
loop
v_line := create_string(r_foobar);
pipe row(v_line);
end loop;
return;
end;
/
select * from TABLE(output_pipelined);
我在尝试这个解决方案,但是由于我有大量的数据,我可以使用它吗? v_line将有更多的2000个字符?它仍然有效吗?或者在v_line中只是一行的信息? – 2010-03-31 09:24:38
v_line是一行的信息。 – 2010-03-31 10:48:56
太好了。有用。非常感谢。 – 2010-03-31 11:51:30
出于好奇,你试试我的解决方案? – 2010-03-31 12:30:35
我已经回答了。我无法承受更多的一次查询。您的解决方案(分析函数)需要查询被执行多个。另一种解决方案不起作用,因为我需要从前面的迭代中获得一个字段的值。 – 2010-03-31 15:40:08
为什么您需要使用分析函数多次执行查询?你读过我的最后一条评论吗? – 2010-03-31 15:53:06