【问题标题】:How to write to files using utl_file in oracle如何在 oracle 中使用 utl_file 写入文件
【发布时间】:2025-12-11 05:25:01
【问题描述】:

如何使用 put 函数。我的程序不是用 put 编译的。但 putline 工作正常。我想在同一行打印

【问题讨论】:

  • 当你说“不编译”的时候,想必有错误信息吧?让我们知道它说了什么会很方便。

标签: plsql


【解决方案1】:

这是一个使用 UTL_FILE.PUT 和 UTL_FILE.PUT_LINE 调用的代码示例:

declare 
  fHandle  UTL_FILE.FILE_TYPE;
begin
  fHandle := UTL_FILE.FOPEN('my_directory', 'test_file', 'w');

  UTL_FILE.PUT(fHandle, 'This is the first line');
  UTL_FILE.PUT(fHandle, 'This is the second line');
  UTL_FILE.PUT_LINE(fHandle, 'This is the third line');

  UTL_FILE.FCLOSE(fHandle);
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('Exception: SQLCODE=' || SQLCODE || '  SQLERRM=' || SQLERRM);
    RAISE;
end;

这个输出看起来像:

This is the first lineThis is the second lineThis is the third line

分享和享受。

【讨论】:

    【解决方案2】:

    这是一个使用 UTL_File.putline 的强大函数,其中包括必要的错误处理。它还处理页眉、页脚和其他一些例外情况。

    PROCEDURE usp_OUTPUT_ToFileAscii(p_Path IN VARCHAR2, p_FileName IN VARCHAR2, p_Input IN refCursor, p_Header in VARCHAR2, p_Footer IN VARCHAR2, p_WriteMode VARCHAR2) IS
    
                  vLine VARCHAR2(30000);
                  vFile UTL_FILE.file_type; 
                  vExists boolean;
                  vLength number;
                  vBlockSize number;
        BEGIN
    
            UTL_FILE.fgetattr(p_path, p_FileName, vExists, vLength, vBlockSize);
    
                     FETCH p_Input INTO vLine;
             IF p_input%ROWCOUNT > 0
             THEN
                IF vExists THEN
                   vFile := UTL_FILE.FOPEN_NCHAR(p_Path, p_FileName, p_WriteMode);
                ELSE
                   --even if the append flag is passed if the file doesn't exist open it with W.
                    vFile := UTL_FILE.FOPEN(p_Path, p_FileName, 'W');
                END IF;
                --GET HANDLE TO FILE
                IF p_Header IS NOT NULL THEN 
                  UTL_FILE.PUT_LINE(vFile, p_Header);
                END IF;
                UTL_FILE.PUT_LINE(vFile, vLine);
                DBMS_OUTPUT.PUT_LINE('Record count > 0');
    
                 --LOOP THROUGH CURSOR VAR
                 LOOP
                    FETCH p_Input INTO vLine;
    
                    EXIT WHEN p_Input%NOTFOUND;
    
                    UTL_FILE.PUT_LINE(vFile, vLine);
    
                 END LOOP;
    
    
                 IF p_Footer IS NOT NULL THEN 
                    UTL_FILE.PUT_LINE(vFile, p_Footer);
                 END IF;
    
                 CLOSE p_Input;
                 UTL_FILE.FCLOSE(vFile);
            ELSE
              DBMS_OUTPUT.PUT_LINE('Record count = 0');
    
            END IF; 
    
    
        EXCEPTION
           WHEN UTL_FILE.INVALID_PATH THEN 
               DBMS_OUTPUT.PUT_LINE ('invalid_path'); 
               DBMS_OUTPUT.PUT_LINE(SQLERRM);
               RAISE;
    
           WHEN UTL_FILE.INVALID_MODE THEN 
               DBMS_OUTPUT.PUT_LINE ('invalid_mode'); 
               DBMS_OUTPUT.PUT_LINE(SQLERRM);
               RAISE;
    
           WHEN UTL_FILE.INVALID_FILEHANDLE THEN 
               DBMS_OUTPUT.PUT_LINE ('invalid_filehandle'); 
               DBMS_OUTPUT.PUT_LINE(SQLERRM);
               RAISE;
    
           WHEN UTL_FILE.INVALID_OPERATION THEN 
               DBMS_OUTPUT.PUT_LINE ('invalid_operation'); 
               DBMS_OUTPUT.PUT_LINE(SQLERRM);
               RAISE;
    
           WHEN UTL_FILE.READ_ERROR THEN  
               DBMS_OUTPUT.PUT_LINE ('read_error');
               DBMS_OUTPUT.PUT_LINE(SQLERRM);
               RAISE;
    
           WHEN UTL_FILE.WRITE_ERROR THEN 
              DBMS_OUTPUT.PUT_LINE ('write_error'); 
              DBMS_OUTPUT.PUT_LINE(SQLERRM);
               RAISE;
    
           WHEN UTL_FILE.INTERNAL_ERROR THEN 
              DBMS_OUTPUT.PUT_LINE ('internal_error'); 
              DBMS_OUTPUT.PUT_LINE(SQLERRM);
              RAISE;            
           WHEN OTHERS THEN
              DBMS_OUTPUT.PUT_LINE ('other write error'); 
              DBMS_OUTPUT.PUT_LINE(SQLERRM);
              RAISE;
        END;
    

    【讨论】:

      【解决方案3】:

      您可以查看以下示例,了解如何在 PL/SQL 中使用 utl_file 进行记录/写入。

      DECLARE
      fhandle  utl_file.file_type;
      BEGIN
      fhandle := utl_file.fopen(
                         'UTL_DIR_*'-- File location
                       , 'Check_Logging.txt'    -- File name
                       , 'a'                    -- Open mode: a = append, w = write
                           );
      utl_file.put(fhandle, '*' );
      utl_file.fclose(fhandle);
      END;
      

      你可能面临的问题-


      无效的目录对象

       Then you can create your own directory object and use the below query.
      
       create or replace directory UTL_DIR_* as '/tmp/';
      

      【讨论】:

        【解决方案4】:
        CREATE OR REPLACE PROCEDURE SP_EXPORT_TO_CSV(P_OWNER       VARCHAR2,
                                                                    P_OBJECT_NAME VARCHAR2,
                                                                    P_FILE_NAME   VARCHAR2 --,
                                                                    --   P_DELIMITED CHAR
                                                                    ) AS
        
          -- declaration
          TYPE C_DATA_CURSOR IS REF CURSOR;
          C_DATA C_DATA_CURSOR;
        
          v_file        UTL_FILE.FILE_TYPE;
          V_COLUMNS     VARCHAR2(32767);
          X             VARCHAR2(32767);
          V_FILE_NAME   VARCHAR2(2000);
          V_OWNER       VARCHAR2(100);
          V_OBJECT_NAME VARCHAR2(1000);
          V_SQL         VARCHAR2(32767);
          V_DELIMITED   VARCHAR2(10);
        BEGIN
          -- set value
          V_FILE_NAME   := P_FILE_NAME;
          V_OBJECT_NAME := P_OBJECT_NAME;
          V_OWNER       := P_OWNER;
          --V_DELIMITED:=P_DELIMITED;
        
          SELECT REPLACE(LISTAGG(COLUMN_NAME, '|') WITHIN
                         GROUP(ORDER BY COLUMN_ID),
                         '|',
                         ' || ' || '''|''' || ' || ')
            INTO V_COLUMNS
            FROM ALL_TAB_COLUMNS W
           WHERE W.TABLE_NAME = V_OBJECT_NAME
             AND W.OWNER = V_OWNER
           ORDER BY COLUMN_ID;
        
          -- SET OUTPUT PARAMETER --'EXPORTED_TO_TEXT_LOCATION'
          v_file := UTL_FILE.FOPEN(location     => 'MYLOCATION',
                                   filename     => V_FILE_NAME,
                                   open_mode    => 'w',
                                   max_linesize => 32767);
          UTL_FILE.PUT_LINE(v_file, REPLACE(V_COLUMNS, ' || ''|'' || ', '|'));
          X := 'SELECT ' || V_COLUMNS || ' AS RECORD FROM ' || V_OWNER || '.' ||
               V_OBJECT_NAME;
        
          OPEN C_DATA FOR X;
          LOOP
            FETCH C_DATA
              INTO V_SQL;
            EXIT WHEN C_DATA%NOTFOUND;
            UTL_FILE.PUT_LINE(v_file, V_SQL);
          END LOOP;
          CLOSE C_DATA;
        
          UTL_FILE.FCLOSE(v_file);
        
         
        END;
        

        【讨论】: