2013-08-21 46 views
2

這可能是一個愚蠢的想法。我正在嘗試編寫一個SQL * Plus .sql腳本,我可以從Windows批處理文件調用該批處理文件,該文件本身使用dbms_output.put_line生成一個新的.sql腳本。這是我到目前爲止有我的劇本:「PL/SQL過程已成功完成」使用dbms_output構建SQL腳本的Oracle SQL腳本

set echo off; 
set serverout on; 

conn [email protected]; 

spool E:\new_script.sql 

DECLARE 

    CURSOR c_groups IS 
    SELECT * FROM table; 

    s varchar2(4000); 

BEGIN 

    dbms_output.put_line('BEGIN'); 

    FOR x IN c_groups LOOP 
    s := 'INSERT INTO TABLE blah VALUES ('''||x.name||''','||x.id||');'; 
    END LOOP; 

    dbms_output.put_line(s); 

    dbms_output.put_line('COMMIT;'); 

    dbms_output.put_line('END;'); 
    dbms_output.put_line('/'); 

END; 
/

spool off; 
exit; 

然而,當我這樣做,我的new_script.sql只是說:任何想法如何使dbms_out.put_line實際顯示他們的消息?

而我實際上並沒有這樣做來建立插入語句 - 這些只是一個簡單的例子,顯示了我想要做的事情的要點。

回答

1

SPOOL將結果發送到文件;但它不能確保結果被打印。要啓用打印到標準輸出;使用SERVEROUTPUT命令。

set serveroutput on 

這通常是一個很糟糕的事情的方式;我承認你說這不是你實際做的,但是SQL是一種基於集合的語言。如果可能的話,做大量的事情。

4
  1. 您必須首先連接,然後使用SET命令。所以,你的三個命令應該是

    順序如下:

    conn [email protected]; 
    set echo off; 
    set serverout on; 
    

    否則,serveroutput參數將被設置爲默認

    值,這是OFF和之所以dbms_output.put_line()

    沒有按預期工作。

  2. 您應該FOR循環內執行dbms_output.put_line(s)

    FOR x IN c_groups LOOP 
        s := 'INSERT INTO TABLE blah VALUES ('''||x.name||''','||x.id||');'; 
        dbms_output.put_line(s); 
    END LOOP; 
    

    而且它是多餘的,以閥芯BEGIN .. END塊。 DML語句

    (一束在這種情況下INSERT INTO語句)由分號結束將是

    沒有被包括在所述塊BEGIN END執行就好了。

  3. 當您運行使用*.bat文件腳本,這將可能是有用的使用

    以下命令:

    set feedback off; -- To not spool messages like 
            -- PL/SQL procedure successfully completed 
    
    set termout off; -- to suppress the output from a command line. 
    
  4. 你的方法也許可以歸結爲一個簡單的SELECT聲明:

    conn [email protected]; 
    
    set echo off; 
    set serverout on; 
    set feedback off; 
    set termout off; 
    set heading off; 
    
    spool E:\new_script.sql 
    
    SELECT 'INSERT INTO TABLE blah VALUES ('''||name||'''','||to_char(id)||');' 
    FROM table; 
    
    spool off; 
    
    exit; 
    
+0

+1但是添加'BEGIN'和'END''可能是一個非常好的主意。在緩慢的網絡上,處理一個PL/SQL塊將比處理許多SQL語句快得多。儘管如果PL/SQL塊是巨大的,那麼這種方法會產生'DIANA'錯誤。 –

+0

1)我不認爲你在SET之前或之後CONN是否重要。我的SET ECHO ON在兩個地方工作。 2)在現實生活中,dbms_output調用位於循環內部;那是一個抄寫錯誤。此外,我的循環內部涉及設置變量的函數調用,所以這就是爲什麼我在那裏有BEGIN和END的原因。 3)這些將是有益的,謝謝。 4)這回到#2,因爲我正在循環內進行更多的處理。 我大概可以在沒有匿名BEGIN..END塊的情況下完成包裝整個事情。儘管我最終使用了UTL_FILE,但是感謝您閱讀它。 – Tom

+0

@Tom它對'serveroutput'參數很重要。 'echo'參數無關緊要。 –