了解Utl_file

时间:2013-08-07 15:55:12

标签: sql oracle directory procedure utl-file

所以我正在改变这个parse_file'c​​lean_files_up过程'的过程。我已经对变化进行了编码,但经过测试我意识到了 我实际上很难理解发生了什么。我从未使用解析文件或utl_file,所以我不完全 不安和这个概念。

总而言之,我们需要它从名为NEWFILE_DIRECTORY的目录中查找名为Files20130807.xxx的文件和当前的sysdate。 如果没有文件意味着找不到与当前sysdate匹配的文件,则需要运行位于其中的orignial文件 在另一个名为ORIGINALFILE_DIRECTORY的目录中,然后执行该过程的结尾。如果有一个匹配的文件 当前sysdate然后需要继续执行该过程。当它实际打开文件时,它将打开文件 匹配来自NEWFILE_DIRECTORY的当前sysdate然后将解析该文件,否则如果来自NEWFILE_DIRECTORY的当前文件 打开然后它将需要打开位于ORIGNIALFILE_DIRECTORY中的原始文件,然后将解析该文件。

PROCEDURE clean_files_up IS
v_fileName VARCHAR2(20) := Files || to_char(sysdate, 'YYYYMMDD') || '.xxx';
v_inFile  utl_file.file_type;
v_outFile  utl_file.file_type;
v_line      VARCHAR2(2000);
v_newLine  VARCHAR2(2000);
v_count     NUMBER := 1; 

BEGIN

--No Files found for current date 
  IF (substr(v_fileName, 6, 8)) <> to_char(sysdate, 'YYYYMMDD') THEN
   v_inFile := utl_file.fopen('ORIGINALFILE_DIRECTORY', 'OriginalFile.xxx', 'r');  

   RETURN;  --go to end of procedure
  END IF;

   v_inFile := utl_file.fopen ('NEWFILE_DIRECTORY', 'v_fileName', 'r');   
    IF utl_file.is_open(v_inFile) THEN
      v_outFile := utl_file.fopen('ORIGINALFILE_DIRECTORY',                      
                               'OriginalFile.xxx',
                               'W');

 LOOP
    BEGIN
      utl_file.get_line(v_inFile, v_line);
      IF v_line IS NULL THEN
        EXIT;
      END IF;
      IF v_count > 1 THEN
        get_new_csv_line(v_line, v_newLine);
        utl_file.put_line(v_outFile, v_newLine);
        utl_file.fflush(v_outFile);
      END IF;
      v_count := v_count + 1;
    EXCEPTION
      WHEN no_data_found THEN
      EXIT; 
    END;
  END LOOP;
  utl_file.fclose(v_outFile);
END IF;

 EXCEPTION
  WHEN OTHERS THEN
     Condition;

END clean_files_up;

问题:

  1. 所以我需要在一些文件路径/ xxx / xxx / xxx中创建一个名为NEWFILE_DIRECTORY的新目录,其中包含文件列表 喜欢 ;文件20130804.xxx,Files20130805.xxx,Files20130806.xxx,Files20130807位于其中。我不知道 在这个过程里面我将创建新目录,或者即使我可以在过程
  2. 中创建它

    以“/ xxx / xxx / xxx”

    创建或替换DIRECTORY newfile_directory

    2 ..我需要读取这些文件以确保它与sysdate匹配,否则它需要运行原始文件和 然后到程序结束。这部分是在BEGIN之后的IF声明。我只是对它如何知道而感到困惑 查看NEWFILE_DIRECTORY以查找匹配的文件名Files20130807.xxx以查看它是否匹配。

    3 ..这是#2的一个类似问题,但是如何(在第一个结束IF之后;)它知道NEWFILE_DIRECOTRY的文件路径在哪里 和ORIGINALFILE_DIRECTORY的位置没有给出或定义路径?

    4 ..最后,当测试代码时,我注意到它在读取v_inFile后:= utl_file.fopen('NEWFILE_DIRECTORY','v_fileName','r'); (在第一个结束IF之后;)它继续到异常而不继续通过if和循环。

    我真的很感激有人可以回答这些问题至少有助于理解正在发生的事情。也 如果我需要澄清和问题(1-4)我可以做到这一点。

2 个答案:

答案 0 :(得分:1)

您的问题的答案:

1)以下代码从Oracle内部定义的目录创建链接(可以通过从DBA_DIRECTORIES中选择数据来查看它们)到文件系统目录。

CREATE OR REPLACE DIRECTORY NEWFILE_DIRECTORY AS '/xxx/xxx/xxx'

如果路径&#39; / xxx / xxx / xxx&#39;已经存在于文件系统中,那么这将是正确的方式。

2)如果我理解正确,那么你必须检查NEWFILE_DIRECTORY中存在的文件是否包含当前日期的名称。可以使用以下功能完成:

FUNCTION check_if_file_exists
  (p_file_name IN VARCHAR2
  ,p_file_dir IN VARCHAR2)
RETURN BOOLEAN
IS
  v_file  utl_file.file_type;
BEGIN
  v_file := utl_file.fopen(p_file_dir, p_file_name, 'R');

  IF utl_file.is_open(v_file) THEN
    RETURN TRUE;
  ELSE
    RETURN FALSE;
  END IF;
EXCEPTION
  WHEN UTL_FILE.invalid_path THEN
    RETURN FALSE;
  WHEN utl_file.invalid_operation THEN
    RETURN FALSE;
END check_if_file_exists;

你的第一个将是:

IF check_if_file_exists(v_fileName, 'NEWFILE_DIRECTORY') THEN

3)您可以通过&#34; CREATE OR REPLACE DIRECTORY&#34;创建数据库目录(DB的映射以查找文件系统路径)。 (见#1)

4)您将参数作为字符串值传递&#39; v_fileName&#39;不是变量v_fileName。正确的代码是:

v_inFile := utl_file.fopen ('NEWFILE_DIRECTORY', v_fileName, 'r');   

答案 1 :(得分:0)

Janis Baiza感谢您的回答,它真正帮助我理解了发生了什么。

我实际上发现这将检查该文件是否存在于当前目录中,如果确实存在则输出它存在,如果不存在则输出它不存在并运行原始文件然后返回到程序结束。

utl_file.fgetattr ('NEWFILE_DIRECTORY', v_fileName, v_check_fileEX, v_fLength, v_Bsize );
IF v_check_fileEX THEN
dbms_output.put_line('file exists');
END IF;
IF NOT v_check_fileEX THEN
dbms_output.put_line('file does not exist');

v_inFile := utl_file.fopen('ORIGINALFILE_DIRECTORY', 'OriginalFile.xxx', 'r');

 RETURN; 
END IF;