2017-09-13 75 views
0

我有一個簡單的oracle數據庫和一個日誌文件。日誌文件中的每一行都是唯一的。有很多線路(~1百萬)。 我需要使用文件中的最後一行作爲插入語句的一部分。PL/SQL獲取文件中的最後一行,避免循環

獲取文件正常工作:

F1 := UTL_FILE.FOPEN('USER_DIR','log.txt','R'); 

把裏面的循環工作方式在文件中的每一行都是唯一的,所以我知道,如果我已經添加了行了或不:

loop 
BEGIN 
UTL_FILE.GET_LINE(F1,VX); 
-- do action 
EXCEPTION WHEN No_Data_Found THEN EXIT; END 
end loop; 

但是,這似乎可怕的效率低下,因爲我要閱讀文件中的每一行,即使我知道我只關心最後一行。這避免了環路,只是

出了點:

UTL_FILE.GET_LAST_LINE(F1,VX) 
-- do action 

將是巨大的。我確定有這樣的構造或東西,但我找不到它。如果這很重要的話,那就是Oracle11g。

回答

3

對此文章有幫助嗎?

UTL_FILE - Random Access of Files

的FGETATTR程序允許我們檢查文件是否存在,並 返回文件長度。然後,我們使用正常的GET_LINE 過程讀取第一行。爲了得到最後一行,我們需要使用FSEEK過程跳到文件末尾 並向後工作,直到我們點擊 行終止符。 GET_LINE過程不會返回行 終止符,因此我們通過檢查 空行的返回來檢測它的存在。然後我們可以顯示最後一行。

SET SERVEROUTPUT ON SIZE 1000000 
DECLARE 
    l_file   UTL_FILE.file_type; 
    l_location  VARCHAR2(100) := 'MY_DOCS'; 
    l_filename  VARCHAR2(100) := 'temp'; 
    l_exists  BOOLEAN; 
    l_file_length NUMBER; 
    l_blocksize NUMBER; 
    l_text   VARCHAR2(32767); 
BEGIN 
    UTL_FILE.fgetattr(l_location, l_filename, l_exists, l_file_length, l_blocksize); 

    IF l_exists THEN 
    -- Open file. 
    l_file := UTL_FILE.fopen(l_location, l_filename, 'r', 32767); 

    -- Read and output first line. 
    UTL_FILE.get_line(l_file, l_text, 32767); 
    DBMS_OUTPUT.put_line('First Line: |' || l_text || '|'); 
    UTL_FILE.FSEEK (l_file, l_file_length-1); 

    -- Step backwards through the file until we reach the start of the last line. 
    FOR i IN REVERSE 0 .. l_file_length-2 LOOP 
     UTL_FILE.FSEEK (l_file, NULL, -2); 
     UTL_FILE.get_line(l_file, l_text, 1); 
     EXIT WHEN l_text IS NULL; 
    END LOOP; 

    -- Read and output the last line. 
    UTL_FILE.get_line(l_file, l_text, 32767); 
    DBMS_OUTPUT.put_line('Last Line : |' || l_text || '|'); 

    -- Close the file. 
    UTL_FILE.fclose(l_file); 
    END IF; 
END; 
/
+0

不像我希望那麼簡單,但它確實有效。謝謝 – Scheme