我正在處理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